mirror of
https://github.com/tiramisulabs/seyfert.git
synced 2025-07-05 06:26:08 +00:00
feat: interaction.Respond
This commit is contained in:
parent
8653e190ea
commit
60484dab40
@ -4,7 +4,7 @@ import type { Events } from "../handlers/Actions.ts";
|
||||
|
||||
import { Snowflake } from "../util/Snowflake.ts";
|
||||
import { EventEmitter } from "../util/EventEmmiter.ts";
|
||||
import { createGatewayManager, createRestManager } from "../vendor/external.ts";
|
||||
import { createGatewayManager, createRestManager, getBotIdFromToken } from "../vendor/external.ts";
|
||||
|
||||
import * as Routes from "../util/Routes.ts";
|
||||
import * as Actions from "../handlers/Actions.ts";
|
||||
@ -39,6 +39,18 @@ export class Session extends EventEmitter {
|
||||
rest: ReturnType<typeof createRestManager>;
|
||||
gateway: ReturnType<typeof createGatewayManager>;
|
||||
|
||||
unrepliedInteractions: Set<bigint> = new Set();
|
||||
|
||||
#botId: Snowflake;
|
||||
|
||||
set botId(id: Snowflake) {
|
||||
this.#botId = id;
|
||||
}
|
||||
|
||||
get botId() {
|
||||
return this.#botId;
|
||||
}
|
||||
|
||||
constructor(options: SessionOptions) {
|
||||
super();
|
||||
this.options = options;
|
||||
@ -71,7 +83,8 @@ export class Session extends EventEmitter {
|
||||
},
|
||||
handleDiscordPayload: this.options.rawHandler ?? defHandler,
|
||||
});
|
||||
// TODO: set botId in Session.botId or something
|
||||
|
||||
this.#botId = getBotIdFromToken(options.token).toString();
|
||||
}
|
||||
|
||||
override on<K extends keyof Events>(event: K, func: Events[K]): this;
|
||||
|
@ -62,7 +62,7 @@ export class Guild extends BaseGuild implements Model {
|
||||
this.vefificationLevel = data.verification_level;
|
||||
this.defaultMessageNotificationLevel = data.default_message_notifications;
|
||||
this.explicitContentFilterLevel = data.explicit_content_filter;
|
||||
this.members = data.members?.map((member) => new Member(session, { ...member, user: member.user! })) ?? [];
|
||||
this.members = data.members?.map((member) => new Member(session, { ...member, user: member.user! }, data.id)) ?? [];
|
||||
this.roles = data.roles.map((role) => new Role(session, role, data.id));
|
||||
this.emojis = data.emojis.map((guildEmoji) => new GuildEmoji(session, guildEmoji, data.id));
|
||||
}
|
||||
|
@ -1,9 +1,42 @@
|
||||
import type { Model } from "./Base.ts";
|
||||
import type { Snowflake } from "../util/Snowflake.ts";
|
||||
import type { Session } from "../session/Session.ts";
|
||||
import type { DiscordInteraction, InteractionTypes } from "../vendor/external.ts";
|
||||
import type {
|
||||
DiscordMessage,
|
||||
DiscordInteraction,
|
||||
InteractionTypes,
|
||||
InteractionResponseTypes,
|
||||
FileContent,
|
||||
} from "../vendor/external.ts";
|
||||
import type { MessageFlags } from "../util/shared/flags.ts";
|
||||
import type { AllowedMentions } from "./Message.ts";
|
||||
import User from "./User.ts";
|
||||
// import Member from "./Member.ts";
|
||||
import Message from "./Message.ts";
|
||||
import Member from "./Member.ts";
|
||||
import * as Routes from "../util/Routes.ts";
|
||||
|
||||
export interface InteractionResponse {
|
||||
type: InteractionResponseTypes;
|
||||
data?: InteractionApplicationCommandCallbackData;
|
||||
}
|
||||
|
||||
export interface InteractionApplicationCommandCallbackData {
|
||||
content?: string;
|
||||
tts?: boolean;
|
||||
allowedMentions?: AllowedMentions;
|
||||
files?: FileContent[];
|
||||
customId?: string;
|
||||
title?: string;
|
||||
// components?: Component[];
|
||||
flags?: MessageFlags;
|
||||
choices?: ApplicationCommandOptionChoice[];
|
||||
}
|
||||
|
||||
/** https://discord.com/developers/docs/interactions/slash-commands#applicationcommandoptionchoice */
|
||||
export interface ApplicationCommandOptionChoice {
|
||||
name: string;
|
||||
value: string | number;
|
||||
}
|
||||
|
||||
export class Interaction implements Model {
|
||||
constructor(session: Session, data: DiscordInteraction) {
|
||||
@ -21,8 +54,7 @@ export class Interaction implements Model {
|
||||
this.user = new User(session, data.user!);
|
||||
}
|
||||
else {
|
||||
// TODO: member transformer
|
||||
// pass
|
||||
this.member = new Member(session, data.member!, data.guild_id);
|
||||
}
|
||||
}
|
||||
|
||||
@ -38,9 +70,74 @@ export class Interaction implements Model {
|
||||
// deno-lint-ignore no-explicit-any
|
||||
data: any;
|
||||
user?: User;
|
||||
member?: Member;
|
||||
|
||||
// TODO: do methods
|
||||
async respond() {
|
||||
async respond({ type, data }: InteractionResponse) {
|
||||
const toSend = {
|
||||
tts: data?.tts,
|
||||
title: data?.title,
|
||||
flags: data?.flags,
|
||||
content: data?.content,
|
||||
choices: data?.choices,
|
||||
custom_id: data?.customId,
|
||||
allowed_mentions: data?.allowedMentions
|
||||
? {
|
||||
users: data.allowedMentions.users,
|
||||
roles: data.allowedMentions.roles,
|
||||
parse: data.allowedMentions.parse,
|
||||
replied_user: data.allowedMentions.repliedUser,
|
||||
}
|
||||
: { parse: [] },
|
||||
};
|
||||
|
||||
if (this.session.unrepliedInteractions.delete(BigInt(this.id))) {
|
||||
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: type,
|
||||
data: toSend,
|
||||
file: data?.files,
|
||||
},
|
||||
headers: {
|
||||
// remove authorization header
|
||||
Authorization: "",
|
||||
},
|
||||
}),
|
||||
}
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const result = await this.session.rest.sendRequest<DiscordMessage>(
|
||||
this.session.rest,
|
||||
{
|
||||
url: Routes.WEBHOOK(this.session.botId, this.token),
|
||||
method: "POST",
|
||||
payload: this.session.rest.createRequestBody(this.session.rest, {
|
||||
method: "POST",
|
||||
body: {
|
||||
...toSend,
|
||||
file: data?.files
|
||||
},
|
||||
headers: {
|
||||
// remove authorization header
|
||||
Authorization: "",
|
||||
},
|
||||
}),
|
||||
}
|
||||
);
|
||||
|
||||
return new Message(this.session, result);
|
||||
}
|
||||
|
||||
inGuild(): this is Interaction & { user: undefined, guildId: Snowflake, member: Member } {
|
||||
return "guildId" in this;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -63,12 +63,10 @@ export class Message implements Model {
|
||||
this.attachments = data.attachments.map((attachment) => new Attachment(session, attachment));
|
||||
|
||||
// user is always null on MessageCreate and its replaced with author
|
||||
this.member = data.member
|
||||
? new Member(session, {
|
||||
...data.member,
|
||||
user: data.author,
|
||||
})
|
||||
: undefined;
|
||||
|
||||
if (data.guild_id && data.member) {
|
||||
this.member = new Member(session, { ...data.member, user: data.author }, data.guild_id);
|
||||
}
|
||||
}
|
||||
|
||||
readonly session: Session;
|
||||
|
@ -139,3 +139,18 @@ export function INVITE(inviteCode: string, options?: GetInvite) {
|
||||
export function GUILD_INVITES(guildId: Snowflake) {
|
||||
return `/guilds/${guildId}/invites`;
|
||||
}
|
||||
|
||||
export function INTERACTION_ID_TOKEN(interactionId: Snowflake, token: string) {
|
||||
return `/interactions/${interactionId}/${token}/callback`;
|
||||
}
|
||||
|
||||
export function WEBHOOK(webhookId: Snowflake, token: string, options?: { wait?: boolean; threadId?: Snowflake }) {
|
||||
let url = `/webhooks/${webhookId}/${token}?`;
|
||||
|
||||
if (options) {
|
||||
if (options.wait !== undefined) url += `wait=${options.wait}`;
|
||||
if (options.threadId) url += `threadId=${options.threadId}`;
|
||||
}
|
||||
|
||||
return url;
|
||||
}
|
||||
|
1
vendor/external.ts
vendored
1
vendor/external.ts
vendored
@ -2,3 +2,4 @@ export * from "./gateway/mod.ts";
|
||||
export * from "./rest/mod.ts";
|
||||
export * from "./types/mod.ts";
|
||||
export * from "./util/constants.ts";
|
||||
export * from "./util/token.ts";
|
||||
|
Loading…
x
Reference in New Issue
Block a user