Commit 674c90f
feat(comment-automation): harden reply delivery and gate media steps per channel (#1121)
Two threads over the same surface: comment replies that silently never
reached the customer, and media steps that a channel cannot deliver.
Reply delivery (worker + sdk + channels):
- Write the dedup row when *any* branch dispatched, not only when both did.
A public reply that went out while the private one threw used to leave no
row, so the contact's next comment posted the public reply a second time.
- Roll the dedup row back when an AI reply job bails out (agent missing, no
text, workspace outside active hours). It used to count as "replied", and
`replyOncePerUserPerPost` then blocked that contact on that post forever.
A thrown failure still keeps the row โ BullMQ retries it.
- Skip a private reply once another automation on the same comment has spent
it: Meta allows exactly one comment_id-anchored DM per comment, so the
second call could only fail. Public replies of that automation still run.
- Skip a private reply for a comment older than Meta's 7-day window, delay
included, instead of letting the Send API reject it.
- Keep a claimed private anchor travelling as `spent: true` rather than
dropping it, so each channel's `sendFlowStep` can tell a comment-triggered
follow-up from a plain flow message. Message two onward now sends as a
normal DM inside the contact's 24-hour window and otherwise throws
`comment_private_reply_already_used`, which lands on the message row as a
`sendError` the inbox shows. Before, Meta rejected it and the error was
swallowed, so a two-message flow looked half-delivered with no reason.
- Log when the incoming comment's message row is missing: like, hide and
parent threading were being skipped with no trace.
Media steps (flow-config + builder + Instagram):
- `media-step-rules` / `media-step-validators` describe which media a channel
accepts, surfaced in the builder as a notice on the send-* step editors.
- Instagram comment replies are text-only (`POST /{ig-comment-id}/replies`
has no `attachment_url`), so both variants' `sendComment` now throw
`PAYLOAD_INVALID` instead of returning an empty result behind a warn.
- Instagram-via-Facebook collects a step's messages before sending so quick
replies land on the last one, and upload failures propagate to the inbox.
Co-authored-by: Deathgiver <anonymous@users.noreply.github.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>1 parent 73b8234 commit 674c90f
65 files changed
Lines changed: 3083 additions & 276 deletions
File tree
- .agents/skills/fb-comment-automation
- apps
- builder
- messages
- src/features/flows/react-flow/steps
- button
- __tests__
- send-audio
- send-file
- send-gif
- send-image
- send-video
- worker
- __tests__
- src/integration/handlers
- comment-automation
- docs
- integrations
- instagram-facebook
- __tests__
- src/handlers
- comment/outgoing-comment
- message/outgoing-message
- instagram
- __tests__
- src/handlers
- comment/outgoing-comment
- message/outgoing-message
- messenger
- __tests__
- src/handlers/message/outgoing-message
- packages
- business/src/fb-comment-automation
- flow-config
- __tests__
- src
- channel-rules
- worker-config/src/queues/ai-agent
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
86 | 86 | | |
87 | 87 | | |
88 | 88 | | |
89 | | - | |
90 | | - | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
91 | 99 | | |
92 | 100 | | |
93 | 101 | | |
94 | 102 | | |
95 | 103 | | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
96 | 111 | | |
97 | 112 | | |
98 | 113 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2524 | 2524 | | |
2525 | 2525 | | |
2526 | 2526 | | |
2527 | | - | |
| 2527 | + | |
| 2528 | + | |
| 2529 | + | |
| 2530 | + | |
| 2531 | + | |
2528 | 2532 | | |
2529 | 2533 | | |
2530 | 2534 | | |
| |||
3179 | 3183 | | |
3180 | 3184 | | |
3181 | 3185 | | |
3182 | | - | |
| 3186 | + | |
| 3187 | + | |
| 3188 | + | |
3183 | 3189 | | |
3184 | 3190 | | |
3185 | 3191 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2387 | 2387 | | |
2388 | 2388 | | |
2389 | 2389 | | |
2390 | | - | |
| 2390 | + | |
| 2391 | + | |
| 2392 | + | |
| 2393 | + | |
| 2394 | + | |
2391 | 2395 | | |
2392 | 2396 | | |
2393 | 2397 | | |
| |||
3179 | 3183 | | |
3180 | 3184 | | |
3181 | 3185 | | |
3182 | | - | |
| 3186 | + | |
| 3187 | + | |
| 3188 | + | |
3183 | 3189 | | |
3184 | 3190 | | |
3185 | 3191 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2387 | 2387 | | |
2388 | 2388 | | |
2389 | 2389 | | |
2390 | | - | |
| 2390 | + | |
| 2391 | + | |
| 2392 | + | |
| 2393 | + | |
| 2394 | + | |
2391 | 2395 | | |
2392 | 2396 | | |
2393 | 2397 | | |
| |||
3179 | 3183 | | |
3180 | 3184 | | |
3181 | 3185 | | |
3182 | | - | |
| 3186 | + | |
| 3187 | + | |
| 3188 | + | |
3183 | 3189 | | |
3184 | 3190 | | |
3185 | 3191 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2711 | 2711 | | |
2712 | 2712 | | |
2713 | 2713 | | |
2714 | | - | |
| 2714 | + | |
| 2715 | + | |
| 2716 | + | |
| 2717 | + | |
| 2718 | + | |
2715 | 2719 | | |
2716 | 2720 | | |
2717 | 2721 | | |
| |||
3366 | 3370 | | |
3367 | 3371 | | |
3368 | 3372 | | |
3369 | | - | |
| 3373 | + | |
| 3374 | + | |
| 3375 | + | |
3370 | 3376 | | |
3371 | 3377 | | |
3372 | 3378 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2524 | 2524 | | |
2525 | 2525 | | |
2526 | 2526 | | |
2527 | | - | |
| 2527 | + | |
| 2528 | + | |
| 2529 | + | |
| 2530 | + | |
| 2531 | + | |
2528 | 2532 | | |
2529 | 2533 | | |
2530 | 2534 | | |
| |||
3179 | 3183 | | |
3180 | 3184 | | |
3181 | 3185 | | |
3182 | | - | |
| 3186 | + | |
| 3187 | + | |
| 3188 | + | |
3183 | 3189 | | |
3184 | 3190 | | |
3185 | 3191 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2387 | 2387 | | |
2388 | 2388 | | |
2389 | 2389 | | |
2390 | | - | |
| 2390 | + | |
| 2391 | + | |
| 2392 | + | |
| 2393 | + | |
| 2394 | + | |
2391 | 2395 | | |
2392 | 2396 | | |
2393 | 2397 | | |
| |||
3179 | 3183 | | |
3180 | 3184 | | |
3181 | 3185 | | |
3182 | | - | |
| 3186 | + | |
| 3187 | + | |
| 3188 | + | |
3183 | 3189 | | |
3184 | 3190 | | |
3185 | 3191 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2387 | 2387 | | |
2388 | 2388 | | |
2389 | 2389 | | |
2390 | | - | |
| 2390 | + | |
| 2391 | + | |
| 2392 | + | |
| 2393 | + | |
| 2394 | + | |
2391 | 2395 | | |
2392 | 2396 | | |
2393 | 2397 | | |
| |||
3179 | 3183 | | |
3180 | 3184 | | |
3181 | 3185 | | |
3182 | | - | |
| 3186 | + | |
| 3187 | + | |
| 3188 | + | |
3183 | 3189 | | |
3184 | 3190 | | |
3185 | 3191 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
530 | 530 | | |
531 | 531 | | |
532 | 532 | | |
533 | | - | |
| 533 | + | |
| 534 | + | |
| 535 | + | |
| 536 | + | |
| 537 | + | |
534 | 538 | | |
535 | 539 | | |
536 | 540 | | |
| |||
1322 | 1326 | | |
1323 | 1327 | | |
1324 | 1328 | | |
1325 | | - | |
| 1329 | + | |
| 1330 | + | |
| 1331 | + | |
1326 | 1332 | | |
1327 | 1333 | | |
1328 | 1334 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2387 | 2387 | | |
2388 | 2388 | | |
2389 | 2389 | | |
2390 | | - | |
| 2390 | + | |
| 2391 | + | |
| 2392 | + | |
| 2393 | + | |
| 2394 | + | |
2391 | 2395 | | |
2392 | 2396 | | |
2393 | 2397 | | |
| |||
3179 | 3183 | | |
3180 | 3184 | | |
3181 | 3185 | | |
3182 | | - | |
| 3186 | + | |
| 3187 | + | |
| 3188 | + | |
3183 | 3189 | | |
3184 | 3190 | | |
3185 | 3191 | | |
| |||
0 commit comments