From 9a4bed608a731611cd0efc030cc063d44e5f74ce Mon Sep 17 00:00:00 2001 From: bertybuttface <110790513+bertybuttface@users.noreply.github.com> Date: Sat, 24 Dec 2022 15:13:56 +0000 Subject: [PATCH 1/6] Fix `isGoogleLogin` ignoring setting and defaulting to true --- src/config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/config.ts b/src/config.ts index 57a1796..9445530 100644 --- a/src/config.ts +++ b/src/config.ts @@ -16,7 +16,7 @@ export const matrixBotPassword = process.env.MATRIX_BOT_PASSWORD as string; /** ChatGPT specific stuff */ export const openAiEmail = process.env.OPENAI_EMAIL as string; export const openAiPassword = process.env.OPENAI_PASSWORD as string; -export const isGoogleLogin = Boolean(process.env.IS_GOOGLE_LOGIN) as boolean; +export const isGoogleLogin = (process.env.IS_GOOGLE_LOGIN.toLowerCase() === "true") as boolean; if(accessToken === undefined) { console.error("MATRIX_ACCESS_TOKEN env variable is undefined"); From 0b55624710090220cb1e19cf6fcb13f64e3ce0e8 Mon Sep 17 00:00:00 2001 From: bertybuttface <110790513+bertybuttface@users.noreply.github.com> Date: Mon, 26 Dec 2022 00:40:56 +0000 Subject: [PATCH 2/6] Fix for when isGoogleLogin undefined --- src/config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/config.ts b/src/config.ts index 9445530..9f7a4c5 100644 --- a/src/config.ts +++ b/src/config.ts @@ -16,7 +16,7 @@ export const matrixBotPassword = process.env.MATRIX_BOT_PASSWORD as string; /** ChatGPT specific stuff */ export const openAiEmail = process.env.OPENAI_EMAIL as string; export const openAiPassword = process.env.OPENAI_PASSWORD as string; -export const isGoogleLogin = (process.env.IS_GOOGLE_LOGIN.toLowerCase() === "true") as boolean; +export const isGoogleLogin = process.env.IS_GOOGLE_LOGIN && process.env.IS_GOOGLE_LOGIN.toLowerCase() === "true"; if(accessToken === undefined) { console.error("MATRIX_ACCESS_TOKEN env variable is undefined"); From 1a80e1daf91c899482dadf467b279586f6b678b3 Mon Sep 17 00:00:00 2001 From: bertybuttface <110790513+bertybuttface@users.noreply.github.com> Date: Wed, 28 Dec 2022 02:57:45 +0000 Subject: [PATCH 3/6] Bump chatgpt dependency to 3.3.5 (latest) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2216b1a..f98a29b 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ "typecheck": "npx tsc" }, "dependencies": { - "chatgpt": "^3.3.1", + "chatgpt": "^3.3.5", "dotenv": "^14.2.0", "matrix-bot-sdk": "^0.6.2", "puppeteer": "^19.4.1", From 5fba831d9453120798285eb2659a26bbaa9c82e9 Mon Sep 17 00:00:00 2001 From: bertybuttface <110790513+bertybuttface@users.noreply.github.com> Date: Wed, 28 Dec 2022 22:48:35 +0000 Subject: [PATCH 4/6] Bump chatgpt to 3.3.6 (latest) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f98a29b..4669e63 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ "typecheck": "npx tsc" }, "dependencies": { - "chatgpt": "^3.3.5", + "chatgpt": "^3.3.6", "dotenv": "^14.2.0", "matrix-bot-sdk": "^0.6.2", "puppeteer": "^19.4.1", From c5793ec12b555bf8b6cb65742299265309e9908a Mon Sep 17 00:00:00 2001 From: bertybuttface <110790513+bertybuttface@users.noreply.github.com> Date: Thu, 29 Dec 2022 01:14:31 +0000 Subject: [PATCH 5/6] Use matrix access token if we have it, print one if we don't. --- src/config.ts | 20 ++++++++++---------- src/index.ts | 11 ++++++++--- 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/src/config.ts b/src/config.ts index 57a1796..d047ab6 100644 --- a/src/config.ts +++ b/src/config.ts @@ -18,21 +18,21 @@ export const openAiEmail = process.env.OPENAI_EMAIL as string; export const openAiPassword = process.env.OPENAI_PASSWORD as string; export const isGoogleLogin = Boolean(process.env.IS_GOOGLE_LOGIN) as boolean; -if(accessToken === undefined) { - console.error("MATRIX_ACCESS_TOKEN env variable is undefined"); - process.exit(1); -} if(homeserverUrl === undefined) { console.error("MATRIX_HOMESERVER_URL env variable is undefined"); process.exit(1); } -if(matrixBotUsername === undefined) { - console.error("MATRIX_BOT_USERNAME env variable is undefined"); - process.exit(1); -} -if(matrixBotPassword === undefined) { - console.error("MATRIX_BOT_PASSWORD env variable is undefined"); +if(accessToken === undefined) { + console.error("MATRIX_ACCESS_TOKEN env variable is undefined, set it to empty string to use username and password"); process.exit(1); + if(matrixBotUsername === undefined) { + console.error("MATRIX_BOT_USERNAME env variable is undefined, set it to empty string to use access token"); + process.exit(1); + } + if(matrixBotPassword === undefined) { + console.error("MATRIX_BOT_PASSWORD env variable is undefined, set it to empty string to use access token"); + process.exit(1); + } } if(openAiEmail === undefined) { console.error("OPENAI_EMAIL env variable is undefined"); diff --git a/src/index.ts b/src/index.ts index 386df51..4398a96 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,7 +4,7 @@ import { RichConsoleLogger, // RustSdkCryptoStorageProvider, } from "matrix-bot-sdk"; -import { openAiEmail, openAiPassword, isGoogleLogin, homeserverUrl, matrixBotPassword, matrixBotUsername } from './config.js' +import { openAiEmail, openAiPassword, isGoogleLogin, homeserverUrl, accessToken, matrixBotPassword, matrixBotUsername } from './config.js' import { parseMatrixUsernamePretty } from './utils.js'; import { handleRoomEvent } from './handlers.js'; import { ChatGPTAPIBrowser } from 'chatgpt' @@ -26,8 +26,13 @@ const storage = new SimpleFsStorageProvider("./storage/bot.json"); async function main() { const botUsernameWithoutDomain = parseMatrixUsernamePretty(matrixBotUsername); - const authedClient = await (new MatrixAuth(homeserverUrl)).passwordLogin(botUsernameWithoutDomain, matrixBotPassword); - const client = new MatrixClient(authedClient.homeserverUrl, authedClient.accessToken, storage); + if (!accessToken){ + const authedClient = await (new MatrixAuth(homeserverUrl)).passwordLogin(botUsernameWithoutDomain, matrixBotPassword); + console.log(authedClient.homeserverUrl + " token: \n" + authedClient.accessToken) + console.log("Set MATRIX_ACCESS_TOKEN to above token, MATRIX_ACCESS_USERNAME and MATRIX_ACCESS_PASSWORD can now be blank") + return; + } + const client = new MatrixClient(homeserverUrl, accessToken, storage); // use puppeteer to bypass cloudflare (headful because of captchas) const chatGPT = new ChatGPTAPIBrowser({ From f33d01e5317af0d67bb3374785ce1825bc96c8eb Mon Sep 17 00:00:00 2001 From: bertybuttface <110790513+bertybuttface@users.noreply.github.com> Date: Thu, 29 Dec 2022 02:38:29 +0000 Subject: [PATCH 6/6] Fix storage, e2e and add feature flags --- Dockerfile | 2 ++ README.md | 9 +++++++-- src/config.ts | 16 ++++++++++++++++ src/index.ts | 21 ++++++++++++++------- 4 files changed, 39 insertions(+), 9 deletions(-) diff --git a/Dockerfile b/Dockerfile index 85c3816..8c0b40c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -66,6 +66,8 @@ RUN npm install puppeteer@19.4.1 \ && chown -R pptruser:pptruser /home/pptruser USER pptruser +VOLUME /storage + # We run a fake display and run our script. # Start script on Xvfb CMD xvfb-run --server-args="-screen 0 1024x768x24" yarn start \ No newline at end of file diff --git a/README.md b/README.md index 813d8c7..80f3c0e 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ You should not be using this ChatGPT account while the bot is using it, because If your OpenAI account uses Google Auth, you shouldn't encounter any of the more complicated Recaptchas — and can avoid using paid third-party CAPTCHA solving providers. To use Google auth, make sure your OpenAI account is using Google and then set IS_GOOGLE_LOGIN to true. # Usage -- Create an unencrypted room +- Create an (encrypted if enabled) room - Add the bot - Start chatting away! @@ -44,6 +44,11 @@ IS_GOOGLE_LOGIN=true # With the @ and :DOMAIN, ie @SOMETHING:DOMAIN MATRIX_BOT_USERNAME= MATRIX_BOT_PASSWORD= +MATRIX_AUTO_JOIN=true +MATRIX_ENCRYPTION=true + +# needs to be ./storage/ if you aren't using Docker or /storage/ if you are. +DATA_PATH=/storage/ ``` # Discussion @@ -65,7 +70,7 @@ recomend following the prompts at https://element.io/get-started to download and ``` docker build . -t matrix-chatgpt-bot -docker run --cap-add=SYS_ADMIN -it matrix-chatgpt-bot +docker run --cap-add=SYS_ADMIN -it -v ./storage:/storage matrix-chatgpt-bot ``` Note: Without -it flags in the command above you won't be able to stop the container using Ctrl-C diff --git a/src/config.ts b/src/config.ts index 57a1796..43c1b7a 100644 --- a/src/config.ts +++ b/src/config.ts @@ -12,6 +12,10 @@ export const homeserverUrl = process.env.MATRIX_HOMESERVER_URL as string; /** The full username: eg @bot:server.com */ export const matrixBotUsername = process.env.MATRIX_BOT_USERNAME as string; export const matrixBotPassword = process.env.MATRIX_BOT_PASSWORD as string; +export const matrixAutojoin = process.env.MATRIX_AUTO_JOIN && process.env.MATRIX_AUTO_JOIN.toLowerCase() === "true" as string; +export const matrixEncryption = process.env.MATRIX_ENCRYPTION && process.env.MATRIX_ENCRYPTION.toLowerCase() === "true" as string; + +export const dataPath = process.env.DATA_PATH as string; /** ChatGPT specific stuff */ export const openAiEmail = process.env.OPENAI_EMAIL as string; @@ -22,6 +26,10 @@ if(accessToken === undefined) { console.error("MATRIX_ACCESS_TOKEN env variable is undefined"); process.exit(1); } +if(dataPath === undefined) { + console.error("DATA_PATH env variable is undefined"); + process.exit(1); +} if(homeserverUrl === undefined) { console.error("MATRIX_HOMESERVER_URL env variable is undefined"); process.exit(1); @@ -34,6 +42,14 @@ if(matrixBotPassword === undefined) { console.error("MATRIX_BOT_PASSWORD env variable is undefined"); process.exit(1); } +if(matrixAutojoin === undefined) { + console.error("MATRIX_AUTO_JOIN env variable is undefined"); + process.exit(1); +} +if(matrixEncryption === undefined) { + console.error("MATRIX_ENCRYPTION env variable is undefined"); + process.exit(1); +} if(openAiEmail === undefined) { console.error("OPENAI_EMAIL env variable is undefined"); process.exit(1); diff --git a/src/index.ts b/src/index.ts index 386df51..3802964 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,9 +2,11 @@ import { MatrixAuth, MatrixClient, SimpleFsStorageProvider, AutojoinRoomsMixin, LogService, LogLevel, RichConsoleLogger, - // RustSdkCryptoStorageProvider, + ICryptoStorageProvider, + RustSdkCryptoStorageProvider, } from "matrix-bot-sdk"; -import { openAiEmail, openAiPassword, isGoogleLogin, homeserverUrl, matrixBotPassword, matrixBotUsername } from './config.js' +import * as path from "path"; +import { dataPath, openAiEmail, openAiPassword, isGoogleLogin, homeserverUrl, accessToken, matrixAutojoin, matrixBotPassword, matrixBotUsername, matrixEncryption } from './config.js' import { parseMatrixUsernamePretty } from './utils.js'; import { handleRoomEvent } from './handlers.js'; import { ChatGPTAPIBrowser } from 'chatgpt' @@ -19,10 +21,13 @@ LogService.setLevel(LogLevel.INFO); // LogService.muteModule("Metrics"); LogService.trace = LogService.debug; -const storage = new SimpleFsStorageProvider("./storage/bot.json"); +const storage = new SimpleFsStorageProvider(path.join(dataPath, "bot.json")); // /storage/bot.json -// Still fails to decrypt sometimes -// const cryptoProvider = new RustSdkCryptoStorageProvider("./crypto/"); +// Prepare a crypto store if we need that +let cryptoStore: ICryptoStorageProvider; +if (matrixEncryption) { + cryptoStore = new RustSdkCryptoStorageProvider(path.join(dataPath, "encrypted")); // /storage/encrypted +} async function main() { const botUsernameWithoutDomain = parseMatrixUsernamePretty(matrixBotUsername); @@ -38,7 +43,9 @@ async function main() { await chatGPT.initSession() // Automatically join rooms the bot is invited to - AutojoinRoomsMixin.setupOnClient(client); + if (matrixAutojoin) { + AutojoinRoomsMixin.setupOnClient(client); + } client.on("room.failed_decryption", async (roomId, event, error) => { // handle `m.room.encrypted` event that could not be decrypted @@ -51,7 +58,7 @@ async function main() { await client.sendMessage(roomId, { "msgtype": "m.notice", - "body": `👋 Hello, I'm the ChatGPT bot! I only work in unencrypted rooms at the moment.`, + "body": `👋 Hello, I'm the ChatGPT bot! Encrypted message support: ${ matrixEncryption }`, }); });