Adds support for capturing Click-to-WhatsApp ad referral metadata from incoming WhatsApp messages. This stores Meta Cloud API `referral` payloads on the incoming message `content_attributes` and normalizes Twilio `Referral*` callback fields into the same shape. The UI display is intentionally deferred until Instagram, Messenger, and TikTok referral payloads are captured as well, so we can design one cross-channel referral surface instead of a WhatsApp-only sidebar block. Why message-level storage Meta sends CTWA referral details as part of the inbound message payload, not as a stable conversation-level webhook. The referral represents the exact ad click that produced that specific customer message, and later messages in the same conversation may not carry the same context. Storing the normalized referral on the message preserves the original webhook semantics, avoids adding conversation-level attribution that could become stale or ambiguous, and keeps support for both Cloud API and Twilio payloads aligned behind `content_attributes.referral`. Fixes https://linear.app/chatwoot/issue/CW-7090/surface-meta-ctwa-referral-on-incoming-whatsapp-messages-cloud-api Closes https://github.com/chatwoot/chatwoot/issues/13995, https://github.com/chatwoot/chatwoot/issues/12560, https://github.com/chatwoot/chatwoot/issues/13006 Related community PRs - https://github.com/chatwoot/chatwoot/pull/13130 - https://github.com/chatwoot/chatwoot/pull/14180 - https://github.com/chatwoot/chatwoot/pull/14121 Related follow-ups - https://linear.app/chatwoot/issue/CW-7301/capture-instagram-ad-referral-metadata-on-incoming-messages - https://linear.app/chatwoot/issue/CW-7302/capture-messenger-ad-referral-metadata-on-facebook-page-conversations - https://linear.app/chatwoot/issue/CW-7303/capture-tiktok-ad-referral-metadata-from-im-referral-msg-events How to test 1. Send or replay a WhatsApp Cloud API inbound message that contains a `messages[0].referral` payload from a Click-to-WhatsApp ad. 2. Confirm the generated incoming message stores the payload under `content_attributes.referral`. 3. Repeat with a Twilio WhatsApp callback containing `Referral*` fields and confirm the stored message has the same normalized `content_attributes.referral` structure. --------- Co-authored-by: Muhsin <12408980+muhsin-k@users.noreply.github.com>
52 lines
1.1 KiB
Ruby
52 lines
1.1 KiB
Ruby
class Twilio::CallbackController < ApplicationController
|
|
def create
|
|
Webhooks::TwilioEventsJob.perform_later(permitted_params.to_unsafe_hash)
|
|
|
|
head :no_content
|
|
end
|
|
|
|
private
|
|
|
|
def permitted_params # rubocop:disable Metrics/MethodLength
|
|
params.permit(
|
|
:ApiVersion,
|
|
:SmsSid,
|
|
:From,
|
|
:ToState,
|
|
:ToZip,
|
|
:AccountSid,
|
|
:MessageSid,
|
|
:FromCountry,
|
|
:ToCity,
|
|
:FromCity,
|
|
:To,
|
|
:FromZip,
|
|
:Body,
|
|
:ToCountry,
|
|
:FromState,
|
|
*Array.new(10) { |i| :"MediaUrl#{i}" },
|
|
*Array.new(10) { |i| :"MediaContentType#{i}" },
|
|
:MessagingServiceSid,
|
|
:NumMedia,
|
|
:Latitude,
|
|
:Longitude,
|
|
:MessageType,
|
|
:ProfileName,
|
|
:ExternalUserId,
|
|
:ParentExternalUserId,
|
|
:ProfileUsername,
|
|
:Username,
|
|
:ReferralBody,
|
|
:ReferralHeadline,
|
|
:ReferralSourceId,
|
|
:ReferralSourceType,
|
|
:ReferralSourceUrl,
|
|
:ReferralMediaId,
|
|
:ReferralMediaContentType,
|
|
:ReferralMediaUrl,
|
|
:ReferralNumMedia,
|
|
:ReferralCtwaClid
|
|
)
|
|
end
|
|
end
|