diff --git a/src/channels/telegram.test.ts b/src/channels/telegram.test.ts new file mode 100644 index 0000000..4f008e7 --- /dev/null +++ b/src/channels/telegram.test.ts @@ -0,0 +1,34 @@ +import { afterEach, describe, expect, it, vi } from 'vitest'; +import { TelegramAdapter } from './telegram.js'; + +describe('TelegramAdapter reactions', () => { + afterEach(() => { + vi.restoreAllMocks(); + }); + + it('strips variation selectors before sending unicode heart reactions', async () => { + const adapter = new TelegramAdapter({ token: 'test-token' }); + const setReaction = vi + .spyOn(adapter.getBot().api, 'setMessageReaction') + .mockImplementation(async () => true as any); + + await adapter.addReaction('123', '456', '❤️'); + + expect(setReaction).toHaveBeenCalledWith('123', 456, [ + { type: 'emoji', emoji: '❤' }, + ]); + }); + + it("normalizes the heart alias to Telegram's bare-heart reaction", async () => { + const adapter = new TelegramAdapter({ token: 'test-token' }); + const setReaction = vi + .spyOn(adapter.getBot().api, 'setMessageReaction') + .mockImplementation(async () => true as any); + + await adapter.addReaction('123', '456', 'heart'); + + expect(setReaction).toHaveBeenCalledWith('123', 456, [ + { type: 'emoji', emoji: '❤' }, + ]); + }); +}); diff --git a/src/channels/telegram.ts b/src/channels/telegram.ts index 16595f6..621cc8f 100644 --- a/src/channels/telegram.ts +++ b/src/channels/telegram.ts @@ -617,7 +617,7 @@ export class TelegramAdapter implements ChannelAdapter { } async addReaction(chatId: string, messageId: string, emoji: string): Promise { - const resolved = resolveEmoji(emoji); + const resolved = resolveTelegramEmoji(emoji); if (!TELEGRAM_REACTION_SET.has(resolved)) { throw new Error(`Unsupported Telegram reaction emoji: ${resolved}`); } @@ -810,6 +810,13 @@ function extractTelegramReaction(reaction?: { return null; } +function resolveTelegramEmoji(input: string): string { + const resolved = resolveEmoji(input); + // Strip variation selectors (U+FE0E / U+FE0F). Telegram's reaction API + // expects bare emoji without them (e.g. ❤ not ❤️). + return resolved.replace(/[\uFE0E\uFE0F]/g, ''); +} + const TELEGRAM_REACTION_EMOJIS = [ '👍', '👎', '❤', '🔥', '🥰', '👏', '😁', '🤔', '🤯', '😱', '🤬', '😢', '🎉', '🤩', '🤮', '💩', '🙏', '👌', '🕊', '🤡', '🥱', '🥴', '😍', '🐳',