UNPKG

@mymj/midjourney

Version:

Node.js client for the unofficial MidJourney API.

201 lines (189 loc) 5.06 kB
import { DiscordImage, MJConfig } from "./interfaces"; export const Commands = [ "ask", "blend", "describe", "fast", "turbo", "help", "imagine", "info", "prefer", "private", "public", "relax", "settings", "show", "stealth", "shorten", "subscribe", ] as const; export type CommandName = (typeof Commands)[number]; function getCommandName(name: string): CommandName | undefined { for (const command of Commands) { if (command === name) { return command; } } } export class Command { constructor(public config: MJConfig) {} cache: Partial<Record<CommandName, any>> = {}; async cacheCommand(name: CommandName) { if (this.cache[name] !== undefined) { return this.cache[name]; } if (this.config.ChannelId) { const command = await this.getCommand(name); this.cache[name] = command; } if (this.cache[name] !== undefined) { return this.cache[name]; } return await this.getCommand(name); } async userCommand() { let url = `${this.config.DiscordBaseUrl}/api/v9/users/@me/application-command-index`; const response = await this.config.fetch(url, { headers: { authorization: this.config.SalaiToken }, }); if (response.status > 300) { console.error(response); throw new Error(`Failed to get application_commands of user for command`); } const data = await response.json(); if (data?.application_commands) { data.application_commands.forEach((command: any) => { const name = getCommandName(command.name); if (name) { this.cache[name] = command; } }); } } async allCommand() { try { let url; if (!this.config.ServerId) { url = `${this.config.DiscordBaseUrl}/api/v9/channels/${this.config.ChannelId}/application-command-index`; } else { url = `${this.config.DiscordBaseUrl}/api/v9/guilds/${this.config.ServerId}/application-command-index`; } const response = await this.config.fetch(url, { headers: { authorization: this.config.SalaiToken }, }); if (response.status > 300) { console.error(response); throw new Error(`Failed to get application_commands for command`); } const data = await response.json(); if (data?.application_commands) { data.application_commands.forEach((command: any) => { const name = getCommandName(command.name); if (name) { this.cache[name] = command; } }); } } catch (error) { console.error('Fail to get command from channel or server'); } if (!this.cache['info']) { await this.userCommand(); } } async getCommand(name: CommandName) { if (this.cache[name]) { return this.cache[name]; } await this.allCommand(); if (this.cache[name]) { return this.cache[name]; } throw new Error(`Missing permission, please make sure you have added MJ Bot.`); } async imaginePayload(prompt: string, nonce?: string) { const data = await this.commandData("imagine", [ { type: 3, name: "prompt", value: prompt, }, ]); return this.data2Paylod(data, nonce); } async PreferPayload(nonce?: string) { const data = await this.commandData("prefer", [ { type: 1, name: "remix", options: [], }, ]); return this.data2Paylod(data, nonce); } async shortenPayload(prompt: string, nonce?: string) { const data = await this.commandData("shorten", [ { type: 3, name: "prompt", value: prompt, }, ]); return this.data2Paylod(data, nonce); } async describePayload(image: DiscordImage, nonce?: string) { const data = await this.commandData( "describe", [ { type: 11, name: "image", value: image.id, }, ], [ { id: <string>image.id, filename: image.filename, uploaded_filename: image.upload_filename, }, ] ); return this.data2Paylod(data, nonce); } async commandPayload(name: CommandName, nonce?:string) { const data = await this.commandData(name); return this.data2Paylod(data, nonce); } protected async commandData( name: CommandName, options: any[] = [], attachments: any[] = [] ) { const command = await this.getCommand(name); const data = { version: command.version, id: command.id, name: command.name, type: command.type, options, application_command: command, attachments, }; return data; } //TODO data type protected data2Paylod(data: any, nonce?: string) { const payload = { type: 2, application_id: data.application_command.application_id, guild_id: this.config.ServerId, channel_id: this.config.ChannelId, session_id: this.config.SessionId, nonce, data, }; return payload; } }