import { fetchDiscord } from "./core"; /** * Represents a message sent in a channel within Discord. * This is a partial interface based on the Discord API documentation. */ export interface Message { id: string; channel_id: string; author: any; // User object content: string; timestamp: string; // ISO8601 timestamp edited_timestamp: string | null; // ISO8601 timestamp tts: boolean; mention_everyone: boolean; mentions: any[]; // array of user objects mention_roles: string[]; // array of role object ids mention_channels?: any[]; // array of channel mention objects attachments: any[]; // array of attachment objects embeds: any[]; // array of embed objects reactions?: any[]; // array of reaction objects nonce?: number | string; pinned: boolean; webhook_id?: string; type: number; activity?: any; // message activity object application?: any; // partial application object application_id?: string; flags?: number; message_reference?: any; // message reference object referenced_message?: Message | null; interaction?: any; // message interaction object thread?: any; // channel object components?: any[]; // array of message components sticker_items?: any[]; // array of message sticker item objects stickers?: any[]; // array of sticker objects position?: number; role_subscription_data?: any; // role subscription data object resolved?: any; } /** * Retrieves the messages in a channel. * @param channelId The ID of the channel. * @param options Options for fetching messages. * @returns An array of message objects. */ export const getChannelMessages = async ( channelId: string, options?: { around?: string; before?: string; after?: string; limit?: number; }, ): Promise => { const query = new URLSearchParams(); if (options?.around) query.append("around", options.around); if (options?.before) query.append("before", options.before); if (options?.after) query.append("after", options.after); if (options?.limit) query.append("limit", String(options.limit)); const queryString = query.toString(); const path = `/channels/${channelId}/messages${queryString ? `?${queryString}` : ""}`; const res = await fetchDiscord(path); return res.json(); }; /** * Retrieves a specific message in the channel. * @param channelId The ID of the channel. * @param messageId The ID of the message. * @returns A message object. */ export const getChannelMessage = async ( channelId: string, messageId: string, ): Promise => { const path = `/channels/${channelId}/messages/${messageId}`; const res = await fetchDiscord(path); return res.json(); }; export interface CreateMessageParams { content?: string; tts?: boolean; embeds?: any[]; allowed_mentions?: any; message_reference?: any; components?: any[]; sticker_ids?: string[]; files?: any[]; payload_json?: string; attachments?: any[]; flags?: number; } /** * Post a message to a guild text or DM channel. * @param channelId The ID of the channel. * @param data The message data. * @returns The created message object. */ export const createMessage = async ( channelId: string, data: CreateMessageParams, ): Promise => { const path = `/channels/${channelId}/messages`; const res = await fetchDiscord(path, { method: "POST", body: JSON.stringify(data), }); return res.json(); }; export interface EditMessageParams { content?: string; embeds?: any[]; flags?: number; allowed_mentions?: any; components?: any[]; files?: any[]; payload_json?: string; attachments?: any[]; } /** * Edit a previously sent message. * @param channelId The ID of the channel. * @param messageId The ID of the message to edit. * @param data The new message data. * @returns The updated message object. */ export const editMessage = async ( channelId: string, messageId: string, data: EditMessageParams, ): Promise => { const path = `/channels/${channelId}/messages/${messageId}`; const res = await fetchDiscord(path, { method: "PATCH", body: JSON.stringify(data), }); return res.json(); }; /** * Delete a message. * @param channelId The ID of the channel. * @param messageId The ID of the message to delete. */ export const deleteMessage = async ( channelId: string, messageId: string, ): Promise => { const path = `/channels/${channelId}/messages/${messageId}`; await fetchDiscord(path, { method: "DELETE", }); }; /** * Delete multiple messages in a single request. * @param channelId The ID of the channel. * @param messageIds An array of message IDs to delete. */ export const bulkDeleteMessages = async ( channelId: string, messageIds: string[], ): Promise => { const path = `/channels/${channelId}/messages/bulk-delete`; await fetchDiscord(path, { method: "POST", body: JSON.stringify({ messages: messageIds }), }); }; /** * Create a reaction for the message. * @param channelId The ID of the channel. * @param messageId The ID of the message. * @param emoji The emoji to react with. */ export const addReaction = async ( channelId: string, messageId: string, emoji: string, ): Promise => { const path = `/channels/${channelId}/messages/${messageId}/reactions/${encodeURIComponent( emoji, )}/@me`; await fetchDiscord(path, { method: "PUT" }); }; /** * Get a list of users that reacted with this emoji. * @param channelId The ID of the channel. * @param messageId The ID of the message. * @param emoji The emoji. * @param options Options for fetching reactions. * @returns A list of user objects. */ export const getReactions = async ( channelId: string, messageId: string, emoji: string, options?: { after?: string; limit?: number }, ): Promise => { const query = new URLSearchParams(); if (options?.after) query.append("after", options.after); if (options?.limit) query.append("limit", String(options.limit ?? 100)); const queryString = query.toString(); const path = `/channels/${channelId}/messages/${messageId}/reactions/${encodeURIComponent( emoji, )}${queryString ? `?${queryString}` : ""}`; const res = await fetchDiscord(path); return res.json(); }; export const listReactionUsersMulti = async ( channelId: string, messageId: string, emojis: string[], ) => { const results = await Promise.all( emojis.map((e) => getReactions(channelId, messageId, e)), ); const byId = new Map(); for (const arr of results) { for (const u of arr) byId.set(u.id, u); // de-dupe across variants } return Array.from(byId.values()); };