From 7203eb01ebef666d205e0d75c67f750ee13698d0 Mon Sep 17 00:00:00 2001 From: Yuzu Date: Tue, 5 Jul 2022 20:26:21 -0500 Subject: [PATCH] wip: CommandInteraction.respond --- structures/Message.ts | 2 + structures/Webhook.ts | 62 ++++++++++++++++++- structures/interactions/CommandInteraction.ts | 48 +++++++++++++- util/Routes.ts | 23 +++++-- 4 files changed, 127 insertions(+), 8 deletions(-) diff --git a/structures/Message.ts b/structures/Message.ts index e193d73..52be7c5 100644 --- a/structures/Message.ts +++ b/structures/Message.ts @@ -48,6 +48,7 @@ export interface CreateMessage { allowedMentions?: AllowedMentions; files?: FileContent[]; messageReference?: CreateMessageReference; + tts?: boolean; } /** @@ -271,6 +272,7 @@ export class Message implements Model { } : undefined, embeds: options.embeds, + tts: options.tts, }, ); diff --git a/structures/Webhook.ts b/structures/Webhook.ts index 6a85a22..c17a7ff 100644 --- a/structures/Webhook.ts +++ b/structures/Webhook.ts @@ -1,9 +1,13 @@ import type { Model } from "./Base.ts"; import type { Session } from "../session/Session.ts"; import type { Snowflake } from "../util/Snowflake.ts"; -import type { DiscordWebhook, WebhookTypes } from "../vendor/external.ts"; +import type { DiscordMessage, DiscordWebhook, WebhookTypes } from "../vendor/external.ts"; +import type { WebhookOptions } from "../util/Routes.ts"; +import type { CreateMessage } from "./Message.ts"; import { iconHashToBigInt } from "../util/hash.ts"; import User from "./User.ts"; +import Message from "./Message.ts"; +import * as Routes from "../util/Routes.ts"; export class Webhook implements Model { constructor(session: Session, data: DiscordWebhook) { @@ -42,6 +46,62 @@ export class Webhook implements Model { channelId?: Snowflake; guildId?: Snowflake; user?: User; + + async execute(options?: WebhookOptions & CreateMessage & { avatarUrl?: string, username?: string }) { + if (!this.token) { + return; + } + + const data = { + content: options?.content, + embeds: options?.embeds, + tts: options?.tts, + allowed_mentions: options?.allowedMentions, + // @ts-ignore: TODO: component builder or something + components: options?.components, + file: options?.files, + }; + + const message = await this.session.rest.sendRequest(this.session.rest, { + url: Routes.WEBHOOK(this.id, this.token!, { + wait: options?.wait, + threadId: options?.threadId, + }), + method: "POST", + payload: this.session.rest.createRequestBody(this.session.rest, { + method: "POST", + body: { + ...data, + }, + }), + }); + + return (options?.wait ?? true) ? new Message(this.session, message) : undefined; + } + + async fetch() { + const message = await this.session.rest.runMethod( + this.session.rest, + "GET", + Routes.WEBHOOK_TOKEN(this.id, this.token), + ); + + return new Webhook(this.session, message); + } + + async fetchMessage(messageId: Snowflake) { + if (!this.token) { + return; + } + + const message = await this.session.rest.runMethod( + this.session.rest, + "GET", + Routes.WEBHOOK_MESSAGE(this.id, this.token, messageId), + ); + + return new Message(this.session, message); + } } export default Webhook; diff --git a/structures/interactions/CommandInteraction.ts b/structures/interactions/CommandInteraction.ts index ef1294a..0d25e91 100644 --- a/structures/interactions/CommandInteraction.ts +++ b/structures/interactions/CommandInteraction.ts @@ -3,6 +3,7 @@ import type { Snowflake } from "../../util/Snowflake.ts"; import type { Session } from "../../session/Session.ts"; import type { ApplicationCommandTypes, DiscordMemberWithUser, DiscordInteraction, InteractionTypes } from "../../vendor/external.ts"; import type { CreateMessage } from "../Message.ts"; +import type { MessageFlags } from "../../util/shared/flags.ts"; import { InteractionResponseTypes } from "../../vendor/external.ts"; import BaseInteraction from "./BaseInteraction.ts"; import CommandInteractionOptionResolver from "./CommandInteractionOptionResolver.ts"; @@ -11,6 +12,8 @@ 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 "../../util/Routes.ts"; /** * @link https://discord.com/developers/docs/interactions/slash-commands#interaction-response @@ -23,12 +26,11 @@ export interface InteractionResponse { /** * @link https://discord.com/developers/docs/interactions/slash-commands#interaction-response-interactionapplicationcommandcallbackdata * */ -export interface InteractionApplicationCommandCallbackData extends Omit { +export interface InteractionApplicationCommandCallbackData extends Pick { customId?: string; title?: string; - // TODO: use builder // components?: MessageComponents; - flags?: number; + flags?: MessageFlags; choices?: ApplicationCommandOptionChoice[]; } @@ -103,6 +105,46 @@ export class CommandInteraction extends BaseInteraction implements Model { }; options: CommandInteractionOptionResolver; responded = false; + + async sendFollowUp(options: InteractionApplicationCommandCallbackData): Promise { + 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 { + 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.respond) { + await this.session.rest.sendRequest(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; diff --git a/util/Routes.ts b/util/Routes.ts index 146f944..51e74e4 100644 --- a/util/Routes.ts +++ b/util/Routes.ts @@ -144,11 +144,26 @@ 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}?`; +export function WEBHOOK_MESSAGE(webhookId: Snowflake, token: string, messageId: Snowflake) { + return `/webhooks/${webhookId}/${token}/messages/${messageId}`; +} - if (options?.wait !== undefined) url += `wait=${options.wait}`; - if (options?.threadId) url += `threadId=${options.threadId}`; +export function WEBHOOK_TOKEN(webhookId: Snowflake, token?: string) { + if (!token) return `/webhooks/${webhookId}`; + return `/webhooks/${webhookId}/${token}`; +} + +export interface WebhookOptions { + wait?: boolean; + threadId?: Snowflake; +} + +export function WEBHOOK(webhookId: Snowflake, token: string, options?: WebhookOptions) { + let url = `/webhooks/${webhookId}/${token}`; + + if (options?.wait) url += `?wait=${options.wait}`; + if (options?.threadId) url += `?threadId=${options.threadId}`; + if (options?.wait && options.threadId) url += `?wait=${options.wait}&threadId=${options.threadId}`; return url; }