(evt: IncomingReaction)
| 572 | await h({ thread, user: evt.user }); |
| 573 | }, |
| 574 | async onReaction(evt: IncomingReaction) { |
| 575 | // Only normalize when the adapter's platform is one the emoji table |
| 576 | // knows; otherwise the raw token passes through unchanged. |
| 577 | const normalized = isEmojiPlatform(adapter.platform) |
| 578 | ? normalizeEmoji(evt.rawEmoji, adapter.platform) |
| 579 | : undefined; |
| 580 | const value: EmojiValue = normalized ?? evt.rawEmoji; |
| 581 | const thread = makeThread( |
| 582 | adapter, |
| 583 | evt.replyTarget, |
| 584 | evt.conversationKey, |
| 585 | ); |
| 586 | // Prefer the adapter's update-capable ref; fall back to the bare id. |
| 587 | const messageRef: MessageRef = evt.messageRef ?? { id: evt.messageId }; |
| 588 | const reactionEvt: ReactionEvent = { |
| 589 | emoji: value, |
| 590 | rawEmoji: evt.rawEmoji, |
| 591 | added: evt.added, |
| 592 | user: evt.user, |
| 593 | messageId: evt.messageId, |
| 594 | messageRef, |
| 595 | threadId: evt.threadId, |
| 596 | thread, |
| 597 | adapter, |
| 598 | raw: evt.raw, |
| 599 | }; |
| 600 | for (const reg of reactionHandlers) { |
| 601 | if (!reg.emojis || reg.emojis.has(value)) |
| 602 | await reg.handler(reactionEvt); |
| 603 | } |
| 604 | // Per-message handler set via `<Message onReaction>` on the posted |
| 605 | // message — hot cache, falling back to the durable snapshot after a restart. |
| 606 | const perMessage = await registry.resolveMessageReaction(evt.messageId); |
| 607 | if (perMessage) { |
| 608 | await perMessage(value, { |
| 609 | emoji: value, |
| 610 | rawEmoji: evt.rawEmoji, |
| 611 | added: evt.added, |
| 612 | user: evt.user, |
| 613 | messageId: evt.messageId, |
| 614 | thread, |
| 615 | messageRef, |
| 616 | }); |
| 617 | } |
| 618 | }, |
| 619 | async onModalSubmit(evt: IncomingModalSubmit) { |
| 620 | const handler = modalSubmitHandlers.get(evt.callbackId); |
| 621 | if (!handler) return; // unregistered → closes |
no test coverage detected
searching dependent graphs…