Skip to content

Commit

Permalink
[STRATCONN-3376] Add phone number to TikTok Audiences (#1730)
Browse files Browse the repository at this point in the history
* Add phone number

* Fix unit tests

* Hide enable batching field + adjust names
  • Loading branch information
maryamsharif authored Nov 29, 2023
1 parent 6fc66be commit ce3c082
Show file tree
Hide file tree
Showing 14 changed files with 221 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ const event = createTestEvent({
advertisingId: ADVERTISING_ID
},
traits: {
email: '[email protected]'
email: '[email protected]',
phone: '1234567890'
},
personas: {
audience_settings: {
Expand All @@ -42,7 +43,7 @@ const event = createTestEvent({
})

const updateUsersRequestBody = {
id_schema: ['EMAIL_SHA256', 'IDFA_SHA256'],
id_schema: ['EMAIL_SHA256', 'PHONE_SHA256', 'IDFA_SHA256'],
advertiser_ids: [ADVERTISER_ID],
action: 'add',
batch_data: [
Expand All @@ -51,6 +52,10 @@ const updateUsersRequestBody = {
id: '584c4423c421df49955759498a71495aba49b8780eb9387dff333b6f0982c777',
audience_ids: [EXTERNAL_AUDIENCE_ID]
},
{
id: 'c775e7b757ede630cd0aa1113bd102661ab38829ca52a6422ab782862f268646',
audience_ids: [EXTERNAL_AUDIENCE_ID]
},
{
id: '0315b4020af3eccab7706679580ac87a710d82970733b8719e70af9b57e7b9e6',
audience_ids: [EXTERNAL_AUDIENCE_ID]
Expand All @@ -74,6 +79,9 @@ describe('TiktokAudiences.addToAudience', () => {
})

expect(r[0].status).toEqual(200)
expect(r[0].options.body).toMatchInlineSnapshot(
`"{\\"advertiser_ids\\":[\\"123\\"],\\"action\\":\\"add\\",\\"id_schema\\":[\\"EMAIL_SHA256\\",\\"PHONE_SHA256\\",\\"IDFA_SHA256\\"],\\"batch_data\\":[[{\\"id\\":\\"584c4423c421df49955759498a71495aba49b8780eb9387dff333b6f0982c777\\",\\"audience_ids\\":[\\"12345\\"]},{\\"id\\":\\"c775e7b757ede630cd0aa1113bd102661ab38829ca52a6422ab782862f268646\\",\\"audience_ids\\":[\\"12345\\"]},{\\"id\\":\\"0315b4020af3eccab7706679580ac87a710d82970733b8719e70af9b57e7b9e6\\",\\"audience_ids\\":[\\"12345\\"]}]]}"`
)
})

it('should normalize and hash emails correctly', async () => {
Expand Down Expand Up @@ -101,7 +109,8 @@ describe('TiktokAudiences.addToAudience', () => {
useDefaultMappings: true,
auth,
mapping: {
send_advertising_id: false
send_advertising_id: false,
send_phone: false
}
})

Expand All @@ -110,6 +119,39 @@ describe('TiktokAudiences.addToAudience', () => {
)
})

it('should normalize and hash phone correctly', async () => {
nock(`${BASE_URL}${TIKTOK_API_VERSION}`)
.post('/segment/mapping/', {
advertiser_ids: ['123'],
action: 'add',
id_schema: ['PHONE_SHA256'],
batch_data: [
[
{
id: 'c775e7b757ede630cd0aa1113bd102661ab38829ca52a6422ab782862f268646',
audience_ids: [EXTERNAL_AUDIENCE_ID]
}
]
]
})
.reply(200)

const responses = await testDestination.testAction('addToAudience', {
event,
settings: {
advertiser_ids: ['123']
},
useDefaultMappings: true,
auth,
mapping: {
send_advertising_id: false,
send_email: false
}
})

expect(responses[0].options.body).toMatchInlineSnapshot()
})

it('should fail if an audience id is invalid', async () => {
const anotherEvent = createTestEvent({
event: 'Audience Entered',
Expand All @@ -122,7 +164,8 @@ describe('TiktokAudiences.addToAudience', () => {
advertisingId: ADVERTISING_ID
},
traits: {
email: '[email protected]'
email: '[email protected]',
phone: '1234567890'
},
personas: {
audience_settings: {
Expand All @@ -136,7 +179,7 @@ describe('TiktokAudiences.addToAudience', () => {

nock(`${BASE_URL}${TIKTOK_API_VERSION}/segment/mapping/`)
.post(/.*/, {
id_schema: ['EMAIL_SHA256', 'IDFA_SHA256'],
id_schema: ['EMAIL_SHA256', 'PHONE_SHA256', 'IDFA_SHA256'],
advertiser_ids: [ADVERTISER_ID],
action: 'add',
batch_data: [
Expand All @@ -145,6 +188,10 @@ describe('TiktokAudiences.addToAudience', () => {
id: '584c4423c421df49955759498a71495aba49b8780eb9387dff333b6f0982c777',
audience_ids: ['THIS_ISNT_REAL']
},
{
id: 'c775e7b757ede630cd0aa1113bd102661ab38829ca52a6422ab782862f268646',
audience_ids: ['THIS_ISNT_REAL']
},
{
id: '0315b4020af3eccab7706679580ac87a710d82970733b8719e70af9b57e7b9e6',
audience_ids: ['THIS_ISNT_REAL']
Expand Down Expand Up @@ -182,10 +229,11 @@ describe('TiktokAudiences.addToAudience', () => {
selected_advertiser_id: '123',
audience_id: '123456',
send_email: false,
send_advertising_id: false
send_advertising_id: false,
send_phone: false
}
})
).rejects.toThrow('At least one of `Send Email`, or `Send Advertising ID` must be set to `true`.')
).rejects.toThrow('At least one of `Send Email`, `Send Phone` or `Send Advertising ID` must be set to `true`.')
})
it('should fail if email and/or advertising_id is not in the payload', async () => {
nock(`${BASE_URL}${TIKTOK_API_VERSION}/segment/mapping/`).post(/.*/, updateUsersRequestBody).reply(400)
Expand Down

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 @@ -5,7 +5,9 @@ import { processPayload } from '../functions'
import {
email,
advertising_id,
phone,
send_email,
send_phone,
send_advertising_id,
event_name,
enable_batching,
Expand All @@ -19,8 +21,10 @@ const action: ActionDefinition<Settings, Payload, AudienceSettings> = {
defaultSubscription: 'event = "Audience Entered"',
fields: {
email: { ...email },
phone: { ...phone },
advertising_id: { ...advertising_id },
send_email: { ...send_email },
send_phone: { ...send_phone },
send_advertising_id: { ...send_advertising_id },
event_name: { ...event_name },
enable_batching: { ...enable_batching },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,21 +26,26 @@ const event = createTestEvent({
advertisingId: '123'
},
traits: {
email: '[email protected]'
email: '[email protected]',
phone: '1234567890'
}
}
})

const updateUsersRequestBody = {
advertiser_ids: ['123'],
action: 'add',
id_schema: ['EMAIL_SHA256', 'IDFA_SHA256'],
id_schema: ['EMAIL_SHA256', 'PHONE_SHA256', 'IDFA_SHA256'],
batch_data: [
[
{
id: '584c4423c421df49955759498a71495aba49b8780eb9387dff333b6f0982c777',
audience_ids: ['1234345']
},
{
id: 'c775e7b757ede630cd0aa1113bd102661ab38829ca52a6422ab782862f268646',
audience_ids: ['1234345']
},
{
id: 'a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3',
audience_ids: ['1234345']
Expand Down Expand Up @@ -94,14 +99,50 @@ describe('TiktokAudiences.addUser', () => {
mapping: {
selected_advertiser_id: '123',
audience_id: '1234345',
send_advertising_id: false
send_advertising_id: false,
send_phone: false
}
})
expect(responses[0].options.body).toMatchInlineSnapshot(
`"{\\"advertiser_ids\\":[\\"123\\"],\\"action\\":\\"add\\",\\"id_schema\\":[\\"EMAIL_SHA256\\"],\\"batch_data\\":[[{\\"id\\":\\"584c4423c421df49955759498a71495aba49b8780eb9387dff333b6f0982c777\\",\\"audience_ids\\":[\\"1234345\\"]}]]}"`
)
})

it('should normalize and hash phone correctly', async () => {
nock(`${BASE_URL}${TIKTOK_API_VERSION}/segment/mapping/`)
.post(/.*/, {
advertiser_ids: ['123'],
action: 'add',
id_schema: ['PHONE_SHA256'],
batch_data: [
[
{
id: 'c775e7b757ede630cd0aa1113bd102661ab38829ca52a6422ab782862f268646',
audience_ids: ['1234345']
}
]
]
})
.reply(200)
const responses = await testDestination.testAction('addUser', {
event,
settings: {
advertiser_ids: ['123']
},
useDefaultMappings: true,
auth,
mapping: {
selected_advertiser_id: '123',
audience_id: '1234345',
send_advertising_id: false,
send_email: false
}
})
expect(responses[0].options.body).toMatchInlineSnapshot(
`"{\\"advertiser_ids\\":[\\"123\\"],\\"action\\":\\"add\\",\\"id_schema\\":[\\"PHONE_SHA256\\"],\\"batch_data\\":[[{\\"id\\":\\"c775e7b757ede630cd0aa1113bd102661ab38829ca52a6422ab782862f268646\\",\\"audience_ids\\":[\\"1234345\\"]}]]}"`
)
})

it('should fail if an audience id is invalid', async () => {
nock(`${BASE_URL}${TIKTOK_API_VERSION}/segment/mapping/`).post(/.*/, updateUsersRequestBody).reply(400)

Expand Down Expand Up @@ -136,10 +177,11 @@ describe('TiktokAudiences.addUser', () => {
selected_advertiser_id: '123',
audience_id: '123456',
send_email: false,
send_advertising_id: false
send_advertising_id: false,
send_phone: false
}
})
).rejects.toThrow('At least one of `Send Email`, or `Send Advertising ID` must be set to `true`.')
).rejects.toThrow('At least one of `Send Email`, `Send Phone` or `Send Advertising ID` must be set to `true`.')
})
it('should fail if email and/or advertising_id is not in the payload', async () => {
nock(`${BASE_URL}${TIKTOK_API_VERSION}/segment/mapping/`).post(/.*/, updateUsersRequestBody).reply(400)
Expand All @@ -159,7 +201,8 @@ describe('TiktokAudiences.addUser', () => {
selected_advertiser_id: '123',
audience_id: 'personas_test_audience',
send_email: true,
send_advertising_id: true
send_advertising_id: true,
send_phone: true
}
})
).rejects.toThrowError('At least one of Email Id or Advertising ID must be provided.')
Expand Down

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 @@ -6,8 +6,10 @@ import {
selected_advertiser_id,
audience_id,
email,
phone,
advertising_id,
send_email,
send_phone,
send_advertising_id,
event_name,
enable_batching
Expand All @@ -26,8 +28,10 @@ const action: ActionDefinition<Settings, Payload> = {
selected_advertiser_id: { ...selected_advertiser_id },
audience_id: { ...audience_id },
email: { ...email },
phone: { ...phone },
advertising_id: { ...advertising_id },
send_email: { ...send_email },
send_phone: { ...send_phone },
send_advertising_id: { ...send_advertising_id },
event_name: { ...event_name },
enable_batching: { ...enable_batching }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,13 @@ export async function createAudience(
}

export function validate(payloads: GenericPayload[]): void {
if (payloads[0].send_email === false && payloads[0].send_advertising_id === false) {
if (
payloads[0].send_email === false &&
payloads[0].send_advertising_id === false &&
payloads[0].send_phone === false
) {
throw new IntegrationError(
'At least one of `Send Email`, or `Send Advertising ID` must be set to `true`.',
'At least one of `Send Email`, `Send Phone` or `Send Advertising ID` must be set to `true`.',
'INVALID_SETTINGS',
400
)
Expand All @@ -85,6 +89,9 @@ export function getIDSchema(payload: GenericPayload): string[] {
if (payload.send_email === true) {
id_schema.push('EMAIL_SHA256')
}
if (payload.send_phone === true) {
id_schema.push('PHONE_SHA256')
}
if (payload.send_advertising_id === true) {
id_schema.push('IDFA_SHA256')
}
Expand Down Expand Up @@ -127,6 +134,17 @@ export function extractUsers(payloads: GenericPayload[]): {}[][] {
user_ids.push(email_id)
}

if (payload.send_phone === true) {
let phone_id = {}
if (payload.phone) {
phone_id = {
id: createHash('sha256').update(payload.phone).digest('hex'),
audience_ids: [external_audience_id]
}
}
user_ids.push(phone_id)
}

if (payload.send_advertising_id === true) {
let advertising_id = {}
if (payload.advertising_id) {
Expand Down
Loading

0 comments on commit ce3c082

Please sign in to comment.