(evt: InteractionEvent)
| 449 | } |
| 450 | }, |
| 451 | async onInteraction(evt: InteractionEvent) { |
| 452 | // Dedup guard: drop duplicate deliveries of the same event within the TTL window. |
| 453 | if (evt.eventId) { |
| 454 | const dupKey = `evt:${adapter.platform}:${evt.eventId}`; |
| 455 | try { |
| 456 | if (await backend.dedup.seen(dupKey, cfg.dedupTtl ?? 300_000)) |
| 457 | return; |
| 458 | } catch (err) { |
| 459 | console.warn( |
| 460 | `[bot] dedup check failed for ${adapter.platform}; processing without dedup`, |
| 461 | err, |
| 462 | ); |
| 463 | } |
| 464 | } |
| 465 | |
| 466 | const thread = makeThread( |
| 467 | adapter, |
| 468 | evt.replyTarget, |
| 469 | evt.conversationKey, |
| 470 | ); |
| 471 | const user = evt.user ?? { id: "" }; |
| 472 | const ctx: InteractionContext = { |
| 473 | thread, |
| 474 | message: { |
| 475 | text: "", |
| 476 | user, |
| 477 | ref: evt.messageRef ?? { id: "" }, |
| 478 | platform: adapter.platform, |
| 479 | }, |
| 480 | action: { id: evt.id, value: evt.value }, |
| 481 | values: {}, |
| 482 | user, |
| 483 | platform: adapter.platform, |
| 484 | }; |
| 485 | const openModal = makeOpenModal( |
| 486 | adapter, |
| 487 | evt.replyTarget, |
| 488 | evt.triggerId, |
| 489 | ); |
| 490 | if (openModal) ctx.openModal = openModal; |
| 491 | // The clicked element's `value`, recovered by the registry when it |
| 492 | // re-renders to find the handler. Used to resolve a HITL waiter on |
| 493 | // platforms whose callback payload can't carry the value (Telegram), |
| 494 | // where `evt.value` is undefined. |
| 495 | let dispatchedValue: unknown; |
| 496 | try { |
| 497 | const explicit = interactionHandlers.get(evt.id); |
| 498 | if (explicit) { |
| 499 | await explicit(ctx); |
| 500 | } else { |
| 501 | dispatchedValue = await registry.dispatch(evt.id, ctx); |
| 502 | } |
| 503 | } catch (err) { |
| 504 | // v1: swallow expired-action dispatches; surface anything else. |
| 505 | if (!(err instanceof ActionExpiredError)) throw err; |
| 506 | } |
| 507 | // Resolve any HITL waiter awaiting a choice in this conversation. Prefer |
| 508 | // the value carried in the event (Slack), falling back to the value the |
no test coverage detected
searching dependent graphs…