-
Notifications
You must be signed in to change notification settings - Fork 28
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
adding sift custom destination function (#34)
* First sift push * update readme + prettier handler * Add Sift Decisions, WF, and update function names. * added changes * Added support for multiple sift response types Co-authored-by: Ju Hae Lee <[email protected]> Co-authored-by: Sophie Saouma <[email protected]>
- Loading branch information
1 parent
3758d7c
commit 72c80c8
Showing
2 changed files
with
164 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
# Sift Custom Destination Function | ||
This example shows how to set up a custom destination function with [Sift](https://sift.com/), a solution that helps you prevent all types of online fraud and abuse. The destination not only sends events to Sift, but also takes the results from Sift and attaches the metric to a user's profile using the `identify` call. | ||
|
||
## Setup | ||
- [ ] Create a [HTTP Source](https://segment.com/docs/connections/sources/catalog/libraries/server/http-api/#http%20tracking%20api) | ||
- [ ] Grab the REST API Key from Sift in your account | ||
|
||
## How to use | ||
|
||
Copy the `handler.js` code in this directory to your destination function | ||
|
||
Make the necessary modifications in the `handler.js` to map your Segment data. | ||
|
||
Replace the first line with your Segment write key that you generated from creating an HTTP Source | ||
|
||
## Maintainers | ||
[@shyaankhan](https://github.com/shyaankhan) Segment | ||
[@ssaouma](https://github.com/ssaouma) Sift | ||
[@juhaelee](https://github.com/juhaelee) Segment |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
// Segment & Sift | ||
const SEGMENT_WRITE_KEY = ''; | ||
const siftEndpoint = 'https://api.sift.com/v205/events'; | ||
const endpointScore = siftEndpoint + '?return_score=true'; | ||
const endpointWorkflow = siftEndpoint + '?return_workflow_status=true'; | ||
|
||
async function addScores(fields, res) { | ||
if (res.status == 0) { | ||
var scoreBody = { | ||
userId: fields.$user_id, | ||
traits: { | ||
contentAbuseScore: res.score_response.scores.content_abuse.score, | ||
paymentAbuseScore: res.score_response.scores.payment_abuse.score | ||
} | ||
}; | ||
|
||
const request = await fetch('https://api.segment.io/v1/identify', { | ||
body: JSON.stringify(scoreBody), | ||
headers: new Headers({ | ||
Authorization: 'Basic ' + btoa(SEGMENT_WRITE_KEY + ':'), | ||
'Content-Type': 'application/json' | ||
}), | ||
method: 'post' | ||
}); | ||
|
||
return request.json(); | ||
} | ||
} | ||
|
||
async function addDecisions(fields, res) { | ||
var decisionBody = { | ||
userId: fields.$user_id, | ||
traits: { | ||
contentAbuseDecisions: | ||
res.score_response.workflow_statuses[0].history[0].config.decision_id, | ||
paymentAbuseDecisions: | ||
res.score_response.workflow_statuses[0].history[0].config.decision_id | ||
} | ||
}; | ||
|
||
const request = await fetch('https://api.segment.io/v1/identify', { | ||
body: JSON.stringify(decisionBody), | ||
headers: new Headers({ | ||
Authorization: 'Basic ' + btoa(SEGMENT_WRITE_KEY + ':'), | ||
'Content-Type': 'application/json' | ||
}), | ||
method: 'post' | ||
}); | ||
|
||
return request.json(); | ||
} | ||
|
||
function getUrl(type) { | ||
if (type == 'SCORE') { | ||
return endpointScore; | ||
} else if (type == 'WORKFLOW') { | ||
return endpointWorkflow; | ||
} else { | ||
return siftEndpoint; | ||
} | ||
} | ||
|
||
async function siftEventCall(fields, type) { | ||
const res = await fetch(getUrl(type), { | ||
body: JSON.stringify(fields), | ||
headers: { 'Content-Type': 'application/json' }, | ||
method: 'post' | ||
}); | ||
|
||
const siftResponse = await res.json(); | ||
|
||
if (siftResponse.status <= 0) { | ||
// Please implement conditions for retries. | ||
} else if (siftResponse.status >= 0) { | ||
throw new InvalidEventPayload(siftResponse.error_message); | ||
} | ||
|
||
var response; | ||
|
||
if (type == 'SCORE') { | ||
response = await addScores(fields, siftResponse); | ||
} else if (type == 'WORKFLOW') { | ||
response = await addDecisions(fields, siftResponse); | ||
} | ||
|
||
return response; | ||
} | ||
|
||
async function onTrack(event, settings) { | ||
var fields = {}; | ||
// Depending on when you want to call for a score, set the appropriate endpoint to hit. | ||
if (event.event == 'Signed Up') { | ||
fields = { | ||
$type: '$create_account', | ||
$user_id: event.userId, | ||
$name: event.properties.name, | ||
$user_email: event.properties.email, | ||
$ip: event.context.ip, | ||
$phone: event.properties.phone, | ||
$browser: { | ||
$user_agent: event.context.userAgent | ||
}, | ||
$api_key: settings.apiKey | ||
}; | ||
|
||
return siftEventCall(fields, 'REGULAR'); | ||
} else if (event.event == 'Signed In') { | ||
fields = { | ||
$type: '$login', | ||
$login_status: '$success', | ||
$user_id: event.userId, | ||
$username: event.properties.username, | ||
$ip: event.context.ip, | ||
$browser: { | ||
$user_agent: event.context.userAgent | ||
}, | ||
$api_key: settings.apiKey | ||
}; | ||
|
||
return siftEventCall(fields, 'REGULAR'); | ||
} else { | ||
return null; | ||
} | ||
} | ||
|
||
async function onIdentify(event, settings) { | ||
// Depending on when you want to call for a score, set the appropriate endpoint to hit. | ||
|
||
if (!event.userId) return; | ||
|
||
var fields = { | ||
$type: '$update_account', | ||
$user_id: event.userId, | ||
$name: event.traits.name, | ||
$user_email: event.traits.email, | ||
$ip: event.context.ip, | ||
$phone: event.traits.phone, | ||
$browser: { | ||
$user_agent: event.context.userAgent | ||
}, | ||
$api_key: settings.apiKey | ||
}; | ||
|
||
return siftEventCall(fields, endpoint); | ||
} |