// deno-lint-ignore-file ban-types import type { Session } from "../session/Session.ts"; import type { Snowflake } from "../util/Snowflake.ts"; import type { GetMessagesOptions, GetReactions } from "../util/Routes.ts"; import type { DiscordChannel, DiscordInvite, DiscordMessage, DiscordWebhook, TargetTypes } from "../vendor/external.ts"; import type { CreateMessage, EditMessage, ReactionResolvable } from "./Message.ts"; import { ChannelTypes } from "../vendor/external.ts"; import { urlToBase64 } from "../util/urlToBase64.ts"; import Message from "./Message.ts"; import Invite from "./Invite.ts"; import Webhook from "./Webhook.ts"; import * as Routes from "../util/Routes.ts"; /** * Represents the options object to create an invitation * @link https://discord.com/developers/docs/resources/channel#create-channel-invite-json-params */ export interface DiscordInviteOptions { maxAge?: number; maxUses?: number; unique?: boolean; temporary: boolean; reason?: string; targetType?: TargetTypes; targetUserId?: Snowflake; targetApplicationId?: Snowflake; } export interface CreateWebhook { name: string; avatar?: string; reason?: string; } export const textBasedChannels = [ ChannelTypes.DM, ChannelTypes.GroupDm, ChannelTypes.GuildPrivateThread, ChannelTypes.GuildPublicThread, ChannelTypes.GuildNews, ChannelTypes.GuildText, ]; export type TextBasedChannels = | ChannelTypes.DM | ChannelTypes.GroupDm | ChannelTypes.GuildPrivateThread | ChannelTypes.GuildPublicThread | ChannelTypes.GuildNews | ChannelTypes.GuildText; export class TextChannel { constructor(session: Session, data: DiscordChannel) { this.session = session; this.id = data.id; this.name = data.name; this.type = data.type as number; this.rateLimitPerUser = data.rate_limit_per_user ?? 0; this.nsfw = !!data.nsfw ?? false; if (data.last_message_id) { this.lastMessageId = data.last_message_id; } if (data.last_pin_timestamp) { this.lastPinTimestamp = data.last_pin_timestamp; } } readonly session: Session; readonly id: Snowflake; name?: string; type: TextBasedChannels; lastMessageId?: Snowflake; lastPinTimestamp?: string; rateLimitPerUser: number; nsfw: boolean; /** * Mixin */ static applyTo(klass: Function) { klass.prototype.fetchPins = TextChannel.prototype.fetchPins; klass.prototype.createInvite = TextChannel.prototype.createInvite; klass.prototype.fetchMessages = TextChannel.prototype.fetchMessages; klass.prototype.sendTyping = TextChannel.prototype.sendTyping; klass.prototype.pinMessage = TextChannel.prototype.pinMessage; klass.prototype.unpinMessage = TextChannel.prototype.unpinMessage; klass.prototype.addReaction = TextChannel.prototype.addReaction; klass.prototype.removeReaction = TextChannel.prototype.removeReaction; klass.prototype.removeReactionEmoji = TextChannel.prototype.removeReactionEmoji; klass.prototype.nukeReactions = TextChannel.prototype.nukeReactions; klass.prototype.fetchReactions = TextChannel.prototype.fetchReactions; klass.prototype.sendMessage = TextChannel.prototype.sendMessage; klass.prototype.editMessage = TextChannel.prototype.editMessage; klass.prototype.createWebhook = TextChannel.prototype.createWebhook; } async fetchPins(): Promise { const messages = await this.session.rest.runMethod( this.session.rest, "GET", Routes.CHANNEL_PINS(this.id), ); return messages[0] ? messages.map((x: DiscordMessage) => new Message(this.session, x)) : []; } async createInvite(options?: DiscordInviteOptions) { const invite = await this.session.rest.runMethod( this.session.rest, "POST", Routes.CHANNEL_INVITES(this.id), options ? { max_age: options.maxAge, max_uses: options.maxUses, temporary: options.temporary, unique: options.unique, target_type: options.targetType, target_user_id: options.targetUserId, target_application_id: options.targetApplicationId, } : {}, ); return new Invite(this.session, invite); } async fetchMessages(options?: GetMessagesOptions): Promise { if (options?.limit! > 100) throw Error("Values must be between 0-100"); const messages = await this.session.rest.runMethod( this.session.rest, "GET", Routes.CHANNEL_MESSAGES(this.id, options), ); return messages[0] ? messages.map((x) => new Message(this.session, x)) : []; } async sendTyping() { await this.session.rest.runMethod( this.session.rest, "POST", Routes.CHANNEL_TYPING(this.id), ); } async pinMessage(messageId: Snowflake) { await Message.prototype.pin.call({ id: messageId, channelId: this.id, session: this.session }); } async unpinMessage(messageId: Snowflake) { await Message.prototype.unpin.call({ id: messageId, channelId: this.id, session: this.session }); } async addReaction(messageId: Snowflake, reaction: ReactionResolvable) { await Message.prototype.addReaction.call( { channelId: this.id, id: messageId, session: this.session }, reaction, ); } async removeReaction(messageId: Snowflake, reaction: ReactionResolvable, options?: { userId: Snowflake }) { await Message.prototype.removeReaction.call( { channelId: this.id, id: messageId, session: this.session }, reaction, options, ); } async removeReactionEmoji(messageId: Snowflake, reaction: ReactionResolvable) { await Message.prototype.removeReactionEmoji.call( { channelId: this.id, id: messageId, session: this.session }, reaction, ); } async nukeReactions(messageId: Snowflake) { await Message.prototype.nukeReactions.call({ channelId: this.id, id: messageId }); } async fetchReactions(messageId: Snowflake, reaction: ReactionResolvable, options?: GetReactions) { const users = await Message.prototype.fetchReactions.call( { channelId: this.id, id: messageId, session: this.session }, reaction, options, ); return users; } sendMessage(options: CreateMessage) { return Message.prototype.reply.call({ channelId: this.id, session: this.session }, options); } editMessage(messageId: Snowflake, options: EditMessage) { return Message.prototype.edit.call({ channelId: this.id, id: messageId, session: this.session }, options); } async createWebhook(options: CreateWebhook) { const webhook = await this.session.rest.runMethod( this.session.rest, "POST", Routes.CHANNEL_WEBHOOKS(this.id), { name: options.name, avatar: options.avatar ? urlToBase64(options.avatar) : undefined, reason: options.reason, }, ); return new Webhook(this.session, webhook); } } export default TextChannel;