STRATCONN-6441 - [Facebook CAPI] - AppendValue support for custom and purchase events#3793
STRATCONN-6441 - [Facebook CAPI] - AppendValue support for custom and purchase events#3793joe-ayoub-segment wants to merge 13 commits into
Conversation
There was a problem hiding this comment.
Pull request overview
Adds support for Facebook CAPI’s AppendValue event shape for Custom and Purchase actions by introducing new append-related fields, a feature flag, and conversion logic in the shared event-data builders.
Changes:
- Introduces
AppendValueEventData/AppendEventDetailstypes and aFEATURE_FLAG_APPEND_VALUEflag. - Extends shared
getCustomEventData/getPurchaseEventDatato optionally convert outgoing payloads intoAppendValuerequests. - Adds new action fields (
is_append_event,append_event_details) and purchase fields (order_id,predicted_ltv) and regenerates action payload types accordingly.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/destination-actions/src/destinations/facebook-conversions-api/shared/types.ts | Adds new AppendValue-related TS interfaces for event payload shaping. |
| packages/destination-actions/src/destinations/facebook-conversions-api/shared/functions.ts | Passes features/statsContext into data builders and adds AppendValue conversion + validation. |
| packages/destination-actions/src/destinations/facebook-conversions-api/shared/fields.ts | Adds append configuration fields and extends purchase/custom field sets. |
| packages/destination-actions/src/destinations/facebook-conversions-api/shared/constants.ts | Introduces FEATURE_FLAG_APPEND_VALUE. |
| packages/destination-actions/src/destinations/facebook-conversions-api/purchase2/generated-types.ts | Regenerates payload types to include append + new purchase fields. |
| packages/destination-actions/src/destinations/facebook-conversions-api/purchase/generated-types.ts | Regenerates payload types to include append + new purchase fields. |
| packages/destination-actions/src/destinations/facebook-conversions-api/custom2/generated-types.ts | Regenerates payload types to include append configuration fields. |
| packages/destination-actions/src/destinations/facebook-conversions-api/custom/generated-types.ts | Regenerates payload types to include append configuration fields. |
Comments suppressed due to low confidence (3)
packages/destination-actions/src/destinations/facebook-conversions-api/shared/functions.ts:268
- Same issue as custom: if
is_append_eventis true butFEATURE_FLAG_APPEND_VALUEis not enabled, the code returns a normalPurchaseevent rather than failing fast. Consider explicitly erroring (or otherwise surfacing) this unsupported configuration to avoid silently sending the wrong event type.
export function getPurchaseEventData(payload: PurchasePayload | Purchase2Payload, features?: Features, statsContext?: StatsContext): PurchaseEventData | AppendValueEventData {
const baseEventData = getBaseEventData(payload)
const { is_append_event, append_event_details, order_id, predicted_ltv, custom_data, currency, value, content_ids, net_revenue, content_name, content_type, num_items, contents } =
payload
const data: PurchaseEventData = {
event_name: 'Purchase',
...baseEventData,
custom_data: {
...custom_data,
currency,
value,
...(order_id && { order_id }),
...(typeof predicted_ltv === 'number' && { predicted_ltv }),
...(typeof net_revenue === 'number' && { net_revenue }),
...(Array.isArray(content_ids) && content_ids.length > 0 && { content_ids }),
...(content_name && { content_name }),
...(content_type && { content_type }),
...(contents && { contents }),
...(typeof num_items === 'number' && { num_items })
}
}
if(features?.[FEATURE_FLAG_APPEND_VALUE] && is_append_event && append_event_details) {
return convertToAppendValueEventData(data, append_event_details as AppendEventDetails, statsContext)
}
return data
packages/destination-actions/src/destinations/facebook-conversions-api/shared/fields.ts:657
purchaseFieldsnow exposesis_append_event/append_event_detailsand alsoorder_id/predicted_ltv, but the Purchase action only usesgetPurchaseEventData(which handles these fields) whenFEATURE_FLAG_PURCHASEis enabled. When that flag is off, the legacyperformpath does not sendorder_id/predicted_ltvand cannot emitAppendValue, so these mapped fields will be silently ignored. Either wire these fields into the legacy path or fail fast / gate the fields so they can't be configured when unsupported.
export const purchaseFields: Record<string, InputField> = {
is_append_event,
append_event_details,
action_source: { ...action_source, required: true },
currency: { ...currency, required: true },
event_time: { ...event_time, required: true },
user_data: user_data_field,
app_data_field,
value: {
...value,
required: true,
default: { '@path': '$.properties.revenue' }
},
order_id,
predicted_ltv,
net_revenue,
packages/destination-actions/src/destinations/facebook-conversions-api/shared/fields.ts:835
customFieldsnow exposesis_append_event/append_event_details, but the Custom action only routes throughgetCustomEventData(which can convert toAppendValue) whenFEATURE_FLAG_CUSTOMis enabled. When that flag is off, the legacyperformpath ignores these fields and will never send anAppendValueevent. Either add AppendValue support to the legacy path or prevent this configuration when the refactor flag is disabled (so the fields aren't silently ignored).
export const customFields: Record<string, InputField> = {
is_append_event,
append_event_details,
action_source: { ...action_source, required: true },
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 8 out of 8 changed files in this pull request and generated 3 comments.
Comments suppressed due to low confidence (1)
packages/destination-actions/src/destinations/facebook-conversions-api/shared/fields.ts:835
customFieldsexposesis_append_eventandappend_event_details, but the legacy (FEATURE_FLAG_CUSTOM off) implementation incustom/index.tsnever callsgetCustomEventData, so the append-value toggle has no effect unless the refactor flag is enabled. To avoid a confusing no-op configuration, either implement append-value behavior for the legacy code path too or gate/hide these fields when the refactor flag isn’t enabled.
export const customFields: Record<string, InputField> = {
is_append_event,
append_event_details,
action_source: { ...action_source, required: true },
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 19 out of 19 changed files in this pull request and generated 3 comments.
Comments suppressed due to low confidence (1)
packages/destination-actions/src/destinations/facebook-conversions-api/shared/functions.ts:276
- When
is_append_eventis true butappend_event_detailsis missing/undefined, this currently returns a normalPurchaseevent instead of failing fast. Since the UI makesappend_event_detailsrequired whenis_append_eventis true, it’s better to enforce the same invariant at runtime and throw aPayloadValidationErrorif details are not provided.
if(is_append_event) {
if(!features?.[FEATURE_FLAG_APPEND_VALUE]) {
throw new PayloadValidationError('AppendValue is not enabled for this destination. Please contact Segment support so the feature can be enabled for your Segment workspace.')
}
if(append_event_details) {
return convertToAppendValueEventData(data, append_event_details as AppendEventDetails, statsContext)
}
}
Co-authored-by: Copilot Autofix powered by AI <[email protected]>
Co-authored-by: Copilot Autofix powered by AI <[email protected]>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 19 out of 19 changed files in this pull request and generated 7 comments.
Comments suppressed due to low confidence (1)
packages/destination-actions/src/destinations/facebook-conversions-api/shared/functions.ts:274
- When
is_append_eventis true butappend_event_detailsis missing/undefined, this function currently returns a normal Purchase payload. That will silently emit a non-AppendValue event even though the caller opted into append mode. Consider throwing aPayloadValidationErrorifis_append_eventis true andappend_event_detailsis not provided (after checking the feature flag).
if(!features?.[FEATURE_FLAG_APPEND_VALUE]) {
throw new PayloadValidationError('AppendValue is not enabled for this destination. Please contact Segment support so the feature can be enabled for your Segment workspace.')
}
if(append_event_details) {
return convertToAppendValueEventData(data, append_event_details as AppendEventDetails, statsContext)
Co-authored-by: Copilot Autofix powered by AI <[email protected]>
Co-authored-by: Copilot Autofix powered by AI <[email protected]>
Co-authored-by: Copilot Autofix powered by AI <[email protected]>
Co-authored-by: Copilot Autofix powered by AI <[email protected]>
Co-authored-by: Copilot Autofix powered by AI <[email protected]>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 19 out of 19 changed files in this pull request and generated 3 comments.
Comments suppressed due to low confidence (4)
packages/destination-actions/src/destinations/facebook-conversions-api/shared/fields.ts:224
ctwa_clidis added to the shared user data schema, but the legacyhash_user_dataimplementation (used in the non-refactoredperformpaths) doesn’t map it through to Facebook, so this field will be silently ignored when the refactor feature flags are OFF. Consider addingctwa_clidpassthrough to the legacy user-data mapping (or ensuring all code paths usegetUserData).
ctwa_clid: {
label: 'Click to WhatsApp Click ID (ctwa_clid)',
description: 'Click ID generated by Meta for ads that click to WhatsApp.',
type: 'string'
}
packages/destination-actions/src/destinations/facebook-conversions-api/shared/functions.ts:273
- Formatting here is inconsistent with the rest of the file (missing spaces in
if (...)/if (!...)), which will likely fail Prettier/ESLint checks. Please run Prettier (or reformat this block).
if(is_append_event) {
if(!features?.[FEATURE_FLAG_APPEND_VALUE]) {
throw new PayloadValidationError('AppendValue is not enabled for this destination. Please contact Segment support so the feature can be enabled for your Segment workspace.')
}
if(append_event_details) {
packages/destination-actions/src/destinations/facebook-conversions-api/shared/functions.ts:347
convertToAppendValueEventDatahas formatting that diverges from the repo’s Prettier conventions (e.g.,if(!original_event_time)missing spacing). Please run Prettier on this function to avoid formatting/lint failures and keep it readable.
if(!original_event_time) {
statsClient?.incr('append_value_event.error', 1, tags)
throw new PayloadValidationError('If sending an AppendValue, Append Event Details field "Original Event Time" is required')
}
packages/destination-actions/src/destinations/facebook-conversions-api/shared/fields.ts:662
order_id/predicted_ltvare now included inpurchaseFields, but the legacy Purchaseperformimplementation (used when FEATURE_FLAG_PURCHASE is OFF) does not include these in the outboundcustom_data, so they’ll be silently dropped for some workspaces. Either add them to the legacy request mapping or ensure the sharedsend/getPurchaseEventDatapath is used when these fields are set.
order_id,
predicted_ltv,
net_revenue,
Adding support for AppendValue to Facebook CAPI custom and purchase events.
Testing
Unit tests and staging tests to be done.
Security Review
Please ensure sensitive data is properly protected in your integration.
type: 'password'New Destination Checklist
verioning-info.tsfile. example