Skip to content

Built for people who want to own their automations. Join the waitlist for an invite.

Package listing

@kody/discord

src/add-reaction.ts

36 lines · 1.5 KB · TypeScript
import { discordBotRequest } from './bot.ts'
import { inputRecord, pickString, requireLiveMutation, snowflake } from './validation.ts'

function reactionEmoji(input: Record<string, unknown>): string {
	const explicit = pickString(input.emoji, input.reaction)
	if (explicit) return explicit
	const name = pickString(input.emojiName, input.emoji_name, input.name)
	const id = pickString(input.emojiId, input.emoji_id, input.id)
	if (name && id) return name + ':' + id
	if (name) return name
	throw new Error('emoji or emojiName is required.')
}

/**
 * Add one bot reaction to a Discord message.
 *
 * Discord rate-limits this endpoint aggressively. Add multiple reactions
 * sequentially and retry HTTP 429 after `retry_after`. Pass `dryRun: true` to
 * preview, or `confirm: true` to send.
 *
 * @param params.secretName - Bot-token secret; default `discordBotToken`.
 */
export default async function addReaction(params: Record<string, unknown> = {}) {
	const input = inputRecord(params)
	const channelId = snowflake(input, 'channelId', ['channel_id'])
	const messageId = snowflake(input, 'messageId', ['message_id'])
	const emoji = reactionEmoji(input)
	const path = '/channels/' + channelId + '/messages/' + messageId + '/reactions/' + encodeURIComponent(emoji) + '/@me'

	if (requireLiveMutation(input, 'add-reaction') === 'dryRun') {
		return { dryRun: true, channelId, messageId, emoji, path }
	}

	await discordBotRequest(path, input, { method: 'PUT' })
	return { ok: true, channelId, messageId, emoji }
}