From ee5e20551dc2368fde64ba34690b8e0e3bad1732 Mon Sep 17 00:00:00 2001 From: Muhsin Keloth Date: Tue, 23 Jun 2026 11:03:04 +0400 Subject: [PATCH] fix(facebook): handle messenger post attachment type (#14813) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Facebook Messenger messages that share a post no longer break message ingestion. Following the recent sticker change, Meta now sends a shared post as a new `post` attachment type. Chatwoot didn't recognise `post` as a valid attachment file type, so the webhook job crashed and the message — and any others in the same batch — failed to sync. Shared posts now appear in the conversation as a fallback link (title + URL), the same way `share` attachments already do. This is the same class of bug as #14793 (sticker), just a different attachment type. #### Root cause `post` was neither skipped as unsupported nor mapped to a valid `file_type`, so `attachment_params` produced `file_type: :post`. The `Attachment#file_type` enum has no `post` value, so it raised `ArgumentError: 'post' is not a valid file_type`, crashing `Webhooks::FacebookEventsJob`. #### Fix The Facebook builder already maps `share -> :fallback` because shared posts point to facebook.com page URLs rather than downloadable media. A `post` is the same kind of attachment, so map both `share` and `post` to `fallback` (stores the title/link, no download attempt). Also read the fallback title from `payload.title`, since the post payload nests it there rather than at the top level. ## How to reproduce 1. Connect a Facebook Page inbox. 2. Share a Facebook post into Messenger to that page. 3. Before this change: `Webhooks::FacebookEventsJob` raises `ArgumentError: 'post' is not a valid file_type` and the message is dropped. 4. After this change: the shared post shows up in the conversation as a fallback link. Co-authored-by: Muhsin <12408980+muhsin-k@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 (1M context) --- app/builders/messages/facebook/message_builder.rb | 6 ++++-- spec/builders/messages/facebook/message_builder_spec.rb | 6 ++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/app/builders/messages/facebook/message_builder.rb b/app/builders/messages/facebook/message_builder.rb index 24b6d9e70..c7608399e 100644 --- a/app/builders/messages/facebook/message_builder.rb +++ b/app/builders/messages/facebook/message_builder.rb @@ -91,15 +91,17 @@ class Messages::Facebook::MessageBuilder < Messages::Messenger::MessageBuilder def fallback_params(attachment) { - fallback_title: attachment['title'], + fallback_title: attachment['title'] || attachment.dig('payload', 'title'), external_url: attachment['url'] || attachment.dig('payload', 'url') } end # Facebook shared posts point to page URLs, not downloadable media URLs. + # Both `share` and `post` attachment types carry a page URL rather than a media file, + # so map them to `fallback` (which keeps the title/link without attempting a download). # Keep this Facebook-only so Messenger/Instagram share attachments still use the parent media handling. def normalize_file_type(type) - return :fallback if type.to_sym == :share + return :fallback if [:share, :post].include?(type.to_sym) super end diff --git a/spec/builders/messages/facebook/message_builder_spec.rb b/spec/builders/messages/facebook/message_builder_spec.rb index 7718d23eb..0468c2c09 100644 --- a/spec/builders/messages/facebook/message_builder_spec.rb +++ b/spec/builders/messages/facebook/message_builder_spec.rb @@ -212,6 +212,12 @@ describe Messages::Facebook::MessageBuilder do attachment: { type: 'share', title: 'Shared Facebook post', payload: { url: 'https://www.facebook.com/example/posts/123' } }, title: 'Shared Facebook post', url: 'https://www.facebook.com/example/posts/123' + }, + { + source_id: 'm_post_test', + attachment: { type: 'post', payload: { title: 'Shared post caption', url: 'https://www.facebook.com/example/posts/456' } }, + title: 'Shared post caption', + url: 'https://www.facebook.com/example/posts/456' } ].each do |message_data| it "stores #{message_data[:attachment][:type]} attachments as fallback links" do