Skip to content

Commit 0fb2b33

Browse files
[Facebook CAPI Web] - New Destination (#3028)
* [Facebook CAPI Web] - New Destination * minor progress * progress * progress * adding actions * adding search action * saving prpgress * more fuddling * refactor to single action * progress * more progress * temporarily removing test files * increasing web bundle max size
1 parent 8a5b8fd commit 0fb2b33

File tree

16 files changed

+1692
-1
lines changed

16 files changed

+1692
-1
lines changed
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# @segment/analytics-browser-actions-facebook-conversions-api-web
2+
3+
The Facebook Conversions Api Web browser action destination for use with @segment/analytics-next.
4+
5+
## License
6+
7+
MIT License
8+
9+
Copyright (c) 2025 Segment
10+
11+
Permission is hereby granted, free of charge, to any person obtaining a copy
12+
of this software and associated documentation files (the "Software"), to deal
13+
in the Software without restriction, including without limitation the rights
14+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15+
copies of the Software, and to permit persons to whom the Software is
16+
furnished to do so, subject to the following conditions:
17+
18+
The above copyright notice and this permission notice shall be included in all
19+
copies or substantial portions of the Software.
20+
21+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27+
SOFTWARE.
28+
29+
## Contributing
30+
31+
All third party contributors acknowledge that any contributions they provide will be made under the same open source license that the open source project is provided under.
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
{
2+
"name": "@segment/analytics-browser-actions-facebook-conversions-api-web",
3+
"version": "1.0.0",
4+
"license": "MIT",
5+
"repository": {
6+
"type": "git",
7+
"url": "https://github.com/segmentio/action-destinations",
8+
"directory": "packages/browser-destinations/destinations/facebook-conversions-api-web"
9+
},
10+
"main": "./dist/cjs",
11+
"module": "./dist/esm",
12+
"scripts": {
13+
"build": "yarn build:esm && yarn build:cjs",
14+
"build:cjs": "tsc --module commonjs --outDir ./dist/cjs",
15+
"build:esm": "tsc --outDir ./dist/esm"
16+
},
17+
"typings": "./dist/esm",
18+
"dependencies": {
19+
"@segment/browser-destination-runtime": "^1.4.0"
20+
},
21+
"peerDependencies": {
22+
"@segment/analytics-next": ">=1.55.0"
23+
}
24+
}

packages/browser-destinations/destinations/facebook-conversions-api-web/src/generated-types.ts

Lines changed: 16 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
import type { Settings } from './generated-types'
2+
import type { BrowserDestinationDefinition } from '@segment/browser-destination-runtime/types'
3+
import { browserDestination } from '@segment/browser-destination-runtime/shim'
4+
import send from './send'
5+
import { initScript } from './init-script'
6+
import { FBClient, LDU } from './types'
7+
import { defaultValues } from '@segment/actions-core'
8+
9+
declare global {
10+
interface Window {
11+
fbq: FBClient
12+
}
13+
}
14+
15+
export const destination: BrowserDestinationDefinition<Settings, FBClient> = {
16+
name: 'Facebook Conversions Api Web',
17+
slug: 'actions-facebook-conversions-api-web',
18+
mode: 'device',
19+
description: 'Send events to Facebook Conversions API from the browser.',
20+
settings: {
21+
pixelId: {
22+
description: 'The Pixel ID associated with your Facebook Pixel.',
23+
label: 'Pixel ID',
24+
type: 'string',
25+
required: true
26+
},
27+
disablePushState: {
28+
description: "If set to true, prevents Facebook Pixel from sending PageView events on history state changes. Set to true if you want to trigger PageView events manually via the pageView Action.",
29+
label: 'Disable Push State',
30+
type: 'boolean'
31+
},
32+
ldu: {
33+
label: 'Limited Data User (LDU)',
34+
description: 'Specify if and how Limited Data Use should apply.',
35+
type: 'string',
36+
required: true,
37+
choices: [
38+
{ label: 'LDU disabled', value: LDU.Disabled.key},
39+
{ label: "LDU enabled - Use Meta Geolocation Logic", value: LDU.GeolocationLogic.key },
40+
{ label: 'LDU enabled - California only', value: LDU.California.key },
41+
{ label: 'LDU enabled - Colorado only', value: LDU.Colorado.key },
42+
{ label: 'LDU enabled - Connecticut only', value: LDU.Connecticut.key },
43+
{ label: 'LDU enabled - Florida only', value: LDU.Florida.key },
44+
{ label: 'LDU enabled - Oregon only', value: LDU.Oregon.key },
45+
{ label: 'LDU enabled - Texas only', value: LDU.Texas.key },
46+
{ label: 'LDU enabled - Montana only', value: LDU.Montana.key },
47+
{ label: 'LDU enabled - Delaware only', value: LDU.Delaware.key },
48+
{ label: 'LDU enabled - Nebraska only', value: LDU.Nebraska.key },
49+
{ label: 'LDU enabled - New Hampshire only', value: LDU.NewHampshire.key },
50+
{ label: 'LDU enabled - New Jersey only', value: LDU.NewJersey.key },
51+
{ label: 'LDU enabled - Minnesota only', value: LDU.Minnesota.key }
52+
],
53+
default: LDU.Disabled.key
54+
}
55+
},
56+
initialize: async ({ settings }, deps) => {
57+
const { pixelId, disablePushState, ldu } = settings
58+
initScript(pixelId, ldu as keyof typeof LDU, disablePushState)
59+
await deps.resolveWhen(() => typeof window.fbq === 'function', 100)
60+
return window.fbq
61+
},
62+
63+
actions: {
64+
send
65+
},
66+
presets: [
67+
{
68+
name: 'AddPaymentInfo',
69+
subscribe: 'event = "Payment Info Entered"',
70+
partnerAction: 'send',
71+
mapping:
72+
{
73+
...defaultValues(send.fields),
74+
event_config: {
75+
event_name: 'AddPaymentInfo',
76+
custom_event_name: null,
77+
show_fields: false
78+
}
79+
},
80+
type: 'automatic'
81+
},
82+
{
83+
name: 'AddToCart',
84+
subscribe: 'event = "Product Added"',
85+
partnerAction: 'send',
86+
mapping:
87+
{
88+
...defaultValues(send.fields),
89+
event_config: {
90+
event_name: 'AddToCart',
91+
custom_event_name: null,
92+
show_fields: false
93+
},
94+
content: {
95+
id: { '@path': '$.properties.product_id' },
96+
quantity: { '@path': '$.properties.quantity' },
97+
item_price: { '@path': '$.properties.price' }
98+
}
99+
},
100+
type: 'automatic'
101+
},
102+
{
103+
name: 'AddToWishlist',
104+
subscribe: 'event = "Product Added To Wishlist"',
105+
partnerAction: 'send',
106+
mapping:
107+
{
108+
...defaultValues(send.fields),
109+
event_config: {
110+
event_name: 'AddToWishlist',
111+
custom_event_name: null,
112+
show_fields: false
113+
},
114+
content: {
115+
id: { '@path': '$.properties.product_id' },
116+
quantity: { '@path': '$.properties.quantity' },
117+
item_price: { '@path': '$.properties.price' }
118+
}
119+
},
120+
type: 'automatic'
121+
},
122+
{
123+
name: 'CompleteRegistration',
124+
subscribe: 'event = "Signed Up"',
125+
partnerAction: 'send',
126+
mapping:
127+
{
128+
...defaultValues(send.fields),
129+
event_config: {
130+
event_name: 'CompleteRegistration',
131+
custom_event_name: null,
132+
show_fields: false
133+
}
134+
},
135+
type: 'automatic'
136+
},
137+
{
138+
name: 'InitiateCheckout',
139+
subscribe: 'event = "Checkout Started"',
140+
partnerAction: 'send',
141+
mapping:
142+
{
143+
...defaultValues(send.fields),
144+
event_config: {
145+
event_name: 'InitiateCheckout',
146+
custom_event_name: null,
147+
show_fields: false
148+
}
149+
},
150+
type: 'automatic'
151+
},
152+
{
153+
name: 'Purchase',
154+
subscribe: 'event = "Order Completed"',
155+
partnerAction: 'send',
156+
mapping:
157+
{
158+
...defaultValues(send.fields),
159+
event_config: {
160+
event_name: 'Purchase',
161+
custom_event_name: null,
162+
show_fields: false
163+
}
164+
},
165+
type: 'automatic'
166+
},
167+
{
168+
name: 'Search',
169+
subscribe: 'event = "Products Searched"',
170+
partnerAction: 'send',
171+
mapping:
172+
{
173+
...defaultValues(send.fields),
174+
event_config: {
175+
event_name: 'Search',
176+
custom_event_name: null,
177+
show_fields: false
178+
}
179+
},
180+
type: 'automatic'
181+
},
182+
{
183+
name: 'ViewContent',
184+
subscribe: 'event = "Product Viewed"',
185+
partnerAction: 'send',
186+
mapping:
187+
{
188+
...defaultValues(send.fields),
189+
event_config: {
190+
event_name: 'ViewContent',
191+
custom_event_name: null,
192+
show_fields: false
193+
},
194+
content: {
195+
id: { '@path': '$.properties.product_id' },
196+
quantity: { '@path': '$.properties.quantity' },
197+
item_price: { '@path': '$.properties.price' }
198+
}
199+
},
200+
type: 'automatic'
201+
}
202+
]
203+
}
204+
205+
export default browserDestination(destination)
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/* eslint-disable */
2+
// @ts-nocheck
3+
import { LDU } from './types'
4+
import { getLDU } from './send/utils';
5+
6+
export function initScript(pixelId: string, ldu: keyof typeof LDU, disablePushState?: boolean ) {
7+
(function(f, b, e, v, n, t, s) {
8+
if (f.fbq) return;
9+
n = f.fbq = function() {
10+
n.callMethod ?
11+
n.callMethod.apply(n, arguments) : n.queue.push(arguments);
12+
};
13+
if (!f._fbq) f._fbq = n;
14+
n.push = n;
15+
n.loaded = true;
16+
n.version = '2.0';
17+
n.queue = [];
18+
t = b.createElement(e);
19+
t.async = true;
20+
t.src = v;
21+
s = b.getElementsByTagName(e)[0];
22+
s.parentNode.insertBefore(t, s);
23+
})(window, document, 'script', 'https://connect.facebook.net/en_US/fbevents.js');
24+
25+
if(ldu === LDU.Disabled.key) {
26+
window.fbq('dataProcessingOptions', [])
27+
}
28+
else {
29+
const lduObj = getLDU(ldu)
30+
window.fbq('dataProcessingOptions', ['LDU'], lduObj.country, lduObj.state)
31+
}
32+
33+
window.fbq('init', pixelId)
34+
if(typeof disablePushState === 'boolean' && disablePushState === false) {
35+
// Customer will handle page tracking manually
36+
window.fbq.disablePushState = false
37+
} else {
38+
window.fbq('track', 'PageView')
39+
}
40+
}

0 commit comments

Comments
 (0)