From 36efda0fcd951212f54fb0b187176ba0992fe445 Mon Sep 17 00:00:00 2001 From: Atridad Lahiji <88056492+atridadl@users.noreply.github.com> Date: Fri, 7 Jul 2023 17:52:54 -0600 Subject: [PATCH] hr pic --- src/commands/pic.ts | 8 +-- src/commands/pic_hr.ts | 137 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 141 insertions(+), 4 deletions(-) create mode 100644 src/commands/pic_hr.ts diff --git a/src/commands/pic.ts b/src/commands/pic.ts index 4bb802a..420ea95 100644 --- a/src/commands/pic.ts +++ b/src/commands/pic.ts @@ -8,7 +8,7 @@ import { AttachmentBuilder, Message } from 'discord.js'; description: 'Make a picture!', options: ['prompt'], // 10mins - cooldownDelay: 300_000, + cooldownDelay: 100_000, cooldownLimit: 1, // Yes... I did hardcode myself. cooldownFilteredUsers: ['83679718401904640'], @@ -52,7 +52,7 @@ export class UserCommand extends Command { const balance = (await creditCountResponse.json()).credits || 0; if (balance > 5) { - const imageGenResponse = await fetch(`https://api.stability.ai/v1/generation/stable-diffusion-xl-1024-v0-9/text-to-image`, { + const imageGenResponse = await fetch(`https://api.stability.ai/v1/generation/stable-diffusion-xl-beta-v2-2-2/text-to-image`, { method: 'POST', headers: { 'Content-Type': 'application/json', @@ -67,8 +67,8 @@ export class UserCommand extends Command { ], cfg_scale: 6, clip_guidance_preset: 'FAST_BLUE', - height: 1024, - width: 1024, + height: 512, + width: 512, samples: 1, steps: 32 }) diff --git a/src/commands/pic_hr.ts b/src/commands/pic_hr.ts new file mode 100644 index 0000000..1ce3466 --- /dev/null +++ b/src/commands/pic_hr.ts @@ -0,0 +1,137 @@ +import { ApplyOptions } from '@sapphire/decorators'; +import { Args, BucketScope, Command } from '@sapphire/framework'; +import { AttachmentBuilder, Message } from 'discord.js'; + +// This is literally the worlds messiest TS code. Please don't judge me... + +@ApplyOptions({ + description: 'Make a picture... but high res!', + options: ['prompt'], + // 10mins + cooldownDelay: 300_000, + cooldownLimit: 1, + // Yes... I did hardcode myself. + cooldownFilteredUsers: ['83679718401904640'], + cooldownScope: BucketScope.User +}) +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('Make a picture... but high res!').setRequired(true)) + ); + } + + // Message command + public async messageRun(message: Message, args: Args) { + return this.picHr(message, args.getOption('prompt') || message.content.split('!pic_hr ')[1]); + } + + // Chat Input (slash) command + public async chatInputRun(interaction: Command.ChatInputCommandInteraction) { + return this.picHr(interaction, interaction.options.getString('prompt') || 'NOTHING'); + } + + private async picHr(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-v0-9/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, + samples: 1, + steps: 32 + }) + }); + + interface GenerationResponse { + artifacts: Array<{ + base64: string; + seed: number; + finishReason: string; + }>; + } + + if (!imageGenResponse.ok) { + const content = `Sorry! I goofed up. Please ask my maker HimbothySwaggins about what could have happened!`; + + if (interactionOrMessage instanceof Message) { + return askMessage.edit({ content }); + } + + return interactionOrMessage.editReply({ + content: content + }); + } else { + const responseJSON = (await imageGenResponse.json()) as GenerationResponse; + const imageAttachment = new AttachmentBuilder(Buffer.from(responseJSON.artifacts[0].base64, 'base64')); + + 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}${ + balance <= 300 + ? `\n\nāš ļøI am now at ${balance} credits. If you'd like to help fund this command, please type "/support" for details!` + : '' + }` || 'ERROR!'; + + if (interactionOrMessage instanceof Message) { + return askMessage.edit({ content, files: [imageAttachment] }); + } + + return interactionOrMessage.editReply({ + content: content, + 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!`; + + if (interactionOrMessage instanceof Message) { + return askMessage.edit({ content }); + } + + return interactionOrMessage.editReply({ + content: content + }); + } + } +}