ts-discord-wrapper
Version:
A wrapper for the Discord API written in TypeScript
127 lines (102 loc) • 5.92 kB
text/typescript
import {SlashCommandBuilder} from "../interactions/slash/SlashCommandBuilder.ts";
import {TSDiscordWrapper} from "../TSDiscordWrapper.ts";
import {ApplicationCommandsEndpoint} from "./EndPoint.ts";
import {DefaultApiException} from "rest-api-handler";
export class SlashInfoSender {
private readonly slashCommands: SlashCommandBuilder[];
private tSDiscordWrapper: TSDiscordWrapper;
private readonly applicationId: string;
constructor(slashCommands: SlashCommandBuilder[], tSDiscordWrapper: TSDiscordWrapper) {
this.slashCommands = slashCommands;
this.tSDiscordWrapper = tSDiscordWrapper;
if (this.tSDiscordWrapper.applicationId === undefined) {
throw new Error("Application id is undefined.");
}
this.applicationId = this.tSDiscordWrapper.applicationId;
this.sendSlashCommands();
}
private sendSlashCommands() {
const promiseCurrentGlobalSlashCommands =
this.getGlobalSlashCommands();
let currentGlobalSlashCommands: Map<number, string>;
promiseCurrentGlobalSlashCommands.then((slashCommands) => {
currentGlobalSlashCommands = slashCommands;
const globalSlashCommands: Map<String, SlashCommandBuilder> = new Map();
for (const slashCommand of this.slashCommands) {
globalSlashCommands.set(slashCommand.getName(), slashCommand);
}
const globalSlashCommandsToRemove: number[] = [];
const globalSlashCommandsToAdd: SlashCommandBuilder[] = [];
for (const [id, name] of currentGlobalSlashCommands) {
if (globalSlashCommands.has(name)) {
globalSlashCommandsToAdd.push(globalSlashCommands.get(name) as SlashCommandBuilder);
} else if (!globalSlashCommands.has(name)) {
globalSlashCommandsToRemove.push(id);
} else {
globalSlashCommandsToAdd.push(globalSlashCommands.get(name) as SlashCommandBuilder);
}
}
for (const [name, slashCommand] of globalSlashCommands) {
const valuesArray = Array.from(currentGlobalSlashCommands.values());
if (!valuesArray.includes(name as string)) {
globalSlashCommandsToAdd.push(slashCommand);
}
}
//To avoid rate limits, we will send the slash commands in batches of 5.
//delete slash commands
const globalSlashCommandsToRemoveBatches: number[][] = [];
const globalSlashCommandsToAddBatches: SlashCommandBuilder[][] = [];
for (let i = 0; i < globalSlashCommandsToRemove.length; i += 5) {
globalSlashCommandsToRemoveBatches.push(globalSlashCommandsToRemove.slice(i, i + 5));
}
for (let i = 0; i < globalSlashCommandsToAdd.length; i += 5) {
globalSlashCommandsToAddBatches.push(globalSlashCommandsToAdd.slice(i, i + 5));
}
for (const globalSlashCommandsToRemoveBatch of globalSlashCommandsToRemoveBatches) {
this.deleteGlobalSlashCommands(globalSlashCommandsToRemoveBatch).then(r => {
this.tSDiscordWrapper.logger.debug("Deleted slash commands: " + globalSlashCommandsToRemoveBatch.map(slashCommand => slashCommand).join(", "));
}).catch(e => {
this.tSDiscordWrapper.logger.error("Failed to delete slash commands: " + globalSlashCommandsToRemoveBatch.map(slashCommand => slashCommand).join(", "));
});
}
for (const globalSlashCommandsToAddBatch of globalSlashCommandsToAddBatches) {
this.addGlobalSlashCommands(globalSlashCommandsToAddBatch).catch(e => {
if (e instanceof DefaultApiException) {
this.tSDiscordWrapper.logger.error("Failed to add slash commands: " + globalSlashCommandsToAddBatch.map(slashCommand => slashCommand.getName()).join(", ") + " because of " + e.getResponse().status + " " + e.getResponse().data.message);
} else {
this.tSDiscordWrapper.logger.error("Failed to add slash commands: " + globalSlashCommandsToAddBatch.map(slashCommand => slashCommand.getName()).join(", ") + " because of " + e);
}
});
}
});
}
private async getGlobalSlashCommands(): Promise<Map<number, string>> {
try {
const response = await this.tSDiscordWrapper.restApiHandler.performGetRequest(ApplicationCommandsEndpoint.GET_GLOBAL_COMMANDS, [this.applicationId]);
if (response == null) {
return new Map();
} else {
const slashCommands: Map<number, string> = new Map();
for (const slashCommand of response) {
slashCommands.set(slashCommand.id, slashCommand.name);
}
return slashCommands;
}
} catch (error) {
return new Map();
}
}
private async deleteGlobalSlashCommands(ids: number[]): Promise<void> {
return this.tSDiscordWrapper.restApiHandler
.performDeleteRequest(ApplicationCommandsEndpoint.DELETE_GLOBAL_COMMAND, [this.applicationId, ids.toString()])
.then((response) => {
return;
});
}
private async addGlobalSlashCommands(slashCommands: SlashCommandBuilder[]) {
for (const slashCommand of slashCommands) {
await this.tSDiscordWrapper.restApiHandler
.performPostRequest(ApplicationCommandsEndpoint.CREATE_GLOBAL_COMMAND, slashCommand.toJson(), [this.applicationId])
}
}
}