Skip to content

fix(instagram): correct story-reply message direction and contact profiles - #885

Merged
sung17 merged 1 commit into
mainfrom
fix/ig-story-reply-contact-attribution
Aug 3, 2026
Merged

fix(instagram): correct story-reply message direction and contact profiles#885
sung17 merged 1 commit into
mainfrom
fix/ig-story-reply-contact-attribution

Conversation

@sung17

@sung17 sung17 commented Aug 3, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Meta echoes a genuine first-time customer message (Instagram story reply or plain inbox DM) as is_echo:true with sender.id equal to the page's own IG business account id, which the worker treated as page-authored.
  • New contacts got no name/avatar because profile lookup was unconditionally skipped for any "outgoing" new-contact message.
  • Story-reply automation never fired for a brand-new contact's first story reply, since the message stayed classified as agent-sent, failing the isFromContact gate.

Changes

  • apps/worker/src/integration/handlers/received-message.ts — always attempt profile lookup for new contacts (the existing try/catch already makes a failed lookup safe); flip a new-contact's outgoing story-reply message back to incoming before persisting. Existing contacts are left untouched so a real agent reply-echo isn't reinterpreted as inbound.
  • apps/worker/src/integration/worker.ts — routes story-reply automation using the shared shape check instead of an inline duplicate.
  • packages/sdk/src/lib/shared/message.ts — new getStoryReply() helper unifying the story-reply contentAttributes shape check (current { type: "story_reply", story } vs. legacy { storyReply } on historical rows), used by both the worker routing and the direction correction to prevent the two from drifting apart again.
  • integrations/instagram/src/handlers/message/incomming-message.ts, integrations/instagram-facebook/src/handlers/message/incoming-message.ts — emit the current typed story-reply shape.
  • apps/builder/src/features/messages/components/message-item.tsx + locale files — render "Replied to your story" context in the inbox for story-reply messages.

Test plan

  • pnpm lint
  • pnpm --filter worker check-types
  • pnpm --filter @chatbotx.io/sdk check-types
  • pnpm --filter builder check-types
  • pnpm --filter worker test (140 files / 1313 tests passing, including new regression tests for the story-reply direction correction)

…files

Meta echoes a genuine first-time customer message (story reply or plain
inbox DM) as `is_echo:true` with `sender.id` equal to the page's own IG
business account id. The worker treated that as page-authored:

- New contacts got no name/avatar, because profile lookup was
  unconditionally skipped for any "outgoing" new-contact message
  (skipProfileLookup was redundant since the getProfile call is already
  try/caught, so removing it is safe).
- Story-reply automation never fired for a brand-new contact's first
  story reply, since the message stayed classified as agent-sent
  (senderType "user"), failing worker.ts's isFromContact gate.

Fix: always attempt profile lookup for new contacts, and flip a
new-contact's outgoing story-reply message back to incoming before
persisting (existing contacts are left untouched, since a real agent
reply-echo to a known contact must not be reinterpreted as inbound).

Also unifies the story-reply contentAttributes shape check
(`{ type: "story_reply", story }` vs. the legacy `{ storyReply }` still
present on historical rows) behind one shared `getStoryReply()` helper
in the SDK, used by both the worker routing and the direction
correction, instead of three independent ad hoc casts that had already
drifted from each other.
@github-actions github-actions Bot added the bug Something isn't working as expected label Aug 3, 2026
@sung17
sung17 merged commit 0fe1ff6 into main Aug 3, 2026
7 checks passed
viethung0o0 pushed a commit that referenced this pull request Sep 7, 2026
…files (#885)

Meta echoes a genuine first-time customer message (story reply or plain
inbox DM) as `is_echo:true` with `sender.id` equal to the page's own IG
business account id. The worker treated that as page-authored:

- New contacts got no name/avatar, because profile lookup was
  unconditionally skipped for any "outgoing" new-contact message
  (skipProfileLookup was redundant since the getProfile call is already
  try/caught, so removing it is safe).
- Story-reply automation never fired for a brand-new contact's first
  story reply, since the message stayed classified as agent-sent
  (senderType "user"), failing worker.ts's isFromContact gate.

Fix: always attempt profile lookup for new contacts, and flip a
new-contact's outgoing story-reply message back to incoming before
persisting (existing contacts are left untouched, since a real agent
reply-echo to a known contact must not be reinterpreted as inbound).

Also unifies the story-reply contentAttributes shape check
(`{ type: "story_reply", story }` vs. the legacy `{ storyReply }` still
present on historical rows) behind one shared `getStoryReply()` helper
in the SDK, used by both the worker routing and the direction
correction, instead of three independent ad hoc casts that had already
drifted from each other.

Co-authored-by: Deathgiver <anonymous@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working as expected

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant