Skip to content

Commit 12e95a1

Browse files
feat: Add meta pixel conversion events (calcom#25638)
* feat(meta-pixel): add trackingEvent to zod schema * fix: do not allow trackingEvent to be optional * feat(meta-pixel): add trackingEvent selection dropdown to UI * feat(meta-pixel): add trackingEvent to Event Type App Data * fix(meta-pixel): implement history API hook for SPA conversion tracking * fix(meta-pixel): check for cancel in URL and prevent Re-wrapping of pushState * Update EventTypeAppSettingsInterface.tsx * fix: make trackingEvent optional in zod schema to fix type-check --------- Co-authored-by: Sahitya Chandra <sahityajb@gmail.com>
1 parent 60b6086 commit 12e95a1

4 files changed

Lines changed: 45 additions & 10 deletions

File tree

packages/app-store/_utils/getEventTypeAppData.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ export const getEventTypeAppData = <T extends EventTypeAppsList>(
2525
currency: eventType.currency || appMetadata.currency || null,
2626
// trackingId is legacy way to store value for TRACKING_ID. So, we need to support both.
2727
TRACKING_ID: appMetadata.TRACKING_ID || appMetadata.trackingId || null,
28+
TRACKING_EVENT: appMetadata.trackingEvent || "Lead",
2829
}
2930
: null;
3031
}

packages/app-store/metapixel/components/EventTypeAppSettingsInterface.tsx

Lines changed: 42 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,55 @@
1+
import { useEffect } from "react";
2+
13
import type { EventTypeAppSettingsComponent } from "@calcom/app-store/types";
2-
import { TextField } from "@calcom/ui/components/form";
4+
import { Label, Select, TextField } from "@calcom/ui/components/form";
35

46
const EventTypeAppSettingsInterface: EventTypeAppSettingsComponent = ({
57
getAppData,
68
setAppData,
79
disabled,
810
}) => {
911
const trackingId = getAppData("trackingId");
12+
const trackingEvent = getAppData("trackingEvent");
13+
14+
type EventOption = { label: string; value: string };
15+
const eventOptions: EventOption[] = [
16+
{ label: "Lead", value: "Lead" },
17+
{ label: "Complete Registration", value: "CompleteRegistration" },
18+
{ label: "Schedule", value: "Schedule" },
19+
{ label: "Page View (use for custom tracking)", value: "PageView" },
20+
];
21+
22+
const currentOption = eventOptions.find((e) => e.value === trackingEvent) || eventOptions[0];
23+
24+
useEffect(() => {
25+
if (!trackingEvent) {
26+
setAppData("trackingEvent", "Lead");
27+
}
28+
}, [trackingEvent, setAppData]);
1029

1130
return (
12-
<TextField
13-
name="Pixel ID"
14-
value={trackingId}
15-
disabled={disabled}
16-
onChange={(e) => {
17-
setAppData("trackingId", e.target.value);
18-
}}
19-
/>
31+
<div className="flex flex-col gap-2">
32+
<TextField
33+
name="Pixel ID"
34+
value={trackingId}
35+
disabled={disabled}
36+
onChange={(e) => {
37+
setAppData("trackingId", e.target.value);
38+
}}
39+
/>
40+
<div className="flex flex-col gap-1">
41+
<Label>Select Conversion Event to Fire</Label>
42+
<Select
43+
options={eventOptions}
44+
value={currentOption}
45+
isDisabled={disabled}
46+
isSearchable={false}
47+
onChange={(e) => {
48+
setAppData("trackingEvent", e?.value ?? "Lead");
49+
}}
50+
/>
51+
</div>
52+
</div>
2053
);
2154
};
2255

packages/app-store/metapixel/config.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
"tag": {
1818
"scripts": [
1919
{
20-
"content": "!function(f,b,e,v,n,t,s){if(f.fbq)return;n=f.fbq=function(){n.callMethod?n.callMethod.apply(n,arguments):n.queue.push(arguments)};if(!f._fbq)f._fbq=n;n.push=n;n.loaded=!0;n.version='2.0';n.queue=[];t=b.createElement(e);t.async=!0;t.src=v;s=b.getElementsByTagName(e)[0];s.parentNode.insertBefore(t,s)}(window,document,'script','https://connect.facebook.net/en_US/fbevents.js');fbq('init','{TRACKING_ID}');fbq('trackCustom','CalcomView');"
20+
"content": "!function(f,b,e,v,n,t,s){if(f.fbq)return;n=f.fbq=function(){n.callMethod?n.callMethod.apply(n,arguments):n.queue.push(arguments)};if(!f._fbq)f._fbq=n;n.push=n;n.loaded=!0;n.version='2.0';n.queue=new Array();t=b.createElement(e);t.async=!0;t.src=v;s=b.getElementsByTagName(e).item(0);s.parentNode.insertBefore(t,s)}(window,document,'script','https://connect.facebook.net/en_US/fbevents.js');fbq('init','{TRACKING_ID}');(function(){window.calMetaCheck=function(u){var url=(typeof u==='string')?u:window.location.href;if(url.indexOf('/booking/')>-1&&url.indexOf('cancel=true')===-1){if(!window.meta_fired){fbq('track','{TRACKING_EVENT}');window.meta_fired=true;}}else{window.meta_fired=false;fbq('track','PageView');fbq('trackCustom','CalcomView');}};if(!history.__cal_meta_pixel_original_push){history.__cal_meta_pixel_original_push=history.pushState;history.pushState=function(s,t,u){history.__cal_meta_pixel_original_push.apply(history,arguments);window.calMetaCheck(u);};}if(!history.__cal_meta_pixel_original_replace){history.__cal_meta_pixel_original_replace=history.replaceState;history.replaceState=function(s,t,u){history.__cal_meta_pixel_original_replace.apply(history,arguments);window.calMetaCheck(u);};}if(!window.__cal_meta_pixel_popstate_added){window.__cal_meta_pixel_popstate_added=true;window.addEventListener('popstate',function(){window.calMetaCheck();});}window.calMetaCheck();})();"
2121
}
2222
]
2323
}

packages/app-store/metapixel/zod.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { eventTypeAppCardZod } from "@calcom/app-store/eventTypeAppCardZod";
55
export const appDataSchema = eventTypeAppCardZod.merge(
66
z.object({
77
trackingId: z.string().default("").optional(),
8+
trackingEvent: z.enum(["Lead", "CompleteRegistration", "Schedule", "PageView"]).optional(),
89
})
910
);
1011
export const appKeysSchema = z.object({});

0 commit comments

Comments
 (0)