22
33import { useEffect } from "react" ;
44import { publicConfig } from "@databuddy/env/public" ;
5+ import type { SignupEventProperties } from "@databuddy/shared/custom-events" ;
56
67const PIXEL_ID = publicConfig . integrations . openAiAdsPixelId ;
78const SCRIPT_SRC = "https://bzrcdn.openai.com/sdk/oaiq.min.js" ;
89
10+ interface RegistrationConversionInput {
11+ email ?: string ;
12+ eventId ?: string ;
13+ properties ?: SignupEventProperties ;
14+ sourceUrl ?: string ;
15+ }
16+
17+ interface RegistrationConversionPayload {
18+ email ?: string ;
19+ eventId : string ;
20+ oppref ?: string ;
21+ sourceUrl : string ;
22+ }
23+
924type OpenAiAdsQueue = ( ( ...args : unknown [ ] ) => void ) & {
1025 q ?: unknown [ ] [ ] ;
1126} ;
@@ -60,6 +75,38 @@ function initOpenAiQueue(): boolean {
6075 return true ;
6176}
6277
78+ function createRegistrationEventId ( ) : string {
79+ if ( typeof crypto !== "undefined" && "randomUUID" in crypto ) {
80+ return crypto . randomUUID ( ) ;
81+ }
82+
83+ return `registration_completed_${ Date . now ( ) } _${ Math . random ( )
84+ . toString ( 36 )
85+ . slice ( 2 ) } `;
86+ }
87+
88+ export function buildOpenAiRegistrationConversionPayload (
89+ input : RegistrationConversionInput
90+ ) : RegistrationConversionPayload {
91+ return {
92+ ...( input . email ? { email : input . email } : { } ) ,
93+ eventId : input . eventId ?? createRegistrationEventId ( ) ,
94+ ...( input . properties ?. oppref ? { oppref : input . properties . oppref } : { } ) ,
95+ sourceUrl : input . sourceUrl ?? window . location . href ,
96+ } ;
97+ }
98+
99+ export function buildOpenAiRegistrationMeasureArgs (
100+ eventId ?: string
101+ ) : unknown [ ] {
102+ return [
103+ "measure" ,
104+ "registration_completed" ,
105+ { type : "customer_action" } ,
106+ ...( eventId ? [ { event_id : eventId } ] : [ ] ) ,
107+ ] ;
108+ }
109+
63110export function OpenAiAdsPixel ( ) {
64111 useEffect ( ( ) => {
65112 initOpenAiQueue ( ) ;
@@ -68,12 +115,39 @@ export function OpenAiAdsPixel() {
68115 return null ;
69116}
70117
71- export function measureOpenAiRegistrationCompleted ( ) {
118+ export function measureOpenAiRegistrationCompleted ( eventId ?: string ) {
72119 if ( ! initOpenAiQueue ( ) ) {
73120 return ;
74121 }
75122
76- window . oaiq ?.( "measure" , "registration_completed" , {
77- type : "customer_action" ,
123+ window . oaiq ?.( ...buildOpenAiRegistrationMeasureArgs ( eventId ) ) ;
124+ }
125+
126+ export function sendOpenAiRegistrationCompletedConversion (
127+ payload : RegistrationConversionPayload
128+ ) {
129+ if (
130+ typeof window === "undefined" ||
131+ ! PIXEL_ID ||
132+ ! isOpenAiAdsPixelHostAllowed ( window . location . hostname )
133+ ) {
134+ return ;
135+ }
136+
137+ fetch ( "/api/openai-ads/conversions" , {
138+ body : JSON . stringify ( payload ) ,
139+ headers : { "Content-Type" : "application/json" } ,
140+ keepalive : true ,
141+ method : "POST" ,
142+ } ) . catch ( ( ) => {
143+ // Signup should not depend on ad-platform reporting.
78144 } ) ;
79145}
146+
147+ export function trackOpenAiRegistrationCompleted (
148+ input : RegistrationConversionInput = { }
149+ ) {
150+ const payload = buildOpenAiRegistrationConversionPayload ( input ) ;
151+ measureOpenAiRegistrationCompleted ( payload . eventId ) ;
152+ sendOpenAiRegistrationCompletedConversion ( payload ) ;
153+ }
0 commit comments