mirror of
https://github.com/tiramisulabs/seyfert.git
synced 2025-07-02 21:16:09 +00:00
refactor: interactions
This commit is contained in:
parent
89c43eb3a5
commit
b2d4c06222
@ -155,8 +155,29 @@ export function INTERACTION_ID_TOKEN(interactionId: Snowflake, token: string): s
|
||||
return `/interactions/${interactionId}/${token}/callback`;
|
||||
}
|
||||
|
||||
export function WEBHOOK_MESSAGE(webhookId: Snowflake, token: string, messageId: Snowflake): string {
|
||||
return `/webhooks/${webhookId}/${token}/messages/${messageId}`;
|
||||
export function WEBHOOK_MESSAGE_ORIGINAL(webhookId: Snowflake, token: string, options?: { threadId?: bigint }): string {
|
||||
let url = `/webhooks/${webhookId}/${token}/messages/@original?`;
|
||||
|
||||
if (options) {
|
||||
if (options.threadId) url += `threadId=${options.threadId}`;
|
||||
}
|
||||
|
||||
return url;
|
||||
}
|
||||
|
||||
export function WEBHOOK_MESSAGE(
|
||||
webhookId: Snowflake,
|
||||
token: string,
|
||||
messageId: Snowflake,
|
||||
options?: { threadId?: Snowflake }
|
||||
): string {
|
||||
let url = `/webhooks/${webhookId}/${token}/messages/${messageId}?`;
|
||||
|
||||
if (options) {
|
||||
if (options.threadId) url += `threadId=${options.threadId}`;
|
||||
}
|
||||
|
||||
return url;
|
||||
}
|
||||
|
||||
export function WEBHOOK_TOKEN(webhookId: Snowflake, token?: string): string {
|
||||
|
@ -1,14 +1,27 @@
|
||||
import type { Model } from "./Base.ts";
|
||||
import type { Session } from "../Session.ts";
|
||||
import type { Snowflake } from "../Snowflake.ts";
|
||||
import type { DiscordMessage, DiscordWebhook, WebhookTypes } from "../../discordeno/mod.ts";
|
||||
import type { DiscordMessageComponents, DiscordEmbed, DiscordMessage, DiscordWebhook, FileContent, WebhookTypes } from "../../discordeno/mod.ts";
|
||||
import type { WebhookOptions } from "../Routes.ts";
|
||||
import type { CreateMessage } from "./Message.ts";
|
||||
import type { Attachment } from "./Attachment.ts";
|
||||
import type { CreateMessage, AllowedMentions } from "./Message.ts";
|
||||
import Util from "../Util.ts";
|
||||
import User from "./User.ts";
|
||||
import Message from "./Message.ts";
|
||||
import * as Routes from "../Routes.ts";
|
||||
|
||||
/**
|
||||
* @link https://discord.com/developers/docs/resources/webhook#edit-webhook-message-jsonform-params
|
||||
* */
|
||||
export interface EditWebhookMessage {
|
||||
content?: string;
|
||||
embeds?: DiscordEmbed[];
|
||||
files?: FileContent[];
|
||||
allowedMentions?: AllowedMentions;
|
||||
attachments?: Attachment[];
|
||||
components?: DiscordMessageComponents;
|
||||
}
|
||||
|
||||
export class Webhook implements Model {
|
||||
constructor(session: Session, data: DiscordWebhook) {
|
||||
this.session = session;
|
||||
@ -88,7 +101,7 @@ export class Webhook implements Model {
|
||||
return new Webhook(this.session, message);
|
||||
}
|
||||
|
||||
async fetchMessage(messageId: Snowflake): Promise<Message | void> {
|
||||
async fetchMessage(messageId: Snowflake, options?: { threadId?: Snowflake }): Promise<Message | undefined> {
|
||||
if (!this.token) {
|
||||
return;
|
||||
}
|
||||
@ -96,7 +109,60 @@ export class Webhook implements Model {
|
||||
const message = await this.session.rest.runMethod<DiscordMessage>(
|
||||
this.session.rest,
|
||||
"GET",
|
||||
Routes.WEBHOOK_MESSAGE(this.id, this.token, messageId),
|
||||
Routes.WEBHOOK_MESSAGE(this.id, this.token, messageId, options),
|
||||
);
|
||||
|
||||
return new Message(this.session, message);
|
||||
}
|
||||
|
||||
async deleteMessage(messageId: Snowflake, options?: { threadId?: Snowflake }): Promise<void> {
|
||||
if (!this.token) {
|
||||
throw new Error("No token found");
|
||||
}
|
||||
|
||||
await this.session.rest.runMethod<undefined>(
|
||||
this.session.rest,
|
||||
"DELETE",
|
||||
Routes.WEBHOOK_MESSAGE(this.id, this.token, messageId, options),
|
||||
);
|
||||
}
|
||||
|
||||
async editMessage(messageId?: Snowflake, options?: EditWebhookMessage & { threadId?: Snowflake }): Promise<Message> {
|
||||
if (!this.token) {
|
||||
throw new Error("No token found");
|
||||
}
|
||||
|
||||
const message = await this.session.rest.runMethod<DiscordMessage>(
|
||||
this.session.rest,
|
||||
"PATCH",
|
||||
messageId
|
||||
? Routes.WEBHOOK_MESSAGE(this.id, this.token, messageId)
|
||||
: Routes.WEBHOOK_MESSAGE_ORIGINAL(this.id, this.token),
|
||||
{
|
||||
content: options?.content,
|
||||
embeds: options?.embeds,
|
||||
file: options?.files,
|
||||
components: options?.components,
|
||||
allowed_mentions: options?.allowedMentions || {
|
||||
parse: options?.allowedMentions!.parse,
|
||||
replied_user: options?.allowedMentions!.repliedUser,
|
||||
users: options?.allowedMentions!.users,
|
||||
roles: options?.allowedMentions!.roles,
|
||||
},
|
||||
attachments: options?.attachments?.map((attachment) => {
|
||||
return {
|
||||
id: attachment.id,
|
||||
filename: attachment.name,
|
||||
content_type: attachment.contentType,
|
||||
size: attachment.size,
|
||||
url: attachment.attachment,
|
||||
proxy_url: attachment.proxyUrl,
|
||||
height: attachment.height,
|
||||
width: attachment.width,
|
||||
ephemeral: attachment.ephemeral,
|
||||
};
|
||||
}),
|
||||
}
|
||||
);
|
||||
|
||||
return new Message(this.session, message);
|
||||
|
@ -8,38 +8,38 @@ export class InputTextBuilder {
|
||||
#data: DiscordInputTextComponent;
|
||||
type: MessageComponentTypes.InputText;
|
||||
|
||||
setStyle(style: TextStyles): InputTextBuilder {
|
||||
setStyle(style: TextStyles): this {
|
||||
this.#data.style = style;
|
||||
return this;
|
||||
}
|
||||
|
||||
setLabel(label: string): InputTextBuilder {
|
||||
setLabel(label: string): this {
|
||||
this.#data.label = label;
|
||||
return this;
|
||||
}
|
||||
|
||||
setPlaceholder(placeholder: string): InputTextBuilder {
|
||||
setPlaceholder(placeholder: string): this {
|
||||
this.#data.placeholder = placeholder;
|
||||
return this;
|
||||
}
|
||||
|
||||
setLength(max?: number, min?: number): InputTextBuilder {
|
||||
setLength(max?: number, min?: number): this {
|
||||
this.#data.max_length = max;
|
||||
this.#data.min_length = min;
|
||||
return this;
|
||||
}
|
||||
|
||||
setCustomId(id: string): InputTextBuilder {
|
||||
setCustomId(id: string): this {
|
||||
this.#data.custom_id = id;
|
||||
return this;
|
||||
}
|
||||
|
||||
setValue(value: string): InputTextBuilder {
|
||||
setValue(value: string): this {
|
||||
this.#data.value = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
setRequired(required = true): InputTextBuilder {
|
||||
setRequired(required = true): this {
|
||||
this.#data.required = required;
|
||||
return this;
|
||||
}
|
||||
|
@ -9,12 +9,12 @@ export class ActionRowBuilder<T extends ComponentBuilder> {
|
||||
components: T[];
|
||||
type: MessageComponentTypes.ActionRow;
|
||||
|
||||
addComponents(...components: T[]): ActionRowBuilder<T> {
|
||||
addComponents(...components: T[]): this {
|
||||
this.components.push(...components);
|
||||
return this;
|
||||
}
|
||||
|
||||
setComponents(...components: T[]): ActionRowBuilder<T> {
|
||||
setComponents(...components: T[]): this {
|
||||
this.components.splice(
|
||||
0,
|
||||
this.components.length,
|
||||
|
@ -8,32 +8,33 @@ export class ButtonBuilder {
|
||||
}
|
||||
#data: DiscordButtonComponent;
|
||||
type: MessageComponentTypes.Button;
|
||||
setStyle(style: ButtonStyles) {
|
||||
|
||||
setStyle(style: ButtonStyles): this {
|
||||
this.#data.style = style;
|
||||
return this;
|
||||
}
|
||||
|
||||
setLabel(label: string): ButtonBuilder {
|
||||
setLabel(label: string): this {
|
||||
this.#data.label = label;
|
||||
return this;
|
||||
}
|
||||
|
||||
setCustomId(id: string): ButtonBuilder {
|
||||
setCustomId(id: string): this {
|
||||
this.#data.custom_id = id;
|
||||
return this;
|
||||
}
|
||||
|
||||
setEmoji(emoji: ComponentEmoji): ButtonBuilder {
|
||||
setEmoji(emoji: ComponentEmoji): this {
|
||||
this.#data.emoji = emoji;
|
||||
return this;
|
||||
}
|
||||
|
||||
setDisabled(disabled = true): ButtonBuilder {
|
||||
setDisabled(disabled = true): this {
|
||||
this.#data.disabled = disabled;
|
||||
return this;
|
||||
}
|
||||
|
||||
setURL(url: string): ButtonBuilder {
|
||||
setURL(url: string): this {
|
||||
this.#data.url = url;
|
||||
return this;
|
||||
}
|
||||
|
@ -11,28 +11,28 @@ export class SelectMenuBuilder {
|
||||
type: MessageComponentTypes.SelectMenu;
|
||||
options: SelectMenuOptionBuilder[];
|
||||
|
||||
setPlaceholder(placeholder: string): SelectMenuBuilder {
|
||||
setPlaceholder(placeholder: string): this {
|
||||
this.#data.placeholder = placeholder;
|
||||
return this;
|
||||
}
|
||||
|
||||
setValues(max?: number, min?: number): SelectMenuBuilder {
|
||||
setValues(max?: number, min?: number): this {
|
||||
this.#data.max_values = max;
|
||||
this.#data.min_values = min;
|
||||
return this;
|
||||
}
|
||||
|
||||
setDisabled(disabled = true): SelectMenuBuilder {
|
||||
setDisabled(disabled = true): this {
|
||||
this.#data.disabled = disabled;
|
||||
return this;
|
||||
}
|
||||
|
||||
setCustomId(id: string): SelectMenuBuilder {
|
||||
setCustomId(id: string): this {
|
||||
this.#data.custom_id = id;
|
||||
return this;
|
||||
}
|
||||
|
||||
setOptions(...options: SelectMenuOptionBuilder[]): SelectMenuBuilder {
|
||||
setOptions(...options: SelectMenuOptionBuilder[]): this {
|
||||
this.options.splice(
|
||||
0,
|
||||
this.options.length,
|
||||
@ -41,7 +41,7 @@ export class SelectMenuBuilder {
|
||||
return this;
|
||||
}
|
||||
|
||||
addOptions(...options: SelectMenuOptionBuilder[]): SelectMenuBuilder {
|
||||
addOptions(...options: SelectMenuOptionBuilder[]): this {
|
||||
this.options.push(
|
||||
...options,
|
||||
);
|
||||
|
@ -25,31 +25,31 @@ export abstract class ApplicationCommandBuilder implements CreateApplicationComm
|
||||
this.dmPermission = dmPermission;
|
||||
}
|
||||
|
||||
public setType(type: ApplicationCommandTypes): ApplicationCommandBuilder {
|
||||
public setType(type: ApplicationCommandTypes): this {
|
||||
return (this.type = type), this;
|
||||
}
|
||||
|
||||
public setName(name: string): ApplicationCommandBuilder {
|
||||
public setName(name: string): this {
|
||||
return (this.name = name), this;
|
||||
}
|
||||
|
||||
public setDescription(description: string): ApplicationCommandBuilder {
|
||||
public setDescription(description: string): this {
|
||||
return (this.description = description), this;
|
||||
}
|
||||
|
||||
public setDefaultMemberPermission(perm: PermissionStrings[]): ApplicationCommandBuilder {
|
||||
public setDefaultMemberPermission(perm: PermissionStrings[]): this {
|
||||
return (this.defaultMemberPermissions = perm), this;
|
||||
}
|
||||
|
||||
public setNameLocalizations(l: Localization): ApplicationCommandBuilder {
|
||||
public setNameLocalizations(l: Localization): this {
|
||||
return (this.nameLocalizations = l), this;
|
||||
}
|
||||
|
||||
public setDescriptionLocalizations(l: Localization): ApplicationCommandBuilder {
|
||||
public setDescriptionLocalizations(l: Localization): this {
|
||||
return (this.descriptionLocalizations = l), this;
|
||||
}
|
||||
|
||||
public setDmPermission(perm: boolean): ApplicationCommandBuilder {
|
||||
public setDmPermission(perm: boolean): this {
|
||||
return (this.dmPermission = perm), this;
|
||||
}
|
||||
}
|
||||
@ -64,7 +64,7 @@ export class MessageApplicationCommandBuilder {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public setName(name: string): MessageApplicationCommandBuilder {
|
||||
public setName(name: string): this {
|
||||
return (this.name = name), this;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { ApplicationCommandOptionTypes, type ChannelTypes, type Localization } from "../../../../discordeno/mod.ts";
|
||||
import { ApplicationCommandOptionChoice } from "../../interactions/CommandInteraction.ts";
|
||||
import { ApplicationCommandOptionChoice } from "../../interactions/BaseInteraction.ts";
|
||||
|
||||
export class ChoiceBuilder {
|
||||
public name?: string;
|
||||
@ -10,7 +10,7 @@ export class ChoiceBuilder {
|
||||
return this;
|
||||
}
|
||||
|
||||
public setValue(value: string): ChoiceBuilder {
|
||||
public setValue(value: string): this {
|
||||
this.value = value;
|
||||
return this;
|
||||
}
|
||||
@ -36,19 +36,19 @@ export class OptionBuilder {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public setType(type: ApplicationCommandOptionTypes): OptionBuilder {
|
||||
public setType(type: ApplicationCommandOptionTypes): this {
|
||||
return (this.type = type), this;
|
||||
}
|
||||
|
||||
public setName(name: string): OptionBuilder {
|
||||
public setName(name: string): this {
|
||||
return (this.name = name), this;
|
||||
}
|
||||
|
||||
public setDescription(description: string): OptionBuilder {
|
||||
public setDescription(description: string): this {
|
||||
return (this.description = description), this;
|
||||
}
|
||||
|
||||
public setRequired(required: boolean): OptionBuilder {
|
||||
public setRequired(required: boolean): this {
|
||||
return (this.required = required), this;
|
||||
}
|
||||
|
||||
@ -86,15 +86,15 @@ export class OptionBuilderLimitedValues extends OptionBuilder {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public setMinValue(n: number): OptionBuilderLimitedValues {
|
||||
public setMinValue(n: number): this {
|
||||
return (this.minValue = n), this;
|
||||
}
|
||||
|
||||
public setMaxValue(n: number): OptionBuilderLimitedValues {
|
||||
public setMaxValue(n: number): this {
|
||||
return (this.maxValue = n), this;
|
||||
}
|
||||
|
||||
public addChoice(fn: (choice: ChoiceBuilder) => ChoiceBuilder): OptionBuilderLimitedValues {
|
||||
public addChoice(fn: (choice: ChoiceBuilder) => ChoiceBuilder): this {
|
||||
const choice = fn(new ChoiceBuilder());
|
||||
this.choices ??= [];
|
||||
this.choices.push(choice);
|
||||
@ -125,7 +125,7 @@ export class OptionBuilderString extends OptionBuilder {
|
||||
this;
|
||||
}
|
||||
|
||||
public addChoice(fn: (choice: ChoiceBuilder) => ChoiceBuilder): OptionBuilderString {
|
||||
public addChoice(fn: (choice: ChoiceBuilder) => ChoiceBuilder): this {
|
||||
const choice = fn(new ChoiceBuilder());
|
||||
this.choices ??= [];
|
||||
this.choices.push(choice);
|
||||
@ -154,7 +154,7 @@ export class OptionBuilderChannel extends OptionBuilder {
|
||||
this;
|
||||
}
|
||||
|
||||
public addChannelTypes(...channels: ChannelTypes[]): OptionBuilderChannel {
|
||||
public addChannelTypes(...channels: ChannelTypes[]): this {
|
||||
this.channelTypes ??= [];
|
||||
this.channelTypes.push(...channels);
|
||||
return this;
|
||||
@ -183,80 +183,80 @@ export class OptionBased {
|
||||
)
|
||||
& OptionBuilderLike[];
|
||||
|
||||
public addOption(fn: (option: OptionBuilder) => OptionBuilder, type?: ApplicationCommandOptionTypes): OptionBased {
|
||||
public addOption(fn: (option: OptionBuilder) => OptionBuilder, type?: ApplicationCommandOptionTypes): this {
|
||||
const option = fn(new OptionBuilder(type));
|
||||
this.options ??= [];
|
||||
this.options.push(option);
|
||||
return this;
|
||||
}
|
||||
|
||||
public addNestedOption(fn: (option: OptionBuilder) => OptionBuilder): OptionBased {
|
||||
public addNestedOption(fn: (option: OptionBuilder) => OptionBuilder): this {
|
||||
const option = fn(new OptionBuilder(ApplicationCommandOptionTypes.SubCommand));
|
||||
this.options ??= [];
|
||||
this.options.push(option);
|
||||
return this;
|
||||
}
|
||||
|
||||
public addStringOption(fn: (option: OptionBuilderString) => OptionBuilderString): OptionBased {
|
||||
public addStringOption(fn: (option: OptionBuilderString) => OptionBuilderString): this {
|
||||
const option = fn(new OptionBuilderString(ApplicationCommandOptionTypes.String));
|
||||
this.options ??= [];
|
||||
this.options.push(option);
|
||||
return this;
|
||||
}
|
||||
|
||||
public addIntegerOption(fn: (option: OptionBuilderLimitedValues) => OptionBuilderLimitedValues): OptionBased {
|
||||
public addIntegerOption(fn: (option: OptionBuilderLimitedValues) => OptionBuilderLimitedValues): this {
|
||||
const option = fn(new OptionBuilderLimitedValues(ApplicationCommandOptionTypes.Integer));
|
||||
this.options ??= [];
|
||||
this.options.push(option);
|
||||
return this;
|
||||
}
|
||||
|
||||
public addNumberOption(fn: (option: OptionBuilderLimitedValues) => OptionBuilderLimitedValues): OptionBased {
|
||||
public addNumberOption(fn: (option: OptionBuilderLimitedValues) => OptionBuilderLimitedValues): this {
|
||||
const option = fn(new OptionBuilderLimitedValues(ApplicationCommandOptionTypes.Number));
|
||||
this.options ??= [];
|
||||
this.options.push(option);
|
||||
return this;
|
||||
}
|
||||
|
||||
public addBooleanOption(fn: (option: OptionBuilder) => OptionBuilder): OptionBased {
|
||||
public addBooleanOption(fn: (option: OptionBuilder) => OptionBuilder): this {
|
||||
return this.addOption(fn, ApplicationCommandOptionTypes.Boolean);
|
||||
}
|
||||
|
||||
public addSubCommand(fn: (option: OptionBuilderNested) => OptionBuilderNested): OptionBased {
|
||||
public addSubCommand(fn: (option: OptionBuilderNested) => OptionBuilderNested): this {
|
||||
const option = fn(new OptionBuilderNested(ApplicationCommandOptionTypes.SubCommand));
|
||||
this.options ??= [];
|
||||
this.options.push(option);
|
||||
return this;
|
||||
}
|
||||
|
||||
public addSubCommandGroup(fn: (option: OptionBuilderNested) => OptionBuilderNested): OptionBased {
|
||||
public addSubCommandGroup(fn: (option: OptionBuilderNested) => OptionBuilderNested): this {
|
||||
const option = fn(new OptionBuilderNested(ApplicationCommandOptionTypes.SubCommandGroup));
|
||||
this.options ??= [];
|
||||
this.options.push(option);
|
||||
return this;
|
||||
}
|
||||
|
||||
public addUserOption(fn: (option: OptionBuilder) => OptionBuilder): OptionBased {
|
||||
public addUserOption(fn: (option: OptionBuilder) => OptionBuilder): this {
|
||||
return this.addOption(fn, ApplicationCommandOptionTypes.User);
|
||||
}
|
||||
|
||||
public addChannelOption(fn: (option: OptionBuilderChannel) => OptionBuilderChannel): OptionBased {
|
||||
public addChannelOption(fn: (option: OptionBuilderChannel) => OptionBuilderChannel): this {
|
||||
const option = fn(new OptionBuilderChannel(ApplicationCommandOptionTypes.Channel));
|
||||
this.options ??= [];
|
||||
this.options.push(option);
|
||||
return this;
|
||||
}
|
||||
|
||||
public addRoleOption(fn: (option: OptionBuilder) => OptionBuilder): OptionBased {
|
||||
public addRoleOption(fn: (option: OptionBuilder) => OptionBuilder): this {
|
||||
return this.addOption(fn, ApplicationCommandOptionTypes.Role);
|
||||
}
|
||||
|
||||
public addMentionableOption(fn: (option: OptionBuilder) => OptionBuilder): OptionBased {
|
||||
public addMentionableOption(fn: (option: OptionBuilder) => OptionBuilder): this {
|
||||
return this.addOption(fn, ApplicationCommandOptionTypes.Mentionable);
|
||||
}
|
||||
|
||||
// deno-lint-ignore ban-types
|
||||
public static applyTo(klass: Function, ignore: Array<keyof OptionBased> = []) {
|
||||
public static applyTo(klass: Function, ignore: Array<keyof OptionBased> = []): void {
|
||||
const methods: Array<keyof OptionBased> = [
|
||||
"addOption",
|
||||
"addNestedOption",
|
||||
|
@ -1,5 +1,5 @@
|
||||
import type { Session } from "../../Session.ts";
|
||||
import type { DiscordComponent } from "../../../discordeno/mod.ts";
|
||||
import type { DiscordComponent, DiscordInputTextComponent } from "../../../discordeno/mod.ts";
|
||||
import type { ActionRowComponent, Component } from "./Component.ts";
|
||||
import { ButtonStyles, MessageComponentTypes } from "../../../discordeno/mod.ts";
|
||||
import BaseComponent from "./Component.ts";
|
||||
@ -24,7 +24,7 @@ export class ActionRow extends BaseComponent implements ActionRowComponent {
|
||||
case MessageComponentTypes.SelectMenu:
|
||||
return new SelectMenu(session, component);
|
||||
case MessageComponentTypes.InputText:
|
||||
return new InputText(session, component);
|
||||
return new InputText(session, component as DiscordInputTextComponent);
|
||||
case MessageComponentTypes.ActionRow:
|
||||
throw new Error("Cannot have an action row inside an action row");
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
import type { Session } from "../../Session.ts";
|
||||
import type { DiscordComponent } from "../../../discordeno/mod.ts";
|
||||
import type { DiscordComponent, DiscordInputTextComponent } from "../../../discordeno/mod.ts";
|
||||
import type { Component } from "./Component.ts";
|
||||
import { ButtonStyles, MessageComponentTypes } from "../../../discordeno/mod.ts";
|
||||
import ActionRow from "./ActionRowComponent.ts";
|
||||
@ -18,14 +18,12 @@ export class ComponentFactory {
|
||||
case MessageComponentTypes.ActionRow:
|
||||
return new ActionRow(session, component);
|
||||
case MessageComponentTypes.Button:
|
||||
if (component.style === ButtonStyles.Link) {
|
||||
return new LinkButton(session, component);
|
||||
}
|
||||
if (component.style === ButtonStyles.Link) return new LinkButton(session, component);
|
||||
return new Button(session, component);
|
||||
case MessageComponentTypes.SelectMenu:
|
||||
return new SelectMenu(session, component);
|
||||
case MessageComponentTypes.InputText:
|
||||
return new TextInput(session, component);
|
||||
return new TextInput(session, component as DiscordInputTextComponent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ import type { Model } from "../Base.ts";
|
||||
import type { Snowflake } from "../../Snowflake.ts";
|
||||
import type { Session } from "../../Session.ts";
|
||||
import type { ApplicationCommandTypes, DiscordInteraction, InteractionTypes } from "../../../discordeno/mod.ts";
|
||||
import type { ApplicationCommandOptionChoice } from "./CommandInteraction.ts";
|
||||
import type { ApplicationCommandOptionChoice } from "./BaseInteraction.ts";
|
||||
import { InteractionResponseTypes } from "../../../discordeno/mod.ts";
|
||||
import BaseInteraction from "./BaseInteraction.ts";
|
||||
import * as Routes from "../../Routes.ts";
|
||||
@ -23,7 +23,7 @@ export class AutoCompleteInteraction extends BaseInteraction implements Model {
|
||||
commandType: ApplicationCommandTypes;
|
||||
commandGuildId?: Snowflake;
|
||||
|
||||
async respond(choices: ApplicationCommandOptionChoice[]): Promise<void> {
|
||||
async respondWithChoices(choices: ApplicationCommandOptionChoice[]): Promise<void> {
|
||||
await this.session.rest.runMethod<undefined>(
|
||||
this.session.rest,
|
||||
"POST",
|
||||
|
@ -1,16 +1,55 @@
|
||||
import type { Model } from "../Base.ts";
|
||||
import type { Session } from "../../Session.ts";
|
||||
import type { DiscordInteraction } from "../../../discordeno/mod.ts";
|
||||
import type {
|
||||
DiscordInteraction,
|
||||
DiscordMessage,
|
||||
DiscordMessageComponents,
|
||||
} from "../../../discordeno/mod.ts";
|
||||
import type CommandInteraction from "./CommandInteraction.ts";
|
||||
import type PingInteraction from "./PingInteraction.ts";
|
||||
import type ComponentInteraction from "./ComponentInteraction.ts";
|
||||
import type ModalSubmitInteraction from "./ModalSubmitInteraction.ts";
|
||||
import type AutoCompleteInteraction from "./AutoCompleteInteraction.ts";
|
||||
import { InteractionTypes } from "../../../discordeno/mod.ts";
|
||||
import type { CreateMessage } from "../Message.ts";
|
||||
import type { MessageFlags } from "../../Util.ts";
|
||||
import type { EditWebhookMessage } from "../Webhook.ts";
|
||||
import { InteractionTypes, InteractionResponseTypes } from "../../../discordeno/mod.ts";
|
||||
import { Snowflake } from "../../Snowflake.ts";
|
||||
import User from "../User.ts";
|
||||
import Member from "../Member.ts";
|
||||
import Message from "../Message.ts";
|
||||
import Permsisions from "../Permissions.ts";
|
||||
import Webhook from "../Webhook.ts";
|
||||
import * as Routes from "../../Routes.ts";
|
||||
|
||||
|
||||
/**
|
||||
* @link https://discord.com/developers/docs/interactions/slash-commands#interaction-response
|
||||
*/
|
||||
export interface InteractionResponse {
|
||||
type: InteractionResponseTypes;
|
||||
data?: InteractionApplicationCommandCallbackData;
|
||||
}
|
||||
|
||||
/**
|
||||
* @link https://discord.com/developers/docs/interactions/slash-commands#interaction-response-interactionapplicationcommandcallbackdata
|
||||
*/
|
||||
export interface InteractionApplicationCommandCallbackData
|
||||
extends Pick<CreateMessage, "allowedMentions" | "content" | "embeds" | "files"> {
|
||||
customId?: string;
|
||||
title?: string;
|
||||
components?: DiscordMessageComponents;
|
||||
flags?: MessageFlags;
|
||||
choices?: ApplicationCommandOptionChoice[];
|
||||
}
|
||||
|
||||
/**
|
||||
* @link https://discord.com/developers/docs/interactions/slash-commands#applicationcommandoptionchoice
|
||||
*/
|
||||
export interface ApplicationCommandOptionChoice {
|
||||
name: string;
|
||||
value: string | number;
|
||||
}
|
||||
|
||||
export abstract class BaseInteraction implements Model {
|
||||
constructor(session: Session, data: DiscordInteraction) {
|
||||
@ -51,6 +90,8 @@ export abstract class BaseInteraction implements Model {
|
||||
|
||||
readonly version: 1;
|
||||
|
||||
responded = false;
|
||||
|
||||
get createdTimestamp(): number {
|
||||
return Snowflake.snowflakeToTimestamp(this.id);
|
||||
}
|
||||
@ -82,6 +123,153 @@ export abstract class BaseInteraction implements Model {
|
||||
inGuild(): this is this & { guildId: Snowflake } {
|
||||
return !!this.guildId;
|
||||
}
|
||||
|
||||
// webhooks methods:
|
||||
|
||||
async editReply(options: EditWebhookMessage & { messageId?: Snowflake }): Promise<Message | undefined> {
|
||||
const message = await this.session.rest.runMethod<DiscordMessage | undefined>(
|
||||
this.session.rest,
|
||||
"PATCH",
|
||||
options.messageId
|
||||
? Routes.WEBHOOK_MESSAGE(this.id, this.token, options.messageId)
|
||||
: Routes.WEBHOOK_MESSAGE_ORIGINAL(this.id, this.token),
|
||||
{
|
||||
content: options.content,
|
||||
embeds: options.embeds,
|
||||
file: options.files,
|
||||
components: options.components,
|
||||
allowed_mentions: options.allowedMentions || {
|
||||
parse: options.allowedMentions!.parse,
|
||||
replied_user: options.allowedMentions!.repliedUser,
|
||||
users: options.allowedMentions!.users,
|
||||
roles: options.allowedMentions!.roles,
|
||||
},
|
||||
attachments: options.attachments?.map((attachment) => {
|
||||
return {
|
||||
id: attachment.id,
|
||||
filename: attachment.name,
|
||||
content_type: attachment.contentType,
|
||||
size: attachment.size,
|
||||
url: attachment.attachment,
|
||||
proxy_url: attachment.proxyUrl,
|
||||
height: attachment.height,
|
||||
width: attachment.width,
|
||||
};
|
||||
}),
|
||||
message_id: options.messageId,
|
||||
}
|
||||
);
|
||||
|
||||
if (!message || !options.messageId) {
|
||||
return message as undefined;
|
||||
}
|
||||
|
||||
return new Message(this.session, message);
|
||||
}
|
||||
|
||||
async sendFollowUp(options: InteractionApplicationCommandCallbackData): Promise<Message> {
|
||||
const message = await Webhook.prototype.execute.call({
|
||||
id: this.applicationId!,
|
||||
token: this.token,
|
||||
session: this.session,
|
||||
}, options);
|
||||
|
||||
return message!;
|
||||
}
|
||||
|
||||
async editFollowUp(messageId: Snowflake, options?: { threadId: Snowflake }): Promise<Message> {
|
||||
const message = await Webhook.prototype.editMessage.call(
|
||||
{
|
||||
id: this.session.applicationId,
|
||||
token: this.token,
|
||||
},
|
||||
messageId,
|
||||
options
|
||||
);
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
async deleteFollowUp(messageId: Snowflake, options?: { threadId?: Snowflake }): Promise<void> {
|
||||
await Webhook.prototype.deleteMessage.call(
|
||||
{
|
||||
id: this.session.applicationId,
|
||||
token: this.token
|
||||
},
|
||||
messageId,
|
||||
options
|
||||
);
|
||||
}
|
||||
|
||||
async fetchFollowUp(messageId: Snowflake, options?: { threadId?: Snowflake }): Promise<Message | undefined> {
|
||||
const message = await Webhook.prototype.fetchMessage.call(
|
||||
{
|
||||
id: this.session.applicationId,
|
||||
token: this.token,
|
||||
},
|
||||
messageId,
|
||||
options
|
||||
);
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
// end webhook methods
|
||||
|
||||
// deno-fmt-ignore
|
||||
async respond(resp: InteractionResponse): Promise<Message | undefined>;
|
||||
async respond(resp: { with: InteractionApplicationCommandCallbackData }): Promise<Message | undefined>;
|
||||
async respond(resp: InteractionResponse | { with: InteractionApplicationCommandCallbackData }): Promise<Message | undefined> {
|
||||
const options = "with" in resp ? resp.with : resp.data;
|
||||
const type = "type" in resp ? resp.type : InteractionResponseTypes.ChannelMessageWithSource;
|
||||
|
||||
const data = {
|
||||
content: options?.content,
|
||||
custom_id: options?.customId,
|
||||
file: options?.files,
|
||||
allowed_mentions: options?.allowedMentions,
|
||||
flags: options?.flags,
|
||||
chocies: options?.choices,
|
||||
embeds: options?.embeds,
|
||||
title: options?.title,
|
||||
components: options?.components,
|
||||
};
|
||||
|
||||
if (!this.responded) {
|
||||
await this.session.rest.sendRequest<undefined>(this.session.rest, {
|
||||
url: Routes.INTERACTION_ID_TOKEN(this.id, this.token),
|
||||
method: "POST",
|
||||
payload: this.session.rest.createRequestBody(this.session.rest, {
|
||||
method: "POST",
|
||||
body: { type, data, file: options?.files },
|
||||
headers: { "Authorization": "" },
|
||||
}),
|
||||
});
|
||||
|
||||
this.responded = true;
|
||||
return;
|
||||
}
|
||||
|
||||
return this.sendFollowUp(data);
|
||||
}
|
||||
|
||||
// start custom methods
|
||||
|
||||
async respondWith(resp: InteractionApplicationCommandCallbackData): Promise<Message | undefined> {
|
||||
const m = await this.respond({ with: resp });
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
async defer() {
|
||||
await this.respond({ type: InteractionResponseTypes.DeferredChannelMessageWithSource });
|
||||
}
|
||||
|
||||
async autocomplete() {
|
||||
await this.respond({ type: InteractionResponseTypes.ApplicationCommandAutocompleteResult });
|
||||
}
|
||||
|
||||
// end custom methods
|
||||
}
|
||||
|
||||
export default BaseInteraction;
|
||||
|
@ -6,11 +6,7 @@ import type {
|
||||
DiscordInteraction,
|
||||
DiscordMemberWithUser,
|
||||
InteractionTypes,
|
||||
DiscordMessageComponents,
|
||||
} from "../../../discordeno/mod.ts";
|
||||
import type { CreateMessage } from "../Message.ts";
|
||||
import type { MessageFlags } from "../../Util.ts";
|
||||
import { InteractionResponseTypes } from "../../../discordeno/mod.ts";
|
||||
import BaseInteraction from "./BaseInteraction.ts";
|
||||
import CommandInteractionOptionResolver from "./CommandInteractionOptionResolver.ts";
|
||||
import Attachment from "../Attachment.ts";
|
||||
@ -18,36 +14,6 @@ import User from "../User.ts";
|
||||
import Member from "../Member.ts";
|
||||
import Message from "../Message.ts";
|
||||
import Role from "../Role.ts";
|
||||
import Webhook from "../Webhook.ts";
|
||||
import * as Routes from "../../Routes.ts";
|
||||
|
||||
/**
|
||||
* @link https://discord.com/developers/docs/interactions/slash-commands#interaction-response
|
||||
*/
|
||||
export interface InteractionResponse {
|
||||
type: InteractionResponseTypes;
|
||||
data?: InteractionApplicationCommandCallbackData;
|
||||
}
|
||||
|
||||
/**
|
||||
* @link https://discord.com/developers/docs/interactions/slash-commands#interaction-response-interactionapplicationcommandcallbackdata
|
||||
*/
|
||||
export interface InteractionApplicationCommandCallbackData
|
||||
extends Pick<CreateMessage, "allowedMentions" | "content" | "embeds" | "files"> {
|
||||
customId?: string;
|
||||
title?: string;
|
||||
components?: DiscordMessageComponents;
|
||||
flags?: MessageFlags;
|
||||
choices?: ApplicationCommandOptionChoice[];
|
||||
}
|
||||
|
||||
/**
|
||||
* @link https://discord.com/developers/docs/interactions/slash-commands#applicationcommandoptionchoice
|
||||
*/
|
||||
export interface ApplicationCommandOptionChoice {
|
||||
name: string;
|
||||
value: string | number;
|
||||
}
|
||||
|
||||
export class CommandInteraction extends BaseInteraction implements Model {
|
||||
constructor(session: Session, data: DiscordInteraction) {
|
||||
@ -111,47 +77,6 @@ export class CommandInteraction extends BaseInteraction implements Model {
|
||||
messages: Map<Snowflake, Message>;
|
||||
};
|
||||
options: CommandInteractionOptionResolver;
|
||||
responded = false;
|
||||
|
||||
async sendFollowUp(options: InteractionApplicationCommandCallbackData): Promise<Message> {
|
||||
const message = await Webhook.prototype.execute.call({
|
||||
id: this.applicationId!,
|
||||
token: this.token,
|
||||
session: this.session,
|
||||
}, options);
|
||||
|
||||
return message!;
|
||||
}
|
||||
|
||||
async respond({ type, data: options }: InteractionResponse): Promise<Message | undefined> {
|
||||
const data = {
|
||||
content: options?.content,
|
||||
custom_id: options?.customId,
|
||||
file: options?.files,
|
||||
allowed_mentions: options?.allowedMentions,
|
||||
flags: options?.flags,
|
||||
chocies: options?.choices,
|
||||
embeds: options?.embeds,
|
||||
title: options?.title,
|
||||
};
|
||||
|
||||
if (!this.responded) {
|
||||
await this.session.rest.sendRequest<undefined>(this.session.rest, {
|
||||
url: Routes.INTERACTION_ID_TOKEN(this.id, this.token),
|
||||
method: "POST",
|
||||
payload: this.session.rest.createRequestBody(this.session.rest, {
|
||||
method: "POST",
|
||||
body: { type, data, file: options?.files },
|
||||
headers: { "Authorization": "" },
|
||||
}),
|
||||
});
|
||||
|
||||
this.responded = true;
|
||||
return;
|
||||
}
|
||||
|
||||
return this.sendFollowUp(data);
|
||||
}
|
||||
}
|
||||
|
||||
export default CommandInteraction;
|
||||
|
@ -2,9 +2,7 @@ import type { Model } from "../Base.ts";
|
||||
import type { Snowflake } from "../../Snowflake.ts";
|
||||
import type { Session } from "../../Session.ts";
|
||||
import type { DiscordInteraction, InteractionTypes } from "../../../discordeno/mod.ts";
|
||||
import type { InteractionApplicationCommandCallbackData, InteractionResponse } from "./CommandInteraction.ts";
|
||||
import { MessageComponentTypes } from "../../../discordeno/mod.ts";
|
||||
import CommandInteraction from "./CommandInteraction.ts";
|
||||
import { MessageComponentTypes, InteractionResponseTypes } from "../../../discordeno/mod.ts";
|
||||
import BaseInteraction from "./BaseInteraction.ts";
|
||||
import Message from "../Message.ts";
|
||||
|
||||
@ -25,7 +23,6 @@ export class ComponentInteraction extends BaseInteraction implements Model {
|
||||
targetId?: Snowflake;
|
||||
values?: string[];
|
||||
message: Message;
|
||||
responded = false;
|
||||
|
||||
//TODO: create interface/class for components types
|
||||
isButton(): boolean {
|
||||
@ -44,12 +41,8 @@ export class ComponentInteraction extends BaseInteraction implements Model {
|
||||
return this.componentType === MessageComponentTypes.SelectMenu;
|
||||
}
|
||||
|
||||
sendFollowUp(options: InteractionApplicationCommandCallbackData): Promise<Message> {
|
||||
return CommandInteraction.prototype.sendFollowUp.call(this, options);
|
||||
}
|
||||
|
||||
respond(options: InteractionResponse): Promise<Message | undefined> {
|
||||
return CommandInteraction.prototype.respond.call(this, options);
|
||||
async deferUpdate() {
|
||||
await this.respond({ type: InteractionResponseTypes.DeferredUpdateMessage });
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -14,11 +14,11 @@ export class EventEmitter {
|
||||
return this;
|
||||
}
|
||||
|
||||
on(event: string, func: Function) {
|
||||
on(event: string, func: Function): this {
|
||||
return this.#addListener(event, func);
|
||||
}
|
||||
|
||||
#removeListener(event: string, func: Function): EventEmitter {
|
||||
#removeListener(event: string, func: Function): this {
|
||||
if (this.listeners.has(event)) {
|
||||
const listener = this.listeners.get(event);
|
||||
|
||||
@ -34,11 +34,11 @@ export class EventEmitter {
|
||||
return this;
|
||||
}
|
||||
|
||||
off(event: string, func: Function): EventEmitter {
|
||||
off(event: string, func: Function): this {
|
||||
return this.#removeListener(event, func);
|
||||
}
|
||||
|
||||
once(event: string, func: Function): EventEmitter {
|
||||
once(event: string, func: Function): this {
|
||||
// it is important for this to be an arrow function
|
||||
const closure = () => {
|
||||
func();
|
||||
|
Loading…
x
Reference in New Issue
Block a user