Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update TikTok Pixel Destination #1937

Merged
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
import { InputField } from '@segment/actions-core'

export const commonFields: Record<string, InputField> = {
event: {
label: 'Event Name',
type: 'string',
required: true,
description:
'Conversion event name. Please refer to the "Supported Web Events" section on in TikTok’s [Pixel SDK documentation](https://business-api.tiktok.com/portal/docs?id=1739585696931842) for accepted event names.'
},
event_id: {
label: 'Event ID',
type: 'string',
description: 'Any hashed ID that can identify a unique user/session.',
default: {
'@path': '$.messageId'
}
},
phone_number: {
label: 'Phone Number',
description:
'A single phone number in E.164 standard format. TikTok Pixel will hash this value before sending to TikTok. e.g. +14150000000. Segment will hash this value before sending to TikTok.',
type: 'string',
multiple: true,
default: {
'@if': {
exists: { '@path': '$.properties.phone' },
then: { '@path': '$.properties.phone' },
else: { '@path': '$.context.traits.phone' }
}
}
},
email: {
label: 'Email',
description: 'A single email address. TikTok Pixel will be hash this value before sending to TikTok.',
type: 'string',
multiple: true,
default: {
'@if': {
exists: { '@path': '$.properties.email' },
then: { '@path': '$.properties.email' },
else: { '@path': '$.context.traits.email' }
}
}
},
order_id: {
label: 'Order ID',
type: 'string',
description: 'Order ID of the transaction.',
default: {
'@path': '$.properties.order_id'
}
},
shop_id: {
label: 'Shop ID',
type: 'string',
description: 'Shop ID of the transaction.',
default: {
'@path': '$.properties.shop_id'
}
},
external_id: {
label: 'External ID',
description:
'Uniquely identifies the user who triggered the conversion event. TikTok Pixel will hash this value before sending to TikTok.',
type: 'string',
multiple: true,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like you are changing this from a string to be a string array. It should be fine, but is this deliberate?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed this to be a string array to match the s2s destination mappings, so that clients can re-use the same mappings for both Pixel & S2S destinations.

default: {
'@if': {
exists: { '@path': '$.userId' },
then: { '@path': '$.userId' },
else: { '@path': '$.anonymousId' }
}
}
},
contents: {
label: 'Contents',
type: 'object',
multiple: true,
description: 'Related item details for the event.',
properties: {
price: {
label: 'Price',
description: 'Price of the item.',
type: 'number'
},
quantity: {
label: 'Quantity',
description: 'Number of items.',
type: 'number'
},
content_category: {
label: 'Content Category',
description: 'Category of the product item.',
type: 'string'
},
content_id: {
label: 'Content ID',
description: 'ID of the product item.',
type: 'string'
},
content_name: {
label: 'Content Name',
description: 'Name of the product item.',
type: 'string'
},
brand: {
label: 'Brand',
description: 'Brand name of the product item.',
type: 'string'
}
}
},
content_type: {
label: 'Content Type',
description:
'Type of the product item. When the `content_id` in the `Contents` field is specified as a `sku_id`, set this field to `product`. When the `content_id` in the `Contents` field is specified as an `item_group_id`, set this field to `product_group`.',
type: 'string',
choices: [
{ label: 'product', value: 'product' },
{ label: 'product_group', value: 'product_group' }
],
default: 'product'
},
currency: {
label: 'Currency',
type: 'string',
description: 'Currency for the value specified as ISO 4217 code.',
default: {
'@path': '$.properties.currency'
}
},
value: {
label: 'Value',
type: 'number',
description: 'Value of the order or items sold.',
default: {
'@if': {
exists: { '@path': '$.properties.value' },
then: { '@path': '$.properties.value' },
else: { '@path': '$.properties.revenue' }
}
}
},
description: {
label: 'Description',
type: 'string',
description: 'A string description of the web event.'
},
query: {
label: 'Query',
type: 'string',
description: 'The text string that was searched for.',
default: {
'@path': '$.properties.query'
}
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,17 @@ const productProperties = {
quantity: {
'@path': '$.quantity'
},
content_type: {
content_category: {
'@path': '$.category'
},
content_id: {
'@path': '$.product_id'
},
content_name: {
'@path': '$.name'
},
brand: {
'@path': '$.brand'
}
}

Expand Down Expand Up @@ -57,16 +63,66 @@ export const destination: BrowserDestinationDefinition<Settings, TikTokPixel> =
slug: 'actions-tiktok-pixel',
mode: 'device',
presets: [
{
name: 'Complete Payment',
subscribe: 'event = "Order Completed"',
partnerAction: 'reportWebEvent',
mapping: {
...multiProductContents,
event: 'CompletePayment'
},
type: 'automatic'
},
{
name: 'Contact',
subscribe: 'event = "Callback Started"',
partnerAction: 'reportWebEvent',
mapping: {
...defaultValues(reportWebEvent.fields),
event: 'Contact'
},
type: 'automatic'
},
{
name: 'Subscribe',
subscribe: 'event = "Subscription Created"',
partnerAction: 'reportWebEvent',
mapping: {
...defaultValues(reportWebEvent.fields),
event: 'Subscribe'
},
type: 'automatic'
},
{
name: 'Submit Form',
subscribe: 'event = "Form Submitted"',
partnerAction: 'reportWebEvent',
mapping: {
...defaultValues(reportWebEvent.fields),
event: 'SubmitForm'
},
type: 'automatic'
},
{
name: 'View Content',
subscribe: 'type="page"',
subscribe: 'event = "Product Viewed"',
partnerAction: 'reportWebEvent',
mapping: {
...singleProductContents,
event: 'ViewContent'
},
type: 'automatic'
},
{
name: 'Click Button',
subscribe: 'event = "Product Clicked"',
partnerAction: 'reportWebEvent',
mapping: {
...singleProductContents,
event: 'ClickButton'
},
type: 'automatic'
},
{
name: 'Search',
subscribe: 'event = "Products Searched"',
Expand Down Expand Up @@ -119,13 +175,33 @@ export const destination: BrowserDestinationDefinition<Settings, TikTokPixel> =
},
{
name: 'Place an Order',
subscribe: 'event = "Order Completed"',
subscribe: 'event = "Order Placed"',
partnerAction: 'reportWebEvent',
mapping: {
...multiProductContents,
event: 'PlaceAnOrder'
},
type: 'automatic'
},
{
name: 'Download',
subscribe: 'event = "Download Link Clicked"',
partnerAction: 'reportWebEvent',
mapping: {
...defaultValues(reportWebEvent.fields),
event: 'Download'
},
type: 'automatic'
},
{
name: 'Complete Registration',
subscribe: 'event = "Signed Up"',
partnerAction: 'reportWebEvent',
mapping: {
...defaultValues(reportWebEvent.fields),
event: 'CompleteRegistration'
},
type: 'automatic'
}
],
settings: {
Expand All @@ -136,16 +212,24 @@ export const destination: BrowserDestinationDefinition<Settings, TikTokPixel> =
"Your TikTok Pixel ID. Please see TikTok's [Pixel documentation](https://ads.tiktok.com/marketing_api/docs?id=1739583652957185) for information on how to find this value.",
required: true
},
useExistingPixel: {
label: 'Use Existing Pixel',
ldu: {
label: 'Limited Data Use',
type: 'boolean',
description:
'Important! Changing this setting may block data collection to Segment if not done correctly. Select "true" to use an existing TikTok Pixel which is already installed on your website. The Pixel MUST be installed on your website when this is set to "true" or all data collection to Segment may fail.'
'In order to help facilitate advertiser\'s compliance with the right to opt-out of sale and sharing of personal data under certain U.S. state privacy laws, TikTok offers a Limited Data Use ("LDU") feature. For more information, please refer to TikTok\'s [documentation page](https://business-api.tiktok.com/portal/docs?id=1770092377990145).'
},
useExistingPixel: {
// TODO: HOW TO DELETE (reusing will not include Segment Partner name)
label: '[Deprecated]Use Existing Pixel',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
label: '[Deprecated]Use Existing Pixel',
label: '[Deprecated] Use Existing Pixel',

type: 'boolean',
default: false,
required: false,
description: 'Deprecated. Please do not provide any value.'
}
jae-rhee-tiktok marked this conversation as resolved.
Show resolved Hide resolved
},
initialize: async ({ settings }, deps) => {
if (!settings.useExistingPixel) {
initScript(settings.pixelCode)
initScript(settings)
}
await deps.resolveWhen(() => window.ttq != null, 100)
return window.ttq
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* eslint-disable */
// @ts-nocheck
export function initScript(pixelCode) {
export function initScript(settings) {
!(function (w, d, t) {
w.TiktokAnalyticsObject = t
var ttq = (w[t] = w[t] || [])
Expand Down Expand Up @@ -44,7 +44,9 @@ export function initScript(pixelCode) {
a.parentNode.insertBefore(o, a)
})

ttq.load(pixelCode)
ttq.load(settings.pixelCode, {
limited_data_use: settings.ldu ? settings.ldu : false
})
ttq.page()
})(window, document, 'ttq')
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,8 @@ export function formatPhone(phone: string | undefined): string | undefined {
formattedPhone = formattedPhone.substring(0, 15)
return formattedPhone
}

export function handleArrayInput(array: string[] | undefined): string {
if (!array) return ''
return array[0]
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we also handle the case where 'array' is empty?
Should we also handle the case where array is a single string? i.e not an array?
Is it intentional that only the first item from the array is being forwarded on to TikTok?