Skip to content

Comment-originated contacts cannot be messaged via API even after the contact replies (silent failure) #879

Description

@auroradream04

Summary

Contacts that originate from a Facebook comment cannot be messaged through the public API — even after the contact replies to the private reply and a standard 24-hour messaging window is open. The send returns 204, a message row is created, and nothing is delivered. sourceId is never populated on the row, which is the only way to tell from outside that it failed.

Sends to non-comment-origin contacts on the same inbox work reliably (22/22 in our sample), so this is specific to comment-originated contacts.

Cloud (app.chatbotx.io), Messenger channel, workspace API key.

Reproduction

Contact A (11630996004388864), inbox 11627001976487936. Times UTC, same thread:

time messageType senderType delivered? note
10:47:30 outgoing user yes (sourceId set) sent from Meta Business Suite, echoed in
10:47:50 incoming contact yes contact replies — 24h window opens
10:47:59 outgoing api no (sourceId null) POST /v1/contacts/id:.../messages → 204

Contact B (11630484688945152) is identical: contact sends "Is this free?" at 01:48:02, our API reply at 01:48:11 never delivers.

Sending manually from the ChatbotX inbox UI on the message thread also fails to deliver, so this is not specific to the public API.

Both contacts have a normal 17-digit contactInbox.sourceId, the same shape as contacts we message successfully. Their conversation.sourceId is <pageId>_<postId>.

Expected

Per Meta's Private Replies docs:

Only when a person responds to the private message can you continue the conversation within the 24-hour messaging window.

The contact responded, so a normal send should succeed.

Suspected cause

apps/worker/src/integration/handlers/received-message.tsreceiveComment keys the conversation to the post:

const incomingContact: IncomingContact = {
  sourceId: commentData.fromId,
  sourceConversationId: commentData.postId,
}

apps/worker/src/chat/handlers/send-message.ts then forwards that to the channel handler:

contact: { ...contactInbox, sourceConversationId: conversation.sourceId }

So a send resolving the comment conversation hands the channel a post id where a working contact supplies a message thread id. (The messenger channel implementation isn't in this repo, so I couldn't verify past this point.)

Possibly compounded by the assumption on the line above it:

// `from.id` is the commenter's ID (PSID for Messenger, ...)

Meta treats IDs across surfaces as not interchangeable — hence the ID Matching API. If a comment's from.id is not the messaging PSID for that Page, storing it as contactInbox.sourceId would produce exactly this: a well-formed id the Send API rejects.

Secondary issue: the failure is invisible to API consumers

send-message.ts emits message:failed internally, but nothing is persisted on the message row and the public API exposes no delivery status. From outside, a dead message is indistinguishable from a delivered one except by inferring from sourceId: null. This is the same silent-failure shape described in #831.

Surfacing a delivery status on the message resource would let integrators detect this without guesswork.

Third issue: lastIncomingMessageAt ignores comments and attachment-only messages

received-message.ts:

if (incomingMessage.messageType !== "outgoing" &&
    (incomingMessage.type ?? "message") === "message") {
  tracking.lastIncomingMessageAt = message.createdAt

Comments never update it, and attachment-only messages appear not to either. Since the unreplied and lastInteractionMinutesAgo contact filters are built on that column, any integrator polling for "who is waiting on a reply" is blind to both. In our workspace 48/50 comment-origin contacts have lastIncomingMessageAt: null.

Impact

Comment-to-DM is our main lead source. Every one of those leads who engages gets a reply that is recorded, billed, and shown as sent — and never arrives. It is silent on every surface except the Facebook thread itself.

Happy to test any fix against a live workspace.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

bugSomething isn't working as expected

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions