mirror of
https://github.com/tiramisulabs/seyfert.git
synced 2025-07-01 20:46:08 +00:00

* fix(Message): delete() params * feat: fetches guilds items * fix(types): literal types * fix
276 lines
9.0 KiB
TypeScript
276 lines
9.0 KiB
TypeScript
import type { Model } from '../Base.ts';
|
|
import type { Session } from '../../Session.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 type { CreateMessage } from '../Message.ts';
|
|
import type { MessageFlags } from '../../Util.ts';
|
|
import type { EditWebhookMessage } from '../Webhook.ts';
|
|
import { InteractionResponseTypes, InteractionTypes } 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';
|
|
|
|
export type InteractionResponseWith = { with: InteractionApplicationCommandCallbackData };
|
|
export type InteractionResponseWithData = InteractionResponse | InteractionResponseWith;
|
|
|
|
/**
|
|
* @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) {
|
|
this.session = session;
|
|
this.id = data.id;
|
|
this.token = data.token;
|
|
this.type = data.type;
|
|
this.guildId = data.guild_id;
|
|
this.channelId = data.channel_id;
|
|
this.applicationId = data.application_id;
|
|
this.version = data.version;
|
|
|
|
// @ts-expect-error: vendor error
|
|
const perms = data.app_permissions as string;
|
|
|
|
if (perms) {
|
|
this.appPermissions = new Permsisions(BigInt(perms));
|
|
}
|
|
|
|
if (!data.guild_id) {
|
|
this.user = new User(session, data.user!);
|
|
} else {
|
|
this.member = new Member(session, data.member!, data.guild_id);
|
|
}
|
|
}
|
|
|
|
readonly session: Session;
|
|
readonly id: Snowflake;
|
|
readonly token: string;
|
|
|
|
type: InteractionTypes;
|
|
guildId?: Snowflake;
|
|
channelId?: Snowflake;
|
|
applicationId?: Snowflake;
|
|
user?: User;
|
|
member?: Member;
|
|
appPermissions?: Permsisions;
|
|
|
|
readonly version: 1;
|
|
|
|
responded = false;
|
|
|
|
get createdTimestamp(): number {
|
|
return Snowflake.snowflakeToTimestamp(this.id);
|
|
}
|
|
|
|
get createdAt(): Date {
|
|
return new Date(this.createdTimestamp);
|
|
}
|
|
|
|
isCommand(): this is CommandInteraction {
|
|
return this.type === InteractionTypes.ApplicationCommand;
|
|
}
|
|
|
|
isAutoComplete(): this is AutoCompleteInteraction {
|
|
return this.type === InteractionTypes.ApplicationCommandAutocomplete;
|
|
}
|
|
|
|
isComponent(): this is ComponentInteraction {
|
|
return this.type === InteractionTypes.MessageComponent;
|
|
}
|
|
|
|
isPing(): this is PingInteraction {
|
|
return this.type === InteractionTypes.Ping;
|
|
}
|
|
|
|
isModalSubmit(): this is ModalSubmitInteraction {
|
|
return this.type === InteractionTypes.ModalSubmit;
|
|
}
|
|
|
|
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, threadId?: Snowflake): Promise<void> {
|
|
await Webhook.prototype.deleteMessage.call(
|
|
{
|
|
id: this.session.applicationId,
|
|
token: this.token,
|
|
},
|
|
messageId,
|
|
threadId,
|
|
);
|
|
}
|
|
|
|
async fetchFollowUp(messageId: Snowflake, threadId?: Snowflake): Promise<Message | undefined> {
|
|
const message = await Webhook.prototype.fetchMessage.call(
|
|
{
|
|
id: this.session.applicationId,
|
|
token: this.token,
|
|
},
|
|
messageId,
|
|
threadId,
|
|
);
|
|
|
|
return message;
|
|
}
|
|
|
|
// end webhook methods
|
|
|
|
// deno-fmt-ignore
|
|
async respond(resp: InteractionResponse): Promise<Message | undefined>;
|
|
async respond(resp: InteractionResponseWith): Promise<Message | undefined>;
|
|
async respond(
|
|
resp: InteractionResponseWithData,
|
|
): 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;
|