seyfert
Version:
The most advanced framework for discord bots
508 lines (507 loc) • 20 kB
JavaScript
;
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ModalSubmitInteraction = exports.MessageCommandInteraction = exports.UserCommandInteraction = exports.ChatInputCommandInteraction = exports.UserSelectMenuInteraction = exports.RoleSelectMenuInteraction = exports.MentionableSelectMenuInteraction = exports.ChannelSelectMenuInteraction = exports.StringSelectMenuInteraction = exports.SelectMenuInteraction = exports.ButtonInteraction = exports.ComponentInteraction = exports.EntryPointInteraction = exports.ApplicationCommandInteraction = exports.Interaction = exports.AutocompleteInteraction = exports.BaseInteraction = void 0;
const types_1 = require("../types");
const builders_1 = require("../builders");
const transformers_1 = require("../client/transformers");
const common_1 = require("../common");
const mixer_1 = require("../deps/mixer");
const _1 = require("./");
const DiscordBase_1 = require("./extra/DiscordBase");
const Permissions_1 = require("./extra/Permissions");
class BaseInteraction extends DiscordBase_1.DiscordBase {
client;
__reply;
user;
member;
channel;
message;
replied;
appPermissions;
entitlements;
constructor(client, interaction, __reply) {
super(client, interaction);
this.client = client;
this.__reply = __reply;
if (interaction.member) {
this.member = transformers_1.Transformers.InteractionGuildMember(client, interaction.member, interaction.member.user, interaction.guild_id);
}
if (interaction.message) {
this.message = transformers_1.Transformers.Message(client, interaction.message);
}
this.appPermissions = new Permissions_1.PermissionsBitField(Number(interaction.app_permissions));
if ('channel' in interaction) {
this.channel = (0, _1.channelFrom)(interaction.channel, client);
}
this.user = this.member?.user ?? transformers_1.Transformers.User(client, interaction.user);
this.entitlements = interaction.entitlements.map(e => transformers_1.Transformers.Entitlement(this.client, e));
}
static transformBodyRequest(body, files, self) {
switch (body.type) {
case types_1.InteractionResponseType.ApplicationCommandAutocompleteResult:
case types_1.InteractionResponseType.DeferredMessageUpdate:
case types_1.InteractionResponseType.DeferredChannelMessageWithSource:
return body;
case types_1.InteractionResponseType.ChannelMessageWithSource:
case types_1.InteractionResponseType.UpdateMessage: {
//@ts-ignore
return {
type: body.type,
data: BaseInteraction.transformBody(body.data ?? {}, files, self),
};
}
case types_1.InteractionResponseType.Modal:
return {
type: body.type,
data: body.data instanceof builders_1.Modal
? body.data.toJSON()
: {
...body.data,
components: body.data?.components
? body.data.components.map(x => x instanceof builders_1.ActionRow
? x.toJSON()
: x)
: [],
},
};
case types_1.InteractionResponseType.LaunchActivity:
return body;
default:
return body;
}
}
static transformBody(body, files, self) {
const poll = body.poll;
const payload = {
allowed_mentions: self.options?.allowedMentions,
...body,
components: body.components?.map(x => (x instanceof builders_1.ActionRow ? x.toJSON() : x)),
embeds: body?.embeds?.map(x => (x instanceof builders_1.Embed ? x.toJSON() : x)),
poll: poll ? (poll instanceof builders_1.PollBuilder ? poll.toJSON() : poll) : undefined,
};
if ('attachments' in body) {
payload.attachments =
body.attachments?.map((x, i) => ({
id: i,
...(0, builders_1.resolveAttachment)(x),
})) ?? undefined;
}
else if (files?.length) {
payload.attachments = files?.map(({ filename }, id) => ({
id,
filename,
}));
}
return payload;
}
async matchReplied(body, withResponse = false) {
if (this.__reply) {
//@ts-expect-error
const { files, ...rest } = body.data ?? {};
//@ts-expect-error
const data = body.data instanceof builders_1.Modal ? body.data : rest;
const parsedFiles = files ? await (0, builders_1.resolveFiles)(files) : undefined;
await (this.replied = this.__reply({
body: BaseInteraction.transformBodyRequest({ data, type: body.type }, parsedFiles, this.client),
files: parsedFiles,
}).then(() => (this.replied = true)));
return;
}
const result = await (this.replied = this.client.interactions.reply(this.id, this.token, body, withResponse));
this.replied = true;
return result?.resource?.message
? transformers_1.Transformers.WebhookMessage(this.client, result.resource.message, this.id, this.token)
: undefined;
}
async reply(body, withResponse) {
if (this.replied) {
throw new Error('Interaction already replied');
}
const result = await this.matchReplied(body, withResponse);
// @ts-expect-error
if (body.data instanceof builders_1.Modal) {
// @ts-expect-error
if (body.data.__exec)
this.client.components.modals.set(this.user.id, body.data.__exec);
else if (this.client.components.modals.has(this.user.id))
this.client.components.modals.delete(this.user.id);
}
return result;
}
deferReply(flags, withResponse) {
return this.reply({
type: types_1.InteractionResponseType.DeferredChannelMessageWithSource,
data: {
flags,
},
}, withResponse);
}
isButton() {
return false;
}
isChannelSelectMenu() {
return false;
}
isRoleSelectMenu() {
return false;
}
isMentionableSelectMenu() {
return false;
}
isUserSelectMenu() {
return false;
}
isStringSelectMenu() {
return false;
}
isChatInput() {
return false;
}
isUser() {
return false;
}
isMessage() {
return false;
}
isAutocomplete() {
return false;
}
isModal() {
return false;
}
isEntryPoint() {
return false;
}
static from(client, gateway, __reply) {
switch (gateway.type) {
case types_1.InteractionType.ApplicationCommandAutocomplete:
return new AutocompleteInteraction(client, gateway, undefined, __reply);
// biome-ignore lint/suspicious/noFallthroughSwitchClause: bad interaction between biome and ts-server
case types_1.InteractionType.ApplicationCommand:
switch (gateway.data.type) {
case types_1.ApplicationCommandType.ChatInput:
return new ChatInputCommandInteraction(client, gateway, __reply);
case types_1.ApplicationCommandType.User:
return new UserCommandInteraction(client, gateway, __reply);
case types_1.ApplicationCommandType.Message:
return new MessageCommandInteraction(client, gateway, __reply);
case types_1.ApplicationCommandType.PrimaryEntryPoint:
return new EntryPointInteraction(client, gateway, __reply);
}
// biome-ignore lint/suspicious/noFallthroughSwitchClause: bad interaction between biome and ts-server
case types_1.InteractionType.MessageComponent:
switch (gateway.data.component_type) {
case types_1.ComponentType.Button:
return new ButtonInteraction(client, gateway, __reply);
case types_1.ComponentType.ChannelSelect:
return new ChannelSelectMenuInteraction(client, gateway, __reply);
case types_1.ComponentType.RoleSelect:
return new RoleSelectMenuInteraction(client, gateway, __reply);
case types_1.ComponentType.MentionableSelect:
return new MentionableSelectMenuInteraction(client, gateway, __reply);
case types_1.ComponentType.UserSelect:
return new UserSelectMenuInteraction(client, gateway, __reply);
case types_1.ComponentType.StringSelect:
return new StringSelectMenuInteraction(client, gateway, __reply);
}
case types_1.InteractionType.ModalSubmit:
return new ModalSubmitInteraction(client, gateway);
default:
return new BaseInteraction(client, gateway);
}
}
async fetchGuild(force = false) {
return this.guildId ? this.client.guilds.fetch(this.guildId, force) : undefined;
}
}
exports.BaseInteraction = BaseInteraction;
class AutocompleteInteraction extends BaseInteraction {
__reply;
options;
constructor(client, interaction, resolver, __reply) {
super(client, interaction);
this.__reply = __reply;
this.options =
resolver ??
transformers_1.Transformers.OptionResolver(client, interaction.data.options, undefined, interaction.guild_id, interaction.data.resolved);
}
getInput() {
return this.options.getAutocompleteValue() ?? '';
}
respond(choices) {
return super.reply({ data: { choices }, type: types_1.InteractionResponseType.ApplicationCommandAutocompleteResult });
}
isAutocomplete() {
return true;
}
/** @intenal */
async reply(..._args) {
throw new Error('Cannot use reply in this interaction');
}
}
exports.AutocompleteInteraction = AutocompleteInteraction;
class Interaction extends BaseInteraction {
fetchMessage(messageId) {
return this.client.interactions.fetchResponse(this.token, messageId);
}
fetchResponse() {
return this.fetchMessage('@original');
}
write(body, withResponse) {
return this.reply({
type: types_1.InteractionResponseType.ChannelMessageWithSource,
data: body,
}, withResponse);
}
modal(body) {
return this.reply({
type: types_1.InteractionResponseType.Modal,
data: body,
});
}
async editOrReply(body, fetchReply) {
if (await this.replied) {
const { content, embeds, allowed_mentions, components, files, attachments, poll } = body;
return this.editResponse({ content, embeds, allowed_mentions, components, files, attachments, poll });
}
return this.write(body, fetchReply);
}
editMessage(messageId, body) {
return this.client.interactions.editMessage(this.token, messageId, body);
}
editResponse(body) {
return this.editMessage('@original', body);
}
deleteResponse() {
return this.deleteMessage('@original');
}
deleteMessage(messageId) {
return this.client.interactions.deleteResponse(this.token, messageId);
}
followup(body) {
return this.client.interactions.followup(this.token, body);
}
}
exports.Interaction = Interaction;
class ApplicationCommandInteraction extends Interaction {
type;
respond(data) {
return this.reply(data);
}
}
exports.ApplicationCommandInteraction = ApplicationCommandInteraction;
/**
* Seyfert don't support activities, so this interaction is blank
*/
class EntryPointInteraction extends ApplicationCommandInteraction {
async withReponse(data) {
let body = { type: types_1.InteractionResponseType.LaunchActivity };
if (data) {
let { files, ...rest } = data;
files = files ? await (0, builders_1.resolveFiles)(files) : undefined;
body = BaseInteraction.transformBody(rest, files, this.client);
}
const response = await this.client.proxy
.interactions(this.id)(this.token)
.callback.post({
body,
query: { with_response: true },
});
const result = {
interaction: (0, common_1.toCamelCase)(response.interaction),
};
if (response.resource) {
if (response.resource.type !== types_1.InteractionResponseType.LaunchActivity) {
result.resource = {
type: response.resource.type,
message: transformers_1.Transformers.WebhookMessage(this.client, response.resource.message, this.id, this.token),
};
}
else {
result.resource = {
type: response.resource.type,
activityInstance: response.resource.activity_instance,
};
}
}
return result;
}
isEntryPoint() {
return true;
}
}
exports.EntryPointInteraction = EntryPointInteraction;
class ComponentInteraction extends Interaction {
update(data) {
return this.reply({
type: types_1.InteractionResponseType.UpdateMessage,
data,
});
}
deferUpdate() {
return this.reply({
type: types_1.InteractionResponseType.DeferredMessageUpdate,
});
}
get customId() {
return this.data.customId;
}
get componentType() {
return this.data.componentType;
}
}
exports.ComponentInteraction = ComponentInteraction;
class ButtonInteraction extends ComponentInteraction {
isButton() {
return true;
}
}
exports.ButtonInteraction = ButtonInteraction;
class SelectMenuInteraction extends ComponentInteraction {
__reply;
constructor(client, interaction, __reply) {
super(client, interaction);
this.__reply = __reply;
}
get values() {
return this.data.values;
}
}
exports.SelectMenuInteraction = SelectMenuInteraction;
class StringSelectMenuInteraction extends SelectMenuInteraction {
isStringSelectMenu() {
return true;
}
}
exports.StringSelectMenuInteraction = StringSelectMenuInteraction;
class ChannelSelectMenuInteraction extends SelectMenuInteraction {
__reply;
channels;
constructor(client, interaction, __reply) {
super(client, interaction);
this.__reply = __reply;
const resolved = interaction.data.resolved;
this.channels = this.values.map(x => (0, _1.channelFrom)(resolved.channels[x], this.client));
}
isChannelSelectMenu() {
return true;
}
}
exports.ChannelSelectMenuInteraction = ChannelSelectMenuInteraction;
class MentionableSelectMenuInteraction extends SelectMenuInteraction {
__reply;
roles;
members;
users;
constructor(client, interaction, __reply) {
super(client, interaction);
this.__reply = __reply;
const resolved = interaction.data.resolved;
this.roles = resolved.roles
? this.values.map(x => transformers_1.Transformers.GuildRole(this.client, resolved.roles[x], this.guildId))
: [];
this.members = resolved.members
? this.values.map(x => transformers_1.Transformers.InteractionGuildMember(this.client, resolved.members[x], resolved.users[this.values.find(u => u === x)], this.guildId))
: [];
this.users = resolved.users ? this.values.map(x => transformers_1.Transformers.User(this.client, resolved.users[x])) : [];
}
isMentionableSelectMenu() {
return true;
}
}
exports.MentionableSelectMenuInteraction = MentionableSelectMenuInteraction;
class RoleSelectMenuInteraction extends SelectMenuInteraction {
__reply;
roles;
constructor(client, interaction, __reply) {
super(client, interaction);
this.__reply = __reply;
const resolved = interaction.data.resolved;
this.roles = this.values.map(x => transformers_1.Transformers.GuildRole(this.client, resolved.roles[x], this.guildId));
}
isRoleSelectMenu() {
return true;
}
}
exports.RoleSelectMenuInteraction = RoleSelectMenuInteraction;
class UserSelectMenuInteraction extends SelectMenuInteraction {
__reply;
members;
users;
constructor(client, interaction, __reply) {
super(client, interaction);
this.__reply = __reply;
const resolved = interaction.data.resolved;
this.users = this.values.map(x => transformers_1.Transformers.User(this.client, resolved.users[x]));
this.members = resolved.members
? this.values.map(x => transformers_1.Transformers.InteractionGuildMember(this.client, resolved.members[x], resolved.users[this.values.find(u => u === x)], this.guildId))
: [];
}
isUserSelectMenu() {
return true;
}
}
exports.UserSelectMenuInteraction = UserSelectMenuInteraction;
class ChatInputCommandInteraction extends ApplicationCommandInteraction {
isChatInput() {
return true;
}
}
exports.ChatInputCommandInteraction = ChatInputCommandInteraction;
class UserCommandInteraction extends ApplicationCommandInteraction {
isUser() {
return true;
}
}
exports.UserCommandInteraction = UserCommandInteraction;
class MessageCommandInteraction extends ApplicationCommandInteraction {
isMessage() {
return true;
}
}
exports.MessageCommandInteraction = MessageCommandInteraction;
let ModalSubmitInteraction = class ModalSubmitInteraction extends BaseInteraction {
update(data, withResponse) {
return this.reply({
type: types_1.InteractionResponseType.UpdateMessage,
data,
}, withResponse);
}
deferUpdate(withResponse) {
return this.reply({
type: types_1.InteractionResponseType.DeferredMessageUpdate,
}, withResponse);
}
get customId() {
return this.data.customId;
}
get components() {
return this.data.components;
}
getInputValue(customId, required) {
let value;
for (const { components } of this.components) {
const get = components.find(x => x.customId === customId);
if (get) {
value = get.value;
break;
}
}
if (!value && required)
throw new Error(`${customId} component doesn't have a value`);
return value;
}
isModal() {
return true;
}
};
exports.ModalSubmitInteraction = ModalSubmitInteraction;
exports.ModalSubmitInteraction = ModalSubmitInteraction = __decorate([
(0, mixer_1.mix)(Interaction)
], ModalSubmitInteraction);