Changed the buntime!
This commit is contained in:
parent
2d0e8ab106
commit
6b53e17c49
20 changed files with 210 additions and 1548 deletions
24
Dockerfile
24
Dockerfile
|
@ -1,10 +1,10 @@
|
|||
# syntax = docker/dockerfile:1
|
||||
|
||||
# Adjust NODE_VERSION as desired
|
||||
ARG NODE_VERSION=18.14.2
|
||||
FROM node:${NODE_VERSION}-slim as base
|
||||
ARG BUN_VERSION=1.0.9
|
||||
FROM oven/bun:${BUN_VERSION} as base
|
||||
|
||||
LABEL fly_launch_runtime="Node.js"
|
||||
LABEL fly_launch_runtime="Bun"
|
||||
|
||||
# Node.js app lives here
|
||||
WORKDIR /app
|
||||
|
@ -12,11 +12,6 @@ WORKDIR /app
|
|||
# Set production environment
|
||||
ENV NODE_ENV="production"
|
||||
|
||||
# Install pnpm
|
||||
ARG PNPM_VERSION=8.9.0
|
||||
RUN npm install -g pnpm@$PNPM_VERSION
|
||||
|
||||
|
||||
# Throw-away build stage to reduce size of final image
|
||||
FROM base as build
|
||||
|
||||
|
@ -25,19 +20,12 @@ RUN apt-get update -qq && \
|
|||
apt-get install -y build-essential pkg-config python-is-python3
|
||||
|
||||
# Install node modules
|
||||
COPY --link .npmrc package.json pnpm-lock.yaml ./
|
||||
RUN pnpm install --frozen-lockfile --prod=false
|
||||
COPY --link .npmrc package.json bun.lockb ./
|
||||
RUN bun install --ci
|
||||
|
||||
# Copy application code
|
||||
COPY --link . .
|
||||
|
||||
# Build application
|
||||
RUN pnpm run build
|
||||
|
||||
# Remove development dependencies
|
||||
RUN pnpm prune --prod
|
||||
|
||||
|
||||
# Final stage for app image
|
||||
FROM base
|
||||
|
||||
|
@ -46,4 +34,4 @@ COPY --from=build /app /app
|
|||
|
||||
# Start the server by default, this can be overwritten at runtime
|
||||
EXPOSE 3000
|
||||
CMD [ "pnpm", "run", "start" ]
|
||||
CMD [ "bun", "start" ]
|
||||
|
|
BIN
bun.lockb
Executable file
BIN
bun.lockb
Executable file
Binary file not shown.
|
@ -34,10 +34,9 @@
|
|||
"scripts": {
|
||||
"sapphire": "sapphire",
|
||||
"generate": "sapphire generate",
|
||||
"build": "tsc",
|
||||
"watch": "tsc -w",
|
||||
"start": "node dist/index.js",
|
||||
"dev": "npm run build && npm run start",
|
||||
"start": "bun run src/index.ts",
|
||||
"dev": "bun run src/index.ts",
|
||||
"watch:start": "tsc-watch --onSuccess \"npm run start\"",
|
||||
"format": "prettier --write \"src/\""
|
||||
},
|
||||
|
|
1082
pnpm-lock.yaml
generated
1082
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load diff
|
@ -1,19 +1,19 @@
|
|||
import { ApplyOptions } from '@sapphire/decorators';
|
||||
import { Args, Command } from '@sapphire/framework';
|
||||
import { AttachmentBuilder, Message, blockQuote, codeBlock } from 'discord.js';
|
||||
import { Command, container } from '@sapphire/framework';
|
||||
import { AttachmentBuilder, blockQuote, codeBlock } from 'discord.js';
|
||||
import OpenAI from 'openai';
|
||||
|
||||
const openai = new OpenAI({
|
||||
apiKey: process.env.OPENAI_API_KEY
|
||||
});
|
||||
|
||||
// @ts-ignore
|
||||
@ApplyOptions<Command.Options>({
|
||||
description: 'You can ACTUALLY ask Himbot something! So cool!',
|
||||
options: ['prompt']
|
||||
})
|
||||
export class UserCommand extends Command {
|
||||
// Register Chat Input and Context Menu command
|
||||
export class AskCommand extends Command {
|
||||
public constructor(context: Command.LoaderContext) {
|
||||
super(context, {
|
||||
description: 'You can ACTUALLY ask Himbot something! So cool!',
|
||||
options: ['prompt']
|
||||
});
|
||||
}
|
||||
|
||||
public override registerApplicationCommands(registry: Command.Registry) {
|
||||
registry.registerChatInputCommand((builder) =>
|
||||
builder
|
||||
|
@ -25,21 +25,10 @@ export class UserCommand extends Command {
|
|||
);
|
||||
}
|
||||
|
||||
// Message command
|
||||
public async messageRun(message: Message, args: Args) {
|
||||
return this.ask(message, args.getOption('prompt') || message.content.split('!ask ')[1]);
|
||||
}
|
||||
|
||||
// Chat Input (slash) command
|
||||
public async chatInputRun(interaction: Command.ChatInputCommandInteraction) {
|
||||
return this.ask(interaction, interaction.options.getString('prompt') || 'NOTHING');
|
||||
}
|
||||
const prompt = interaction.options.getString('prompt');
|
||||
|
||||
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 });
|
||||
await interaction.reply({ content: '🤔 Thinking... 🤔', fetchReply: true });
|
||||
|
||||
const chatCompletion = await openai.chat.completions.create({
|
||||
model: 'gpt-4-1106-preview',
|
||||
|
@ -64,17 +53,7 @@ export class UserCommand extends Command {
|
|||
);
|
||||
}
|
||||
|
||||
if (interactionOrMessage instanceof Message) {
|
||||
return askMessage.edit({
|
||||
content:
|
||||
content.length < 2000
|
||||
? content
|
||||
: `Discord only allows messages with 2000 characters or less. Please see your response in the attached file!`,
|
||||
files: messageAttachment
|
||||
});
|
||||
}
|
||||
|
||||
return interactionOrMessage.editReply({
|
||||
return interaction.editReply({
|
||||
content:
|
||||
content.length < 2000
|
||||
? content
|
||||
|
@ -83,3 +62,9 @@ export class UserCommand extends Command {
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
void container.stores.loadPiece({
|
||||
store: 'commands',
|
||||
name: 'ask',
|
||||
piece: AskCommand
|
||||
});
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
import { ApplyOptions } from '@sapphire/decorators';
|
||||
import { Command } from '@sapphire/framework';
|
||||
import { Message } from 'discord.js';
|
||||
import { Command, container } from '@sapphire/framework';
|
||||
|
||||
export class BorfCommand extends Command {
|
||||
public constructor(context: Command.LoaderContext) {
|
||||
super(context, {
|
||||
description: 'Borf! Borf!'
|
||||
});
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
@ApplyOptions<Command.Options>({
|
||||
description: 'Borf! Borf!'
|
||||
})
|
||||
export class UserCommand extends Command {
|
||||
// Register Chat Input and Context Menu command
|
||||
public override registerApplicationCommands(registry: Command.Registry) {
|
||||
// Register Chat Input command
|
||||
|
@ -16,27 +16,20 @@ export class UserCommand extends Command {
|
|||
});
|
||||
}
|
||||
|
||||
// Message command
|
||||
public async messageRun(message: Message) {
|
||||
return this.sendBorf(message);
|
||||
}
|
||||
|
||||
// Chat Input (slash) command
|
||||
public async chatInputRun(interaction: Command.ChatInputCommandInteraction) {
|
||||
return this.sendBorf(interaction);
|
||||
}
|
||||
|
||||
private async sendBorf(interactionOrMessage: Message | Command.ChatInputCommandInteraction | Command.ContextMenuCommandInteraction) {
|
||||
const dogResponse = await fetch('https://dog.ceo/api/breeds/image/random');
|
||||
const dogData = (await dogResponse.json()) as { message: string; status: string };
|
||||
|
||||
interactionOrMessage instanceof Message
|
||||
? await interactionOrMessage.channel.send({
|
||||
content: dogData?.status === 'success' ? dogData.message : 'Error: I had troubles fetching perfect puppies for you... :('
|
||||
})
|
||||
: await interactionOrMessage.reply({
|
||||
content: dogData.status === 'success' ? dogData.message : 'Error: I had troubles fetching perfect puppies for you... :(',
|
||||
fetchReply: true
|
||||
});
|
||||
await interaction.reply({
|
||||
content: dogData.status === 'success' ? dogData.message : 'Error: I had troubles fetching perfect puppies for you... :(',
|
||||
fetchReply: true
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void container.stores.loadPiece({
|
||||
store: 'commands',
|
||||
name: 'borf',
|
||||
piece: BorfCommand
|
||||
});
|
||||
|
|
|
@ -1,23 +1,23 @@
|
|||
import { ApplyOptions } from '@sapphire/decorators';
|
||||
import { Args, BucketScope, Command } from '@sapphire/framework';
|
||||
import { AttachmentBuilder, Message } from 'discord.js';
|
||||
import { BucketScope, Command, container } from '@sapphire/framework';
|
||||
import { AttachmentBuilder } from 'discord.js';
|
||||
import OpenAI from 'openai';
|
||||
|
||||
const openai = new OpenAI({
|
||||
apiKey: process.env.OPENAI_API_KEY
|
||||
});
|
||||
|
||||
// @ts-ignore
|
||||
@ApplyOptions<Command.Options>({
|
||||
description: 'Generate an image using OpenAI! Cooldown of 10 Minutes due to cost!',
|
||||
options: ['prompt'],
|
||||
cooldownDelay: 480_000,
|
||||
cooldownLimit: 1,
|
||||
// Yes... I did hardcode myself.
|
||||
cooldownFilteredUsers: ['83679718401904640'],
|
||||
cooldownScope: BucketScope.User
|
||||
})
|
||||
export class UserCommand extends Command {
|
||||
export class HDPicCommand extends Command {
|
||||
public constructor(context: Command.LoaderContext) {
|
||||
super(context, {
|
||||
description: 'Generate an image using OpenAI! Cooldown of 10 Minutes due to cost!',
|
||||
options: ['prompt'],
|
||||
cooldownDelay: 480_000,
|
||||
cooldownLimit: 1,
|
||||
cooldownFilteredUsers: ['83679718401904640'],
|
||||
cooldownScope: BucketScope.User
|
||||
});
|
||||
}
|
||||
|
||||
// Register Chat Input and Context Menu command
|
||||
public override registerApplicationCommands(registry: Command.Registry) {
|
||||
registry.registerChatInputCommand((builder) =>
|
||||
|
@ -30,21 +30,11 @@ export class UserCommand extends Command {
|
|||
);
|
||||
}
|
||||
|
||||
// Message command
|
||||
public async messageRun(message: Message, args: Args) {
|
||||
return this.pic(message, args.getOption('prompt') || 'NOTHING');
|
||||
}
|
||||
|
||||
// Chat Input (slash) command
|
||||
public async chatInputRun(interaction: Command.ChatInputCommandInteraction) {
|
||||
return this.pic(interaction, interaction.options.getString('prompt') || 'NOTHING');
|
||||
}
|
||||
const prompt = interaction.options.getString('prompt') || '';
|
||||
|
||||
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 });
|
||||
await interaction.reply({ content: '🤔 Thinking... 🤔', fetchReply: true });
|
||||
|
||||
try {
|
||||
const response = await openai.images.generate({
|
||||
|
@ -70,22 +60,20 @@ export class UserCommand extends Command {
|
|||
|
||||
const content = `Prompt: ${prompt}:`;
|
||||
|
||||
if (interactionOrMessage instanceof Message) {
|
||||
return askMessage.edit({ content, files: imageAttachment });
|
||||
}
|
||||
|
||||
return interactionOrMessage.editReply({
|
||||
return interaction.editReply({
|
||||
content,
|
||||
files: imageAttachment
|
||||
});
|
||||
} catch (error) {
|
||||
const content = "Sorry, I can't complete the prompt for: " + prompt + '\n' + error;
|
||||
|
||||
if (interactionOrMessage instanceof Message) {
|
||||
return askMessage.edit({ content });
|
||||
}
|
||||
|
||||
return interactionOrMessage.editReply({ content });
|
||||
return interaction.editReply({ content });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void container.stores.loadPiece({
|
||||
store: 'commands',
|
||||
name: 'hdpic',
|
||||
piece: HDPicCommand
|
||||
});
|
||||
|
|
|
@ -1,23 +1,24 @@
|
|||
import { ApplyOptions } from '@sapphire/decorators';
|
||||
import { Args, BucketScope, Command } from '@sapphire/framework';
|
||||
import { AttachmentBuilder, Message, MessageFlags } from 'discord.js';
|
||||
import { BucketScope, Command, container } from '@sapphire/framework';
|
||||
import { AttachmentBuilder, MessageFlags } from 'discord.js';
|
||||
import OpenAI from 'openai';
|
||||
|
||||
const openai = new OpenAI({
|
||||
apiKey: process.env.OPENAI_API_KEY
|
||||
});
|
||||
|
||||
// @ts-ignore
|
||||
@ApplyOptions<Command.Options>({
|
||||
description: 'Generate "HD" TTS every 2 minutes!',
|
||||
options: ['prompt'],
|
||||
cooldownDelay: 200_000,
|
||||
cooldownLimit: 1,
|
||||
// Yes... I did hardcode myself.
|
||||
cooldownFilteredUsers: ['83679718401904640'],
|
||||
cooldownScope: BucketScope.User
|
||||
})
|
||||
export class UserCommand extends Command {
|
||||
export class HDTTSCommand extends Command {
|
||||
public constructor(context: Command.LoaderContext) {
|
||||
super(context, {
|
||||
description: 'Generate "HD" TTS every 2 minutes!',
|
||||
options: ['prompt'],
|
||||
cooldownDelay: 200_000,
|
||||
cooldownLimit: 1,
|
||||
// Yes... I did hardcode myself.
|
||||
cooldownFilteredUsers: ['83679718401904640'],
|
||||
cooldownScope: BucketScope.User
|
||||
});
|
||||
}
|
||||
|
||||
// Register Chat Input and Context Menu command
|
||||
public override registerApplicationCommands(registry: Command.Registry) {
|
||||
registry.registerChatInputCommand((builder) =>
|
||||
|
@ -28,22 +29,11 @@ export class UserCommand extends Command {
|
|||
);
|
||||
}
|
||||
|
||||
// Message command
|
||||
public async messageRun(message: Message, args: Args) {
|
||||
return this.tts(message, args.getOption('prompt') || 'NOTHING');
|
||||
}
|
||||
|
||||
// Chat Input (slash) command
|
||||
public async chatInputRun(interaction: Command.ChatInputCommandInteraction) {
|
||||
return this.tts(interaction, interaction.options.getString('prompt') || 'NOTHING');
|
||||
}
|
||||
|
||||
private async tts(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 prompt = interaction.options.getString('prompt') || 'NOTHING';
|
||||
|
||||
await interaction.reply({ content: '🤔 Thinking... 🤔', fetchReply: true });
|
||||
try {
|
||||
enum voice {
|
||||
alloy = 'alloy',
|
||||
|
@ -73,15 +63,7 @@ export class UserCommand extends Command {
|
|||
|
||||
const content = `Prompt: ${prompt}:`;
|
||||
|
||||
if (interactionOrMessage instanceof Message) {
|
||||
return askMessage.edit({
|
||||
content,
|
||||
files: mp3Attachment,
|
||||
flags: '8192'
|
||||
});
|
||||
}
|
||||
|
||||
return interactionOrMessage.editReply({
|
||||
return interaction.editReply({
|
||||
content,
|
||||
files: mp3Attachment,
|
||||
options: {
|
||||
|
@ -91,15 +73,15 @@ export class UserCommand extends Command {
|
|||
} catch (error) {
|
||||
const content = "Sorry, I can't complete the prompt for: " + prompt + '\n' + error;
|
||||
|
||||
if (interactionOrMessage instanceof Message) {
|
||||
return askMessage.edit({
|
||||
content
|
||||
});
|
||||
}
|
||||
|
||||
return interactionOrMessage.editReply({
|
||||
return interaction.editReply({
|
||||
content
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void container.stores.loadPiece({
|
||||
store: 'commands',
|
||||
name: 'hdtts',
|
||||
piece: HDTTSCommand
|
||||
});
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
import { ApplyOptions } from '@sapphire/decorators';
|
||||
import { Args, Command } from '@sapphire/framework';
|
||||
import { Message } from 'discord.js';
|
||||
import { Command, container } from '@sapphire/framework';
|
||||
|
||||
export class HighSchoolCommand extends Command {
|
||||
public constructor(context: Command.LoaderContext) {
|
||||
super(context, {
|
||||
description: 'This command was your nickname in highschool!',
|
||||
options: ['nickname']
|
||||
});
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
@ApplyOptions<Command.Options>({
|
||||
description: 'This command was your nickname in highschool!',
|
||||
options: ['nickname']
|
||||
})
|
||||
export class UserCommand extends Command {
|
||||
// Register Chat Input and Context Menu command
|
||||
public override registerApplicationCommands(registry: Command.Registry) {
|
||||
registry.registerChatInputCommand((builder) =>
|
||||
|
@ -18,27 +18,18 @@ export class UserCommand extends Command {
|
|||
);
|
||||
}
|
||||
|
||||
// Message command
|
||||
public async messageRun(message: Message, args: Args) {
|
||||
return this.sendPing(message, args.getOption('nickname') || message.content.split('!wryna ')[1]);
|
||||
}
|
||||
|
||||
// Chat Input (slash) command
|
||||
public async chatInputRun(interaction: Command.ChatInputCommandInteraction) {
|
||||
return this.sendPing(interaction, interaction.options.getString('nickname') || 'NOTHING');
|
||||
}
|
||||
|
||||
private async sendPing(
|
||||
interactionOrMessage: Message | Command.ChatInputCommandInteraction | Command.ContextMenuCommandInteraction,
|
||||
nickname: string
|
||||
) {
|
||||
interactionOrMessage instanceof Message
|
||||
? await interactionOrMessage.channel.send({
|
||||
content: `${nickname} was ${interactionOrMessage.author.username}'s nickname in highschool!`
|
||||
})
|
||||
: await interactionOrMessage.reply({
|
||||
content: `${nickname} was ${interactionOrMessage.user.username}'s nickname in highschool!`,
|
||||
fetchReply: true
|
||||
});
|
||||
const nickname = interaction.options.getString('nickname') || 'NOTHING';
|
||||
await interaction.reply({
|
||||
content: `${nickname} was ${interaction.user.username}'s nickname in highschool!`,
|
||||
fetchReply: true
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void container.stores.loadPiece({
|
||||
store: 'commands',
|
||||
name: 'hs',
|
||||
piece: HighSchoolCommand
|
||||
});
|
||||
|
|
|
@ -1,24 +1,24 @@
|
|||
import { ApplyOptions } from '@sapphire/decorators';
|
||||
import { Args, BucketScope, Command } from '@sapphire/framework';
|
||||
import { AttachmentBuilder, Message } from 'discord.js';
|
||||
import { BucketScope, Command, container } from '@sapphire/framework';
|
||||
import { AttachmentBuilder } from 'discord.js';
|
||||
import Replicate from 'replicate';
|
||||
|
||||
const replicate = new Replicate({
|
||||
auth: process.env.REPLICATE_API_TOKEN
|
||||
});
|
||||
|
||||
// @ts-ignore
|
||||
@ApplyOptions<Command.Options>({
|
||||
description: 'Generate an image using Stability AI! Cooldown 1 Minute to prevent spam!',
|
||||
options: ['prompt'],
|
||||
// 10mins
|
||||
cooldownDelay: 100_000,
|
||||
cooldownLimit: 1,
|
||||
// Yes... I did hardcode myself.
|
||||
cooldownFilteredUsers: ['83679718401904640'],
|
||||
cooldownScope: BucketScope.User
|
||||
})
|
||||
export class UserCommand extends Command {
|
||||
export class PicCommand extends Command {
|
||||
public constructor(context: Command.LoaderContext) {
|
||||
super(context, {
|
||||
description: 'Generate an image using Stability AI! Cooldown 1 Minute to prevent spam!',
|
||||
options: ['prompt'],
|
||||
cooldownDelay: 100_000,
|
||||
cooldownLimit: 1,
|
||||
// Yes... I did hardcode myself.
|
||||
cooldownFilteredUsers: ['83679718401904640'],
|
||||
cooldownScope: BucketScope.User
|
||||
});
|
||||
}
|
||||
|
||||
// Register Chat Input and Context Menu command
|
||||
public override registerApplicationCommands(registry: Command.Registry) {
|
||||
registry.registerChatInputCommand((builder) =>
|
||||
|
@ -31,21 +31,11 @@ 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.');
|
||||
}
|
||||
|
||||
// Chat Input (slash) command
|
||||
public async chatInputRun(interaction: Command.ChatInputCommandInteraction) {
|
||||
return this.picHr(interaction, interaction.options.getString('prompt') || 'NOTHING');
|
||||
}
|
||||
const prompt = 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 });
|
||||
await interaction.reply({ content: '🤔 Thinking... 🤔', fetchReply: true });
|
||||
|
||||
let result = (await replicate.run('stability-ai/sdxl:39ed52f2a78e934b3ba6e2a89f5b1c712de7dfea535525255b1aa35c5565e08b', {
|
||||
input: {
|
||||
|
@ -66,11 +56,7 @@ export class UserCommand extends Command {
|
|||
if (result.length <= 0) {
|
||||
const content = `Sorry, I can't complete the prompt for: ${prompt}`;
|
||||
|
||||
if (interactionOrMessage instanceof Message) {
|
||||
return askMessage.edit({ content });
|
||||
}
|
||||
|
||||
return interactionOrMessage.editReply({
|
||||
return interaction.editReply({
|
||||
content: content
|
||||
});
|
||||
} else {
|
||||
|
@ -89,14 +75,16 @@ export class UserCommand extends Command {
|
|||
|
||||
const content = `Prompt: ${prompt}`;
|
||||
|
||||
if (interactionOrMessage instanceof Message) {
|
||||
return askMessage.edit({ content, files: imageAttachment });
|
||||
}
|
||||
|
||||
return interactionOrMessage.editReply({
|
||||
return interaction.editReply({
|
||||
content,
|
||||
files: imageAttachment
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void container.stores.loadPiece({
|
||||
store: 'commands',
|
||||
name: 'pic',
|
||||
piece: PicCommand
|
||||
});
|
||||
|
|
|
@ -1,47 +0,0 @@
|
|||
import { ApplyOptions } from '@sapphire/decorators';
|
||||
import { Command } from '@sapphire/framework';
|
||||
import { Message } from 'discord.js';
|
||||
|
||||
// @ts-ignore
|
||||
@ApplyOptions<Command.Options>({
|
||||
description: 'Pong!'
|
||||
})
|
||||
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.sendPing(message);
|
||||
}
|
||||
|
||||
// Chat Input (slash) command
|
||||
public async chatInputRun(interaction: Command.ChatInputCommandInteraction) {
|
||||
return this.sendPing(interaction);
|
||||
}
|
||||
|
||||
private async sendPing(interactionOrMessage: Message | Command.ChatInputCommandInteraction | Command.ContextMenuCommandInteraction) {
|
||||
const pingMessage =
|
||||
interactionOrMessage instanceof Message
|
||||
? await interactionOrMessage.channel.send({ content: 'Ping?' })
|
||||
: await interactionOrMessage.reply({ content: 'Ping?', fetchReply: true });
|
||||
|
||||
const content = `Pong! Bot Latency ${Math.round(this.container.client.ws.ping)}ms. API Latency ${
|
||||
pingMessage.createdTimestamp - interactionOrMessage.createdTimestamp
|
||||
}ms.`;
|
||||
|
||||
if (interactionOrMessage instanceof Message) {
|
||||
return pingMessage.edit({ content });
|
||||
}
|
||||
|
||||
return interactionOrMessage.editReply({
|
||||
content: content
|
||||
});
|
||||
}
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
import { ApplyOptions } from '@sapphire/decorators';
|
||||
import { Command } from '@sapphire/framework';
|
||||
import { Message } from 'discord.js';
|
||||
|
||||
// @ts-ignore
|
||||
@ApplyOptions<Command.Options>({
|
||||
description: 'Quack!'
|
||||
})
|
||||
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.sendQuack(message);
|
||||
}
|
||||
|
||||
// Chat Input (slash) command
|
||||
public async chatInputRun(interaction: Command.ChatInputCommandInteraction) {
|
||||
return this.sendQuack(interaction);
|
||||
}
|
||||
|
||||
private async sendQuack(interactionOrMessage: Message | Command.ChatInputCommandInteraction | Command.ContextMenuCommandInteraction) {
|
||||
const duckResponse = await fetch('https://random-d.uk/api/v2/quack');
|
||||
const duckData = (await duckResponse.json()) as { url: string };
|
||||
|
||||
interactionOrMessage instanceof Message
|
||||
? await interactionOrMessage.channel.send({
|
||||
content: duckData.url
|
||||
})
|
||||
: await interactionOrMessage.reply({
|
||||
content: duckData.url,
|
||||
fetchReply: true
|
||||
});
|
||||
}
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
import { ApplyOptions } from '@sapphire/decorators';
|
||||
import { Command } from '@sapphire/framework';
|
||||
import { Message } from 'discord.js';
|
||||
|
||||
// @ts-ignore
|
||||
@ApplyOptions<Command.Options>({
|
||||
description: "Help support HimBot's AI features."
|
||||
})
|
||||
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.sendSupport(message);
|
||||
}
|
||||
|
||||
// Chat Input (slash) command
|
||||
public async chatInputRun(interaction: Command.ChatInputCommandInteraction) {
|
||||
return this.sendSupport(interaction);
|
||||
}
|
||||
|
||||
private async sendSupport(interactionOrMessage: Message | Command.ChatInputCommandInteraction | Command.ContextMenuCommandInteraction) {
|
||||
interactionOrMessage instanceof Message
|
||||
? await interactionOrMessage.channel.send({
|
||||
content: 'Thanks! The link to donate is here: https://buy.stripe.com/eVa6p95ho0Kn33a8wx'
|
||||
})
|
||||
: await interactionOrMessage.reply({
|
||||
content: 'Thanks! The link to donate is here: https://buy.stripe.com/eVa6p95ho0Kn33a8wx',
|
||||
fetchReply: true
|
||||
});
|
||||
}
|
||||
}
|
|
@ -1,13 +1,13 @@
|
|||
import { ApplyOptions } from '@sapphire/decorators';
|
||||
import { Args, Command } from '@sapphire/framework';
|
||||
import { Message } from 'discord.js';
|
||||
import { Command, container } from '@sapphire/framework';
|
||||
|
||||
export class TitleCommand extends Command {
|
||||
public constructor(context: Command.LoaderContext) {
|
||||
super(context, {
|
||||
description: 'This command is the title of your sextape.',
|
||||
options: ['title']
|
||||
});
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
@ApplyOptions<Command.Options>({
|
||||
description: 'This command is the title of your sextape.',
|
||||
options: ['title']
|
||||
})
|
||||
export class UserCommand extends Command {
|
||||
// Register Chat Input and Context Menu command
|
||||
public override registerApplicationCommands(registry: Command.Registry) {
|
||||
registry.registerChatInputCommand((builder) =>
|
||||
|
@ -18,27 +18,19 @@ export class UserCommand extends Command {
|
|||
);
|
||||
}
|
||||
|
||||
// Message command
|
||||
public async messageRun(message: Message, args: Args) {
|
||||
return this.titleHandler(message, args.getOption('title') || message.content.split('!title ')[1]);
|
||||
}
|
||||
|
||||
// Chat Input (slash) command
|
||||
public async chatInputRun(interaction: Command.ChatInputCommandInteraction) {
|
||||
return this.titleHandler(interaction, interaction.options.getString('title') || 'NOTHING');
|
||||
}
|
||||
const title = interaction.options.getString('title') || 'NOTHING';
|
||||
|
||||
private async titleHandler(
|
||||
interactionOrMessage: Message | Command.ChatInputCommandInteraction | Command.ContextMenuCommandInteraction,
|
||||
title: string
|
||||
) {
|
||||
interactionOrMessage instanceof Message
|
||||
? await interactionOrMessage.channel.send({
|
||||
content: `${title}: Title of ${interactionOrMessage.author.username}'s sex tape!`
|
||||
})
|
||||
: await interactionOrMessage.reply({
|
||||
content: `${title}: Title of ${interactionOrMessage.user.username}'s sex tape!`,
|
||||
fetchReply: true
|
||||
});
|
||||
await interaction.reply({
|
||||
content: `${title}: Title of ${interaction.user.username}'s sex tape!`,
|
||||
fetchReply: true
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void container.stores.loadPiece({
|
||||
store: 'commands',
|
||||
name: 'title',
|
||||
piece: TitleCommand
|
||||
});
|
||||
|
|
|
@ -1,23 +1,24 @@
|
|||
import { ApplyOptions } from '@sapphire/decorators';
|
||||
import { Args, BucketScope, Command } from '@sapphire/framework';
|
||||
import { AttachmentBuilder, Message, MessageFlags } from 'discord.js';
|
||||
import { BucketScope, Command, container } from '@sapphire/framework';
|
||||
import { AttachmentBuilder, MessageFlags } from 'discord.js';
|
||||
import OpenAI from 'openai';
|
||||
|
||||
const openai = new OpenAI({
|
||||
apiKey: process.env.OPENAI_API_KEY
|
||||
});
|
||||
|
||||
// @ts-ignore
|
||||
@ApplyOptions<Command.Options>({
|
||||
description: 'Generate TTS every minute!',
|
||||
options: ['prompt'],
|
||||
cooldownDelay: 100_000,
|
||||
cooldownLimit: 1,
|
||||
// Yes... I did hardcode myself.
|
||||
cooldownFilteredUsers: ['83679718401904640'],
|
||||
cooldownScope: BucketScope.User
|
||||
})
|
||||
export class UserCommand extends Command {
|
||||
export class TTSCommand extends Command {
|
||||
public constructor(context: Command.LoaderContext) {
|
||||
super(context, {
|
||||
description: 'Generate TTS every minute!',
|
||||
options: ['prompt'],
|
||||
cooldownDelay: 100_000,
|
||||
cooldownLimit: 1,
|
||||
// Yes... I did hardcode myself.
|
||||
cooldownFilteredUsers: ['83679718401904640'],
|
||||
cooldownScope: BucketScope.User
|
||||
});
|
||||
}
|
||||
|
||||
// Register Chat Input and Context Menu command
|
||||
public override registerApplicationCommands(registry: Command.Registry) {
|
||||
registry.registerChatInputCommand((builder) =>
|
||||
|
@ -28,21 +29,11 @@ export class UserCommand extends Command {
|
|||
);
|
||||
}
|
||||
|
||||
// Message command
|
||||
public async messageRun(message: Message, args: Args) {
|
||||
return this.tts(message, args.getOption('prompt') || 'NOTHING');
|
||||
}
|
||||
|
||||
// Chat Input (slash) command
|
||||
public async chatInputRun(interaction: Command.ChatInputCommandInteraction) {
|
||||
return this.tts(interaction, interaction.options.getString('prompt') || 'NOTHING');
|
||||
}
|
||||
const prompt = interaction.options.getString('prompt') || 'NOTHING';
|
||||
|
||||
private async tts(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 });
|
||||
await interaction.reply({ content: '🤔 Thinking... 🤔', fetchReply: true });
|
||||
|
||||
try {
|
||||
enum voice {
|
||||
|
@ -73,15 +64,7 @@ export class UserCommand extends Command {
|
|||
|
||||
const content = `Prompt: ${prompt}:`;
|
||||
|
||||
if (interactionOrMessage instanceof Message) {
|
||||
return askMessage.edit({
|
||||
content,
|
||||
files: mp3Attachment,
|
||||
flags: '8192'
|
||||
});
|
||||
}
|
||||
|
||||
return interactionOrMessage.editReply({
|
||||
return interaction.editReply({
|
||||
content,
|
||||
files: mp3Attachment,
|
||||
options: {
|
||||
|
@ -91,15 +74,15 @@ export class UserCommand extends Command {
|
|||
} catch (error) {
|
||||
const content = "Sorry, I can't complete the prompt for: " + prompt + '\n' + error;
|
||||
|
||||
if (interactionOrMessage instanceof Message) {
|
||||
return askMessage.edit({
|
||||
content
|
||||
});
|
||||
}
|
||||
|
||||
return interactionOrMessage.editReply({
|
||||
return interaction.editReply({
|
||||
content
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void container.stores.loadPiece({
|
||||
store: 'commands',
|
||||
name: 'tts',
|
||||
piece: TTSCommand
|
||||
});
|
||||
|
|
14
src/index.ts
14
src/index.ts
|
@ -1,4 +1,14 @@
|
|||
import './lib/setup';
|
||||
import './listeners/ready';
|
||||
import './commands/ask';
|
||||
import './commands/borf';
|
||||
import './commands/hdpic';
|
||||
import './commands/hdtts';
|
||||
import './commands/hs';
|
||||
import './commands/pic';
|
||||
import './commands/title';
|
||||
import './commands/tts';
|
||||
import './listeners/commands/chatInputCommands/chatInputCommandSuccess';
|
||||
import { LogLevel, SapphireClient, BucketScope } from '@sapphire/framework';
|
||||
import { ActivityType, GatewayIntentBits } from 'discord.js';
|
||||
|
||||
|
@ -18,7 +28,6 @@ const client = new SapphireClient({
|
|||
level: LogLevel.Debug
|
||||
},
|
||||
intents: [GatewayIntentBits.DirectMessages, GatewayIntentBits.GuildMessages, GatewayIntentBits.Guilds, GatewayIntentBits.MessageContent],
|
||||
loadMessageCommandListeners: true,
|
||||
defaultCooldown: {
|
||||
// 10s
|
||||
delay: 10_000,
|
||||
|
@ -27,7 +36,8 @@ const client = new SapphireClient({
|
|||
// Yes... I did hardcode myself.
|
||||
filteredUsers: ['83679718401904640'],
|
||||
scope: BucketScope.User
|
||||
}
|
||||
},
|
||||
baseUserDirectory: null
|
||||
});
|
||||
|
||||
const main = async () => {
|
||||
|
|
|
@ -1,21 +1,11 @@
|
|||
import {
|
||||
container,
|
||||
type ChatInputCommandSuccessPayload,
|
||||
type Command,
|
||||
type ContextMenuCommandSuccessPayload,
|
||||
type MessageCommandSuccessPayload
|
||||
} from '@sapphire/framework';
|
||||
import { container, type ChatInputCommandSuccessPayload, type Command, type ContextMenuCommandSuccessPayload } from '@sapphire/framework';
|
||||
import { cyan } from 'colorette';
|
||||
import type { APIUser, Guild, User } from 'discord.js';
|
||||
|
||||
export function logSuccessCommand(payload: ContextMenuCommandSuccessPayload | ChatInputCommandSuccessPayload | MessageCommandSuccessPayload): void {
|
||||
export function logSuccessCommand(payload: ContextMenuCommandSuccessPayload | ChatInputCommandSuccessPayload): void {
|
||||
let successLoggerData: ReturnType<typeof getSuccessLoggerData>;
|
||||
|
||||
if ('interaction' in payload) {
|
||||
successLoggerData = getSuccessLoggerData(payload.interaction.guild, payload.interaction.user, payload.command);
|
||||
} else {
|
||||
successLoggerData = getSuccessLoggerData(payload.message.guild, payload.message.author, payload.command);
|
||||
}
|
||||
successLoggerData = getSuccessLoggerData(payload.interaction.guild, payload.interaction.user, payload.command);
|
||||
|
||||
container.logger.debug(`${successLoggerData.shard} - ${successLoggerData.commandName} ${successLoggerData.author} ${successLoggerData.sentAt}`);
|
||||
}
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
import type { Events, MessageCommandDeniedPayload } from '@sapphire/framework';
|
||||
import { Listener, type UserError } from '@sapphire/framework';
|
||||
|
||||
export class UserEvent extends Listener<typeof Events.MessageCommandDenied> {
|
||||
public async run({ context, message: content }: UserError, { message }: MessageCommandDeniedPayload) {
|
||||
// `context: { silent: true }` should make UserError silent:
|
||||
// Use cases for this are for example permissions error when running the `eval` command.
|
||||
if (Reflect.get(Object(context), 'silent')) return;
|
||||
|
||||
return message.reply({ content, allowedMentions: { users: [message.author.id], roles: [] } });
|
||||
}
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
import type { MessageCommandSuccessPayload } from '@sapphire/framework';
|
||||
import { Listener, LogLevel } from '@sapphire/framework';
|
||||
import type { Logger } from '@sapphire/plugin-logger';
|
||||
import { logSuccessCommand } from '../../../lib/utils';
|
||||
|
||||
export class UserEvent extends Listener {
|
||||
public run(payload: MessageCommandSuccessPayload) {
|
||||
logSuccessCommand(payload);
|
||||
}
|
||||
|
||||
public onLoad() {
|
||||
this.enabled = (this.container.logger as Logger).level <= LogLevel.Debug;
|
||||
return super.onLoad();
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
import { ApplyOptions } from '@sapphire/decorators';
|
||||
import { Listener, Store } from '@sapphire/framework';
|
||||
import { Listener, Store, container } from '@sapphire/framework';
|
||||
import { blue, gray, green, magenta, magentaBright, white, yellow } from 'colorette';
|
||||
|
||||
const dev = process.env.NODE_ENV !== 'production';
|
||||
|
@ -41,11 +41,17 @@ ${line03}${dev ? ` ${pad}${blc('<')}${llc('/')}${blc('>')} ${llc('DEVELOPMENT MO
|
|||
const stores = [...client.stores.values()];
|
||||
const last = stores.pop()!;
|
||||
|
||||
for (const store of stores) logger.info(this.styleStore(store, false));
|
||||
logger.info(this.styleStore(last, true));
|
||||
for (const store of stores) logger.info(this.styleStore(store));
|
||||
logger.info(this.styleStore(last));
|
||||
}
|
||||
|
||||
private styleStore(store: Store<any>, last: boolean) {
|
||||
return gray(`${last ? '└─' : '├─'} Loaded ${this.style(store.size.toString().padEnd(3, ' '))} ${store.name}.`);
|
||||
private styleStore(store: Store<any>) {
|
||||
return gray(`${'└─'} Loaded ${this.style(store.size.toString().padEnd(3, ' '))} ${store.name}.`);
|
||||
}
|
||||
}
|
||||
|
||||
void container.stores.loadPiece({
|
||||
piece: UserEvent,
|
||||
name: 'ready',
|
||||
store: 'listeners'
|
||||
});
|
||||
|
|
Loading…
Add table
Reference in a new issue