From 98137cc4fd3ec0cc3232ee93759510ccd16619da Mon Sep 17 00:00:00 2001 From: Atridad Lahiji <88056492+atridadl@users.noreply.github.com> Date: Thu, 15 Jun 2023 17:20:00 -0600 Subject: [PATCH] added ask --- package.json | 3 +- pnpm-lock.yaml | 69 ++++++++++++++++++++++++++++++++++++++++++++- src/commands/ask.ts | 59 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 129 insertions(+), 2 deletions(-) create mode 100644 src/commands/ask.ts diff --git a/package.json b/package.json index 1a33897..f276c56 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,8 @@ "@sapphire/utilities": "^3.11.1", "@skyra/env-utilities": "^1.2.0", "colorette": "^2.0.20", - "discord.js": "^14.10.2" + "discord.js": "^14.10.2", + "openai": "^3.3.0" }, "devDependencies": { "@sapphire/cli": "^1.6.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5f03e56..144399d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,4 +1,4 @@ -lockfileVersion: '6.1' +lockfileVersion: '6.0' settings: autoInstallPeers: false @@ -29,6 +29,9 @@ dependencies: discord.js: specifier: ^14.10.2 version: 14.10.2 + openai: + specifier: ^3.3.0 + version: 3.3.0 devDependencies: '@sapphire/cli': @@ -300,6 +303,18 @@ packages: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} dev: true + /asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + dev: false + + /axios@0.26.1: + resolution: {integrity: sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==} + dependencies: + follow-redirects: 1.15.2 + transitivePeerDependencies: + - debug + dev: false + /busboy@1.6.0: resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} engines: {node: '>=10.16.0'} @@ -310,6 +325,13 @@ packages: /colorette@2.0.20: resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} + /combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + dependencies: + delayed-stream: 1.0.0 + dev: false + /commander@10.0.1: resolution: {integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==} engines: {node: '>=14'} @@ -324,6 +346,11 @@ packages: which: 2.0.2 dev: true + /delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + dev: false + /discord-api-types@0.37.43: resolution: {integrity: sha512-bBhDWU3TF9KADxR/mHp1K4Bvu/LRtFQdGyBjADu4e66F3ZnD4kp12W/SJCttIaCcMXzPV3sfty6eDGRNRph51Q==} dev: false @@ -413,6 +440,25 @@ packages: path-exists: 4.0.0 dev: true + /follow-redirects@1.15.2: + resolution: {integrity: sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + dev: false + + /form-data@4.0.0: + resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} + engines: {node: '>= 6'} + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + dev: false + /from@0.1.7: resolution: {integrity: sha512-twe20eF1OxVxp/ML/kq2p1uc6KvFK/+vs8WjEbeKmV2He22MKm7YF2ANIt+EOqhJ5L3K/SuuPhk0hWQDjOM23g==} dev: true @@ -479,6 +525,18 @@ packages: resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} dev: true + /mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + dev: false + + /mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + dependencies: + mime-db: 1.52.0 + dev: false + /mimic-fn@4.0.0: resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} engines: {node: '>=12'} @@ -502,6 +560,15 @@ packages: mimic-fn: 4.0.0 dev: true + /openai@3.3.0: + resolution: {integrity: sha512-uqxI/Au+aPRnsaQRe8CojU0eCR7I0mBiKjD3sNMzY6DaC1ZVrc85u98mtJW6voDug8fgGN+DIZmTDxTthxb7dQ==} + dependencies: + axios: 0.26.1 + form-data: 4.0.0 + transitivePeerDependencies: + - debug + dev: false + /p-limit@3.1.0: resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} engines: {node: '>=10'} diff --git a/src/commands/ask.ts b/src/commands/ask.ts new file mode 100644 index 0000000..acf5074 --- /dev/null +++ b/src/commands/ask.ts @@ -0,0 +1,59 @@ +import { ApplyOptions } from '@sapphire/decorators'; +import { Args, Command } from '@sapphire/framework'; +import { Message } from 'discord.js'; +import { Configuration, OpenAIApi } from 'openai'; + +const configuration = new Configuration({ + apiKey: process.env.OPENAI_API_KEY +}); +const openai = new OpenAIApi(configuration); + +@ApplyOptions({ + description: 'You can ACTUALLY ask Himbot something! So cool!', + options: ['prompt'] +}) +export class UserCommand extends Command { + // Register Chat Input and Context Menu command + public override registerApplicationCommands(registry: Command.Registry) { + registry.registerChatInputCommand((builder) => + builder // + .setName(this.name) + .setDescription(this.description) + .addStringOption((option) => + option.setName('prompt').setDescription('You can ACTUALLY ask Himbot something! So cool!').setRequired(true) + ) + ); + } + + // Message command + public async messageRun(message: Message, args: Args) { + return this.ask(message, args.getOption('prompt') || message.content.split('!wryna ')[1]); + } + + // Chat Input (slash) command + public async chatInputRun(interaction: Command.ChatInputCommandInteraction) { + return this.ask(interaction, interaction.options.getString('prompt') || 'NOTHING'); + } + + private async ask(interactionOrMessage: Message | Command.ChatInputCommandInteraction | Command.ContextMenuCommandInteraction, prompt: string) { + const askMessage = + interactionOrMessage instanceof Message + ? await interactionOrMessage.channel.send({ content: '🤔 Thinking... 🤔' }) + : await interactionOrMessage.reply({ content: '🤔 Thinking... 🤔', fetchReply: true }); + + const chatCompletion = await openai.createChatCompletion({ + model: 'gpt-3.5-turbo', + messages: [{ role: 'user', content: prompt }] + }); + + const content = chatCompletion.data.choices[0].message?.content || 'ERROR!'; + + if (interactionOrMessage instanceof Message) { + return askMessage.edit({ content }); + } + + return interactionOrMessage.editReply({ + content: content + }); + } +}