feat: all reaction-related endpoints

This commit is contained in:
Yuzu 2022-07-01 14:10:25 -05:00
parent 486fcbe289
commit 050d5a3973
3 changed files with 129 additions and 2 deletions

View File

@ -1,7 +1,8 @@
import type { Model } from "./Base.ts";
import type { Snowflake } from "../util/Snowflake.ts";
import type { Session } from "../session/Session.ts";
import type { AllowedMentionsTypes, DiscordMessage, FileContent } from "../vendor/external.ts";
import type { AllowedMentionsTypes, DiscordMessage, DiscordUser, FileContent } from "../vendor/external.ts";
import type { GetReactions } from "../util/Routes.ts";
import { MessageFlags } from "../util/shared/flags.ts";
import User from "./User.ts";
import Member from "./Member.ts";
@ -42,6 +43,11 @@ export interface EditMessage extends Partial<CreateMessage> {
flags?: MessageFlags;
}
export type ReactionResolvable = string | {
name: string;
id: Snowflake;
};
/**
* Represents a message
* @link https://discord.com/developers/docs/resources/channel#message-object
@ -176,6 +182,74 @@ export class Message implements Model {
return new Message(this.session, message);
}
/**
* alias for Message.addReaction
* */
get react() {
return this.addReaction;
}
async addReaction(reaction: ReactionResolvable) {
const r = typeof reaction === "string" ? reaction : `${reaction.name}:${reaction.id}`;
await this.session.rest.runMethod<undefined>(
this.session.rest,
"PUT",
Routes.CHANNEL_MESSAGE_REACTION_ME(this.channelId, this.id, r),
{},
);
}
async removeReaction(reaction: ReactionResolvable, options?: { userId: Snowflake }) {
const r = typeof reaction === "string" ? reaction : `${reaction.name}:${reaction.id}`;
await this.session.rest.runMethod<undefined>(
this.session.rest,
"DELETE",
options?.userId
? Routes.CHANNEL_MESSAGE_REACTION_USER(
this.channelId,
this.id,
r,
options.userId,
)
: Routes.CHANNEL_MESSAGE_REACTION_ME(this.channelId, this.id, r)
);
}
/**
* Get users who reacted with this emoji
* */
async fetchReactions(reaction: ReactionResolvable, options?: GetReactions): Promise<User[]> {
const r = typeof reaction === "string" ? reaction : `${reaction.name}:${reaction.id}`;
const users = await this.session.rest.runMethod<DiscordUser[]>(
this.session.rest,
"GET",
Routes.CHANNEL_MESSAGE_REACTION(this.channelId, this.id, encodeURIComponent(r), options),
);
return users.map((user) => new User(this.session, user));
}
async removeReactionEmoji(reaction: ReactionResolvable) {
const r = typeof reaction === "string" ? reaction : `${reaction.name}:${reaction.id}`;
await this.session.rest.runMethod<undefined>(
this.session.rest,
"DELETE",
Routes.CHANNEL_MESSAGE_REACTION(this.channelId, this.id, r)
);
}
async nukeReactions() {
await this.session.rest.runMethod<undefined>(
this.session.rest,
"DELETE",
Routes.CHANNEL_MESSAGE_REACTIONS(this.channelId, this.id)
);
}
inGuild(): this is { guildId: Snowflake } & Message {
return !!this.guildId;
}

View File

@ -1,7 +1,8 @@
import type { Session } from "../session/Session.ts";
import type { Snowflake } from "../util/Snowflake.ts";
import type { GetMessagesOptions } from "../util/Routes.ts";
import type { GetMessagesOptions, GetReactions } from "../util/Routes.ts";
import type { DiscordChannel, DiscordInvite, DiscordMessage, TargetTypes } from "../vendor/external.ts";
import type { ReactionResolvable } from "./Message.ts";
import GuildChannel from "./GuildChannel.ts";
import Guild from "./Guild.ts";
import ThreadChannel from "./ThreadChannel.ts";
@ -115,6 +116,28 @@ export class TextChannel extends GuildChannel {
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 }, reaction);
}
async removeReaction(messageId: Snowflake, reaction: ReactionResolvable, options?: { userId: Snowflake }) {
await Message.prototype.removeReaction.call({ channelId: this.id, id: messageId }, reaction, options);
}
async removeReactionEmoji(messageId: Snowflake, reaction: ReactionResolvable) {
await Message.prototype.removeReactionEmoji.call({ channelId: this.id, id: messageId }, 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 }, reaction, options);
return users;
}
}
export default TextChannel;

View File

@ -177,3 +177,33 @@ export function CHANNEL_PIN(channelId: Snowflake, messageId: Snowflake) {
export function CHANNEL_PINS(channelId: Snowflake) {
return `/channels/${channelId}/pins`;
}
export function CHANNEL_MESSAGE_REACTION_ME(channelId: Snowflake, messageId: Snowflake, emoji: string) {
return `/channels/${channelId}/messages/${messageId}/reactions/${encodeURIComponent(emoji)}/@me`;
}
export function CHANNEL_MESSAGE_REACTION_USER(channelId: Snowflake, messageId: Snowflake, emoji: string, userId: Snowflake) {
return `/channels/${channelId}/messages/${messageId}/reactions/${encodeURIComponent(emoji)}/${userId}`;
}
export function CHANNEL_MESSAGE_REACTIONS(channelId: Snowflake, messageId: Snowflake) {
return `/channels/${channelId}/messages/${messageId}/reactions`;
}
/**
* @link https://discord.com/developers/docs/resources/channel#get-reactions-query-string-params
* */
export interface GetReactions {
after?: string;
limit?: number;
}
export function CHANNEL_MESSAGE_REACTION(channelId: Snowflake, messageId: Snowflake, emoji: string, options?: GetReactions) {
let url = `/channels/${channelId}/messages/${messageId}/reactions/${encodeURIComponent(emoji)}?`;
if (options?.after) url += `after=${options.after}`;
if (options?.limit) url += `&limit=${options.limit}`;
return url;
}