2022-12-09 09:41:17 +00:00
|
|
|
import {
|
|
|
|
MatrixAuth, MatrixClient, SimpleFsStorageProvider, AutojoinRoomsMixin,
|
|
|
|
LogService, LogLevel,
|
|
|
|
RichConsoleLogger,
|
2022-12-29 02:38:29 +00:00
|
|
|
ICryptoStorageProvider,
|
|
|
|
RustSdkCryptoStorageProvider,
|
2022-12-09 09:41:17 +00:00
|
|
|
} from "matrix-bot-sdk";
|
2022-12-29 02:48:50 +00:00
|
|
|
|
2022-12-29 02:38:29 +00:00
|
|
|
import * as path from "path";
|
2023-02-03 10:35:49 +00:00
|
|
|
import { DATA_PATH, OPENAI_API_KEY, OPENAI_PRO, MATRIX_HOMESERVER_URL, MATRIX_ACCESS_TOKEN, MATRIX_AUTOJOIN, MATRIX_BOT_PASSWORD, MATRIX_BOT_USERNAME, MATRIX_ENCRYPTION, MATRIX_THREADS, CHATGPT_CONTEXT, CHATGPT_MODEL } from './env.js'
|
2022-12-09 09:41:17 +00:00
|
|
|
import { parseMatrixUsernamePretty } from './utils.js';
|
2023-01-06 23:59:52 +00:00
|
|
|
import CommandHandler from "./handlers.js"
|
2023-02-02 12:44:14 +00:00
|
|
|
import { ChatGPTAPI } from 'chatgpt'
|
2022-12-09 09:41:17 +00:00
|
|
|
|
|
|
|
LogService.setLogger(new RichConsoleLogger());
|
|
|
|
|
|
|
|
// Shows the Matrix sync loop details - not needed most of the time
|
|
|
|
// LogService.setLevel(LogLevel.DEBUG);
|
|
|
|
|
|
|
|
LogService.setLevel(LogLevel.INFO);
|
|
|
|
|
|
|
|
// LogService.muteModule("Metrics");
|
|
|
|
LogService.trace = LogService.debug;
|
|
|
|
|
2022-12-29 11:11:52 +00:00
|
|
|
const storage = new SimpleFsStorageProvider(path.join(DATA_PATH, "bot.json")); // /storage/bot.json
|
2022-12-09 09:41:17 +00:00
|
|
|
|
2022-12-29 02:38:29 +00:00
|
|
|
// Prepare a crypto store if we need that
|
|
|
|
let cryptoStore: ICryptoStorageProvider;
|
2022-12-29 11:11:52 +00:00
|
|
|
if (MATRIX_ENCRYPTION) {
|
|
|
|
cryptoStore = new RustSdkCryptoStorageProvider(path.join(DATA_PATH, "encrypted")); // /storage/encrypted
|
2022-12-29 02:38:29 +00:00
|
|
|
}
|
2022-12-09 09:41:17 +00:00
|
|
|
|
|
|
|
async function main() {
|
2022-12-29 11:11:52 +00:00
|
|
|
if (!MATRIX_ACCESS_TOKEN){
|
2023-01-07 00:30:09 +00:00
|
|
|
const botUsernameWithoutDomain = parseMatrixUsernamePretty(MATRIX_BOT_USERNAME);
|
2022-12-29 11:11:52 +00:00
|
|
|
const authedClient = await (new MatrixAuth(MATRIX_HOMESERVER_URL)).passwordLogin(botUsernameWithoutDomain, MATRIX_BOT_PASSWORD);
|
2022-12-29 01:14:31 +00:00
|
|
|
console.log(authedClient.homeserverUrl + " token: \n" + authedClient.accessToken)
|
2022-12-29 11:11:52 +00:00
|
|
|
console.log("Set MATRIX_ACCESS_TOKEN to above token, MATRIX_BOT_PASSWORD can now be blank")
|
2022-12-29 01:14:31 +00:00
|
|
|
return;
|
|
|
|
}
|
2023-01-27 18:01:52 +00:00
|
|
|
if (!MATRIX_THREADS && CHATGPT_CONTEXT !== "room") throw Error("You must set CHATGPT_CONTEXT to 'room' if you set MATRIX_THREADS to false")
|
2023-01-07 18:17:13 +00:00
|
|
|
const client: MatrixClient = new MatrixClient(MATRIX_HOMESERVER_URL, MATRIX_ACCESS_TOKEN, storage, cryptoStore);
|
2022-12-09 09:41:17 +00:00
|
|
|
|
2022-12-22 14:57:34 +00:00
|
|
|
// use puppeteer to bypass cloudflare (headful because of captchas)
|
2023-02-02 12:44:14 +00:00
|
|
|
const chatGPT: ChatGPTAPI = new ChatGPTAPI({
|
2023-02-03 10:35:49 +00:00
|
|
|
apiKey: OPENAI_API_KEY,
|
|
|
|
completionParams: {
|
|
|
|
model: CHATGPT_MODEL
|
|
|
|
}
|
2022-12-09 09:41:17 +00:00
|
|
|
})
|
2023-01-27 18:30:14 +00:00
|
|
|
|
2023-01-28 13:04:56 +00:00
|
|
|
// // call `api.refreshSession()` every hour to refresh the session
|
|
|
|
// setInterval(() => {
|
|
|
|
// chatGPT.refreshSession().then(() => {
|
|
|
|
// LogService.info('ChatGPT session reset');
|
|
|
|
// });
|
|
|
|
// }, 60 * 60 * 1000);
|
2023-01-27 18:30:14 +00:00
|
|
|
|
2023-01-28 13:04:56 +00:00
|
|
|
// // call `api.resetSession()` every 24 hours to reset the session
|
|
|
|
// setInterval(() => {
|
|
|
|
// chatGPT.resetSession().then(() => {
|
|
|
|
// LogService.info('ChatGPT session reset');
|
|
|
|
// });
|
|
|
|
// }, 24 * 60 * 60 * 1000);
|
2022-12-09 09:41:17 +00:00
|
|
|
|
|
|
|
// Automatically join rooms the bot is invited to
|
2022-12-29 11:11:52 +00:00
|
|
|
if (MATRIX_AUTOJOIN) {
|
2022-12-29 02:38:29 +00:00
|
|
|
AutojoinRoomsMixin.setupOnClient(client);
|
|
|
|
}
|
2022-12-09 09:41:17 +00:00
|
|
|
|
|
|
|
client.on("room.failed_decryption", async (roomId, event, error) => {
|
|
|
|
// handle `m.room.encrypted` event that could not be decrypted
|
|
|
|
LogService.error("index", `Failed decryption event!\n${{ roomId, event, error }}`);
|
|
|
|
await client.sendText(roomId, `I couldn't decrypt the message :( Please add me to an unencrypted room.`);
|
|
|
|
});
|
|
|
|
|
|
|
|
client.on("room.join", async (roomId: string, _event: any) => {
|
|
|
|
LogService.info("index", `Bot joined room ${roomId}`);
|
|
|
|
await client.sendMessage(roomId, {
|
|
|
|
"msgtype": "m.notice",
|
2023-01-12 18:03:23 +00:00
|
|
|
"body": `👋 Hello, I'm the ChatGPT bot! Encrypted message support: ${MATRIX_ENCRYPTION}`,
|
2022-12-09 09:41:17 +00:00
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2023-01-06 23:59:52 +00:00
|
|
|
// Prepare the command handler
|
|
|
|
const commands = new CommandHandler(client, chatGPT);
|
|
|
|
await commands.start();
|
2022-12-09 09:41:17 +00:00
|
|
|
|
2023-02-03 10:35:49 +00:00
|
|
|
LogService.info("index", `Starting bot using ChatGPT model ${CHATGPT_MODEL}`);
|
2022-12-09 09:41:17 +00:00
|
|
|
await client.start()
|
|
|
|
LogService.info("index", "Bot started!");
|
|
|
|
}
|
|
|
|
|
|
|
|
main();
|