From f40ccb198f4d1474335c5b2fff4794bffbe470c5 Mon Sep 17 00:00:00 2001 From: ChrisChrome Date: Wed, 8 Mar 2023 17:36:35 -0700 Subject: [PATCH] Doin my thang --- commands.json | 7 +++ config.json.default | 9 ++++ gpt-test.js | 50 ++++++++++++++++++++ index.js | 113 ++++++++++++++++++++++++++++++++++++++++++++ lang.json | 4 ++ package-lock.json | 27 ++++++++++- package.json | 4 +- 7 files changed, 212 insertions(+), 2 deletions(-) create mode 100644 commands.json create mode 100644 gpt-test.js create mode 100644 lang.json diff --git a/commands.json b/commands.json new file mode 100644 index 0000000..acb79e6 --- /dev/null +++ b/commands.json @@ -0,0 +1,7 @@ +[ + { + "name": "reset", + "description": "Reset the GPT-3 chat", + "type": 1 + } +] \ No newline at end of file diff --git a/config.json.default b/config.json.default index e69de29..898dd78 100644 --- a/config.json.default +++ b/config.json.default @@ -0,0 +1,9 @@ +{ + "discord": { + "token": "", + "channel": "" + }, + "openai": { + "key": "" + } +} \ No newline at end of file diff --git a/gpt-test.js b/gpt-test.js new file mode 100644 index 0000000..0355310 --- /dev/null +++ b/gpt-test.js @@ -0,0 +1,50 @@ +const config = require("./config.json"); +const { + Configuration, + OpenAIApi +} = require("openai"); +const openai = new OpenAIApi(new Configuration({ + apiKey: config.openai.key +})); + +// Take user input via command line +const readline = require("readline").createInterface({ + input: process.stdin, + output: process.stdout +}); + +sessions = {}; + +// Command line is session 0 +sessions[0] = { + messages: [] +}; + +// The ask() function but as a promise +const askPromise = (prompt, session) => { + return new Promise((resolve, reject) => { + // If the session doesn't exist, create it + if (!sessions[session]) { + sessions[session] = { + messages: [] + + +// Ask the user for a prompt +const ask = () => { + readline.question("What would you like to ask the bot? ", async (prompt) => { + // Create a new session + sessions[0].messages.push({ + role: "user", + content: prompt + }); + await openai.createChatCompletion({ + model: "gpt-3.5-turbo", + messages: sessions[0].messages + }).then((data) => { + sessions[0].messages.push(data.data.choices[0].message); + console.log(`${data.data.choices[0].message.role}: ${data.data.choices[0].message.content}`); + ask(); + }); + }); +}; +ask(); \ No newline at end of file diff --git a/index.js b/index.js index e69de29..d70eea6 100644 --- a/index.js +++ b/index.js @@ -0,0 +1,113 @@ +const config = require("./config.json"); +const lang = require("./lang.json"); +const { + Configuration, + OpenAIApi +} = require("openai"); +const openai = new OpenAIApi(new Configuration({ + apiKey: config.openai.key +})); +const Discord = require("discord.js"); +const { + REST, + Routes +} = require('discord.js'); +const rest = new REST({ + version: '10' +}).setToken(config.discord.token); +const fs = require("fs"); +const path = require("path"); +const colors = require("colors"); + +// Create a new Discord client +const client = new Discord.Client({ + intents: ["MessageContent", "GuildMessages", "Guilds"] +}); +var sessions = {}; // Keep track of sessions, not really used right now, but if I wanted to allow multiple sessions, I could +client.on("ready", () => { + console.log(`${colors.cyan("[INFO]")} Logged in as ${colors.green(client.user.tag)}`) + // Log startup time in seconds + console.log(`${colors.cyan("[INFO]")} Startup took ${colors.green((Date.now() - initTime) / 1000)} seconds.`) + // Load Commands + console.log(`${colors.cyan("[INFO]")} Loading Commands...`) + const commands = require('./commands.json'); + (async () => { + try { + console.log(`${colors.cyan("[INFO]")} Registering Commands...`) + let start = Date.now() + // For every guild + for (const guild of client.guilds.cache.values()) { + // Register commands + await rest.put( + Routes.applicationGuildCommands(client.user.id, guild.id), { + body: commands + }, + ); + } + console.log(`${colors.cyan("[INFO]")} Successfully registered commands. Took ${colors.green((Date.now() - start) / 1000)} seconds.`); + } catch (error) { + console.error(error); + } + })(); +}); + +client.on('interactionCreate', async (interaction) => { + if (!interaction.isCommand()) return; + switch(interaction.commandName) { + case "reset": + // Reset the session + sessions[interaction.channelId] = {messages: []}; + interaction.reply(lang.reset); + break; + } +}); + +client.on('messageCreate', async (message) => { + if(!message.channelId == config.discord.channel) return; + if(message.author.bot) return; + if(message.content.startsWith("!!")) return; // So you can chat without the bot replying + // If the session doesn't exist, create it + if (!sessions[message.channelId]) { + sessions[message.channelId] = { + messages: [], + // 10 minute auto reset + autoReset: setTimeout(() => { + sessions[message.channelId] = {messages: []}; + message.channel.send(lang.timeout) + }, config.openai.resetTime) + }; + } else { + // Reset the auto reset timer + clearTimeout(sessions[message.channelId].autoReset); + sessions[message.channelId].autoReset = setTimeout(() => { + sessions[message.channelId] = {messages: []}; + message.channel.send(lang.timeout) + }, config.openai.resetTime); + } + message.channel.sendTyping(); + // Add the message to the session + sessions[message.channelId].messages.push({ + "name": "User", + "content": message.content, + "role": "user" + }); + // Send the message to OpenAI + await openai.createChatCompletion({ + model: "gpt-3.5-turbo", + messages: sessions[message.channelId].messages + }).then((data) => { + output = data.data.choices[0].message; + output.name = "Bot"; + // Add the bot's response to the session + sessions[message.channelId].messages.push(output); + // Send the bot's response + message.channel.send(output.content); + }); +}); + +// Init +console.log(`${colors.cyan("[INFO]")} Starting...`) +// Start timer to see how long startup takes +const initTime = Date.now() +// Login to Discord +client.login(config.discord.token); \ No newline at end of file diff --git a/lang.json b/lang.json new file mode 100644 index 0000000..8144f74 --- /dev/null +++ b/lang.json @@ -0,0 +1,4 @@ +{ + "reset": "Session reset.", + "timeout": "Session timed out. Type anything to start a new session." +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 351129c..5838524 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,8 +9,10 @@ "version": "1.0.0", "license": "GPL-3.0-or-later", "dependencies": { + "colors": "^1.4.0", "discord.js": "^14.7.1", - "openai": "^3.2.1" + "openai": "^3.2.1", + "readline": "^1.3.0" } }, "node_modules/@discordjs/builders": { @@ -136,6 +138,14 @@ "node": ">=10.16.0" } }, + "node_modules/colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", + "engines": { + "node": ">=0.1.90" + } + }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -337,6 +347,11 @@ "url": "https://github.com/sponsors/Borewit" } }, + "node_modules/readline": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/readline/-/readline-1.3.0.tgz", + "integrity": "sha512-k2d6ACCkiNYz222Fs/iNze30rRJ1iIicW7JuX/7/cozvih6YCkFZH+J6mAFDVgv0dRBaAyr4jDqC95R2y4IADg==" + }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -548,6 +563,11 @@ "streamsearch": "^1.1.0" } }, + "colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==" + }, "combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -680,6 +700,11 @@ "readable-stream": "^3.6.0" } }, + "readline": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/readline/-/readline-1.3.0.tgz", + "integrity": "sha512-k2d6ACCkiNYz222Fs/iNze30rRJ1iIicW7JuX/7/cozvih6YCkFZH+J6mAFDVgv0dRBaAyr4jDqC95R2y4IADg==" + }, "safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", diff --git a/package.json b/package.json index b5581f7..c6d10b5 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,9 @@ "author": "", "license": "GPL-3.0-or-later", "dependencies": { + "colors": "^1.4.0", "discord.js": "^14.7.1", - "openai": "^3.2.1" + "openai": "^3.2.1", + "readline": "^1.3.0" } }