Skip to content

Commit

Permalink
Merge branch 'v2' of https://github.com/spongedsc/SpongeChat into v2
Browse files Browse the repository at this point in the history
  • Loading branch information
artifishvr committed May 18, 2024
2 parents f3dd17f + fd040ca commit d2bd0dc
Show file tree
Hide file tree
Showing 6 changed files with 164 additions and 40 deletions.
21 changes: 21 additions & 0 deletions src/actions/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/**
* Defines the structure of an Action.
*
* @typedef {object} Action
* @property {import('discord.js').RESTPostAPIApplicationCommandsJSONBody} data The data for the command
* @property {(interaction: import('discord.js').ContextMenuCommandInteraction) => Promise<void> | void} execute The function to execute when the command is called
*/

/**
* Defines the predicate to check if an object is a valid Command type.
*
* @type {import('../util/loaders.js').StructurePredicate<Action>}
* @returns {structure is Action}
*/
export const predicate = (structure) =>
Boolean(structure) &&
typeof structure === "object" &&
"data" in structure &&
"execute" in structure &&
typeof structure.data === "object" &&
typeof structure.execute === "function";
76 changes: 76 additions & 0 deletions src/commands/imagine.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import { SlashCommandBuilder } from "discord.js";
import { WorkersAI } from "../util/models/index.js";

/** @type {import('./index.js').Command} */
export default {
data: new SlashCommandBuilder()
.setName("imagine")
.setDescription("Generate an image.")
.addStringOption((o) =>
o
.setName("model")
.setDescription("Enter a description of what you're generating.")
.setChoices([
{
name: "lykon/dreamshaper-8-lcm",
value: "@cf/lykon/dreamshaper-8-lcm",
},
{
name: "bytedance/stable-diffusion-xl-lightning",
value: "@cf/bytedance/stable-diffusion-xl-lightning",
},
{
name: "stabilityai/stable-diffusion-xl-base-1.0",
value: "@cf/stabilityai/stable-diffusion-xl-base-1.0",
},
])
.setRequired(true),
)
.addStringOption((o) =>
o.setName("prompt").setDescription("Enter a description of what you're generating.").setRequired(true),
)
.toJSON(),
async execute(interaction) {
const workersAI = new WorkersAI({
accountId: process.env.CLOUDFLARE_ACCOUNT_ID,
token: process.env.CLOUDFLARE_ACCOUNT_TOKEN,
});

await interaction.deferReply();
const prompt = interaction.options.getString("prompt");
const model = interaction.options.getString("model");

const callToModel = await (async () => {
const prefix = model?.split("/")?.[0];
if (prefix !== "@cf") return;

return await workersAI
.callModel(
{
model,
input: {
prompt,
},
},
true,
)
.then((r) => r.arrayBuffer())
.catch(() => (e) => {
console.error(e);
return null;
});
})();

if (callToModel === null)
return await interaction.editReply({
content: `The model did not generate an image.`,
});

const buffer = Buffer.from(callToModel);

await interaction.editReply({
content: `\`${prompt}\`\n*generated with \`${model}\`*`,
files: [buffer],
});
},
};
44 changes: 44 additions & 0 deletions src/events/interactionCreate.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { Events } from "discord.js";
import chalk from "chalk";

/** @type {import('./index.js').Event<Events.InteractionCreate>} */
export default {
name: Events.InteractionCreate,
async execute(interaction) {
const client = interaction.client;
const commands = client.commandsMap;
const actions = client.actionsMap;

if (interaction.isContextMenuCommand()) {
const action = actions.get(interaction.commandName);

if (!action) {
throw new Error(`Action '${interaction.commandName}' not found.`);
}

await action.execute(interaction).catch((e) => {
console.log(
`${chalk.bold.red("Action")} exception (${interaction.commandName}): \n`,
e,
` ${Temporal.Now.instant().toLocaleString("en-GB", { timeZone: "Etc/UTC", timeZoneName: "short" })}`,
);
});
}

if (interaction.isChatInputCommand()) {
const command = commands.get(interaction.commandName);

if (!command) {
throw new Error(`Command '${interaction.commandName}' not found.`);
}

await command.execute(interaction).catch((e) => {
console.log(
`${chalk.bold.red("Command")} exception (${interaction.commandName}): \n`,
e,
` ${Temporal.Now.instant().toLocaleString("en-GB", { timeZone: "Etc/UTC", timeZoneName: "short" })}`,
);
});
}
},
};
3 changes: 2 additions & 1 deletion src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,10 @@ await cmdRollout();
// Load the events and commands
const events = await loadEvents(new URL("events/", import.meta.url));
const commands = await loadCommands(new URL("commands/", import.meta.url));
const actions = await loadCommands(new URL("actions/", import.meta.url));

// Register the event handlers
registerEvents(commands, events, client);
registerEvents(commands, actions, events, client);

// Login to the client
void client.login(process.env.DISCORD_TOKEN);
29 changes: 15 additions & 14 deletions src/util/deploy.js
Original file line number Diff line number Diff line change
@@ -1,31 +1,32 @@
import process from 'node:process';
import { URL } from 'node:url';
import { API } from '@discordjs/core/http-only';
import { REST } from 'discord.js';
import { Environment } from './helpers.js';
import { loadCommands } from './loaders.js';
import process from "node:process";
import { URL } from "node:url";
import { API } from "@discordjs/core/http-only";
import { REST } from "discord.js";
import { Environment } from "./helpers.js";
import { loadCommands } from "./loaders.js";

import chalk from 'chalk';
import chalk from "chalk";

export const cmdRollout = async () => {
const env = new Environment();

const commands = await loadCommands(new URL('../commands/', import.meta.url));
const commandData = [...commands.values()].map((command) => command.data);
const commands = await loadCommands(new URL("../commands/", import.meta.url));
const actions = await loadCommands(new URL("../actions/", import.meta.url));
const data = [...commands.values(), ...actions.values()].map((command) => command.data);

const rest = new REST({ version: '10' }).setToken(process.env.DISCORD_TOKEN);
const rest = new REST({ version: "10" }).setToken(process.env.DISCORD_TOKEN);
const api = new API(rest);

const result =
env.getRuntimeScenario() === 'development'
env.getRuntimeScenario() === "development"
? await api.applicationCommands.bulkOverwriteGuildCommands(
process.env.APPLICATION_ID,
process.env.DEV_GUILD,
commandData,
data,
)
: await api.applicationCommands.bulkOverwriteGlobalCommands(process.env.APPLICATION_ID, commandData);
: await api.applicationCommands.bulkOverwriteGlobalCommands(process.env.APPLICATION_ID, data);

console.log(
`${chalk.bold.green('Core')} Successfully registered ${chalk.bold(result.length)} commands (${Temporal.Now.instant().toLocaleString('en-GB', { timeZone: 'Etc/UTC', timeZoneName: 'short' })})`,
`${chalk.bold.green("Core")} Successfully registered ${chalk.bold(result.length)} commands/actions (${Temporal.Now.instant().toLocaleString("en-GB", { timeZone: "Etc/UTC", timeZoneName: "short" })})`,
);
};
31 changes: 6 additions & 25 deletions src/util/registerEvents.js
Original file line number Diff line number Diff line change
@@ -1,36 +1,17 @@
import { Events } from "discord.js";
import chalk from "chalk";

/**
* @param {Map<string, import('../commands/index.js').Command>} commands
* @param {import('../events/index.js').Event[]} events
* @param {import('discord.js').Client} client
*/
export function registerEvents(commands, events, client) {
// Create an event to handle command interactions
/** @type {import('../events/index.js').Event<Events.InteractionCreate>} */
const interactionCreateEvent = {
name: Events.InteractionCreate,
async execute(interaction) {
if (interaction.isCommand()) {
const command = commands.get(interaction.commandName);
export function registerEvents(commands, actions, events, client) {
// Move the command map to the client context.
// Necessary change to move interactionCreate into its' own file.
client.commandsMap = commands;
client.actionsMap = actions;

if (!command) {
throw new Error(`Command '${interaction.commandName}' not found.`);
}

await command.execute(interaction).catch((e) => {
console.log(
`${chalk.bold.red("Command")} exception (${interaction.commandName}): \n`,
e,
` ${Temporal.Now.instant().toLocaleString("en-GB", { timeZone: "Etc/UTC", timeZoneName: "short" })}`,
);
});
}
},
};

for (const event of [...events, interactionCreateEvent]) {
for (const event of [...events]) {
client[event.once ? "once" : "on"](event.name, async (...args) => {
try {
return event.execute(...args);
Expand Down

0 comments on commit d2bd0dc

Please sign in to comment.