From e9d9b202b05677ce208610e54da89b3fe1602e85 Mon Sep 17 00:00:00 2001 From: atridadl Date: Fri, 10 Nov 2023 18:47:06 -0700 Subject: [PATCH] Cleanup! --- src/commands/credits.ts | 51 ------------------- src/commands/disclosure.ts | 35 ------------- src/commands/fancypic.ts | 5 +- src/commands/meow.ts | 41 --------------- src/commands/pic.ts | 100 +++++++++++-------------------------- 5 files changed, 33 insertions(+), 199 deletions(-) delete mode 100644 src/commands/credits.ts delete mode 100644 src/commands/disclosure.ts delete mode 100644 src/commands/meow.ts diff --git a/src/commands/credits.ts b/src/commands/credits.ts deleted file mode 100644 index 208cf42..0000000 --- a/src/commands/credits.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { ApplyOptions } from '@sapphire/decorators'; -import { Command } from '@sapphire/framework'; -import { Message } from 'discord.js'; - -// @ts-ignore -@ApplyOptions({ - description: 'Check how many credits I have left!' -}) -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)); - } - - // Message command - public async messageRun(message: Message) { - return this.credits(message); - } - - // Chat Input (slash) command - public async chatInputRun(interaction: Command.ChatInputCommandInteraction) { - return this.credits(interaction); - } - - private async credits(interactionOrMessage: Message | Command.ChatInputCommandInteraction | Command.ContextMenuCommandInteraction) { - const askMessage = - interactionOrMessage instanceof Message - ? await interactionOrMessage.channel.send({ content: '🤔 Thinking... 🤔' }) - : await interactionOrMessage.reply({ content: '🤔 Thinking... 🤔', fetchReply: true }); - - const creditCountResponse = await fetch(`https://api.stability.ai/v1/user/balance`, { - method: 'GET', - headers: { - 'Content-Type': 'application/json', - Authorization: `Bearer ${process.env.STABILITY_API_KEY}` - } - }); - - const balance = (await creditCountResponse.json()).credits || 0; - - const content = `I have ${balance} credits remaining for image generation!`; - - if (interactionOrMessage instanceof Message) { - return askMessage.edit({ content }); - } - - return interactionOrMessage.editReply({ - content: content - }); - } -} diff --git a/src/commands/disclosure.ts b/src/commands/disclosure.ts deleted file mode 100644 index a52a78a..0000000 --- a/src/commands/disclosure.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { ApplyOptions } from '@sapphire/decorators'; -import { Command } from '@sapphire/framework'; -import { Message } from 'discord.js'; - -// @ts-ignore -@ApplyOptions({ - description: 'Disclosures for privacy.' -}) -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)); - } - - // Message command - public async messageRun(message: Message) { - return this.sendDisclosure(message); - } - - // Chat Input (slash) command - public async chatInputRun(interaction: Command.ChatInputCommandInteraction) { - return this.sendDisclosure(interaction); - } - - private async sendDisclosure(interactionOrMessage: Message | Command.ChatInputCommandInteraction | Command.ContextMenuCommandInteraction) { - interactionOrMessage instanceof Message - ? await interactionOrMessage.channel.send({ - content: `Commands such as /ask and /pic do not send your discord data to the AI providers. They will, however, send anything you include in the prompts. /ask uses OpenAI's gpt3.5 model and /pic uses Stable Diffusion. All other commands and the data associated stays with HimBot's server and Discord's Servers.` - }) - : await interactionOrMessage.reply({ - content: `Commands such as /ask and /pic do not send your discord data to the AI providers. They will, however, send anything you include in the prompts. /ask uses OpenAI's gpt3.5 model and /pic uses Stable Diffusion. All other commands and the data associated stays with HimBot's server and Discord's Servers.`, - fetchReply: true - }); - } -} diff --git a/src/commands/fancypic.ts b/src/commands/fancypic.ts index e478a9e..a85f2cb 100644 --- a/src/commands/fancypic.ts +++ b/src/commands/fancypic.ts @@ -12,7 +12,7 @@ const openai = new OpenAI({ description: 'Pic... but better!', options: ['prompt'], // 10mins - cooldownDelay: 400_000, + cooldownDelay: 500_000, cooldownLimit: 1, // Yes... I did hardcode myself. cooldownFilteredUsers: ['83679718401904640'], @@ -52,7 +52,8 @@ export class UserCommand extends Command { model: 'dall-e-3', prompt, n: 1, - size: '1024x1024' + size: '1024x1024', + quality: 'hd' }); const imageUrl = response.data[0].url || ''; diff --git a/src/commands/meow.ts b/src/commands/meow.ts deleted file mode 100644 index a9d3667..0000000 --- a/src/commands/meow.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { ApplyOptions } from '@sapphire/decorators'; -import { Command } from '@sapphire/framework'; -import { Message } from 'discord.js'; - -// @ts-ignore -@ApplyOptions({ - description: 'Meow!' -}) -export class UserCommand extends Command { - // Register Chat Input and Context Menu command - public override registerApplicationCommands(registry: Command.Registry) { - // Register Chat Input command - registry.registerChatInputCommand({ - name: this.name, - description: this.description - }); - } - - // Message command - public async messageRun(message: Message) { - return this.sendMeow(message); - } - - // Chat Input (slash) command - public async chatInputRun(interaction: Command.ChatInputCommandInteraction) { - return this.sendMeow(interaction); - } - - private async sendMeow(interactionOrMessage: Message | Command.ChatInputCommandInteraction | Command.ContextMenuCommandInteraction) { - const catResponse = await fetch('https://cataas.com/cat?json=true'); - const catData = await catResponse.json(); - interactionOrMessage instanceof Message - ? await interactionOrMessage.channel.send({ - content: `https://cataas.com/${catData.url}` - }) - : await interactionOrMessage.reply({ - content: `https://cataas.com/${catData.url}`, - fetchReply: true - }); - } -} diff --git a/src/commands/pic.ts b/src/commands/pic.ts index 5fee092..625e107 100644 --- a/src/commands/pic.ts +++ b/src/commands/pic.ts @@ -1,15 +1,18 @@ import { ApplyOptions } from '@sapphire/decorators'; import { Args, BucketScope, Command } from '@sapphire/framework'; import { AttachmentBuilder, Message } from 'discord.js'; +import OpenAI from 'openai'; -// This is literally the world's messiest Typescript code. Please don't judge me... +const openai = new OpenAI({ + apiKey: process.env.OPENAI_API_KEY +}); // @ts-ignore @ApplyOptions({ - description: 'Make a picture... but high res!', + description: 'Pic... but better!', options: ['prompt'], // 10mins - cooldownDelay: 300_000, + cooldownDelay: 400_000, cooldownLimit: 1, // Yes... I did hardcode myself. cooldownFilteredUsers: ['83679718401904640'], @@ -30,62 +33,34 @@ export class UserCommand extends Command { // Message command public async messageRun(message: Message, args: Args) { - return this.picHr(message, args.getOption('prompt') || 'Scold me for not passing any prompt in.'); + return this.pic(message, args.getOption('prompt') || 'NOTHING'); } // Chat Input (slash) command public async chatInputRun(interaction: Command.ChatInputCommandInteraction) { - return this.picHr(interaction, interaction.options.getString('prompt') || 'NOTHING'); + return this.pic(interaction, interaction.options.getString('prompt') || 'NOTHING'); } - private async picHr(interactionOrMessage: Message | Command.ChatInputCommandInteraction | Command.ContextMenuCommandInteraction, prompt: string) { + private async pic(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 creditCountResponse = await fetch(`https://api.stability.ai/v1/user/balance`, { - method: 'GET', - headers: { - 'Content-Type': 'application/json', - Authorization: `Bearer ${process.env.STABILITY_API_KEY}` - } - }); - - const balance = (await creditCountResponse.json()).credits || 0; - - if (balance > 5) { - const imageGenResponse = await fetch(`https://api.stability.ai/v1/generation/stable-diffusion-xl-1024-v1-0/text-to-image`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - Accept: 'application/json', - Authorization: `Bearer ${process.env.STABILITY_API_KEY}` - }, - body: JSON.stringify({ - text_prompts: [ - { - text: prompt - } - ], - cfg_scale: 6, - clip_guidance_preset: 'FAST_BLUE', - height: 1024, - width: 1024, - steps: 32, - seed: Number(String(interactionOrMessage.member?.user.id).substring(0, 5)) || 0 - }) + try { + const response = await openai.images.generate({ + model: 'dall-e-3', + prompt, + n: 1, + size: '1024x1024', + quality: 'standard' }); - interface GenerationResponse { - artifacts: Array<{ - base64: string; - seed: number; - finishReason: string; - }>; - } + const imageUrl = response.data[0].url || ''; + // get an array buffer + const imageBuffer = await fetch(imageUrl).then((r) => r.arrayBuffer()); - if (!imageGenResponse.ok) { + if (response.data.length === 0) { const content = `Sorry, I can't complete the prompt for: ${prompt}`; if (interactionOrMessage instanceof Message) { @@ -96,29 +71,16 @@ export class UserCommand extends Command { content: content }); } else { - const responseJSON = (await imageGenResponse.json()) as GenerationResponse; const imageAttachment: AttachmentBuilder[] = []; - for (let i = 0; i < responseJSON.artifacts.length; i++) { - imageAttachment.push( - new AttachmentBuilder(Buffer.from(responseJSON.artifacts[i].base64, 'base64'), { - name: 'himbot_response.jpg', - description: `An image generated by Himbot using the prompt: ${prompt}` - }) - ); - } + imageAttachment.push( + new AttachmentBuilder(Buffer.from(new Uint8Array(imageBuffer)), { + name: 'himbot_response.jpg', + description: `An image generated by Himbot using the prompt: ${prompt}` + }) + ); - const newCreditCountResponse = await fetch(`https://api.stability.ai/v1/user/balance`, { - method: 'GET', - headers: { - 'Content-Type': 'application/json', - Authorization: `Bearer ${process.env.STABILITY_API_KEY}` - } - }); - - const newBalance = (await newCreditCountResponse.json()).credits || 0; - - const content = `Credits Used: ${balance - newBalance}\nPrompt: ${prompt}` || 'ERROR!'; + const content = `Prompt: ${prompt}:`; if (interactionOrMessage instanceof Message) { return askMessage.edit({ content, files: imageAttachment }); @@ -129,16 +91,14 @@ export class UserCommand extends Command { files: imageAttachment }); } - } else { - const content = `Oops! We're out of credits for this. If you'd like to help fund this command, please type "/support" for details!`; + } catch (error) { + const content = "Sorry, I can't complete the prompt for: " + prompt + '\n' + 'Error: ' + error; if (interactionOrMessage instanceof Message) { return askMessage.edit({ content }); } - return interactionOrMessage.editReply({ - content: content - }); + return interactionOrMessage.editReply({ content }); } } }