Profiles SDK
The Profiles JavaScript SDK can be used to identify, authenticate, access, create, and update profiles for visitors to a website or mobile app; functions can also get segments for the visitor, based on criteria defined in Profiles > Segments in the Wyng platform.
This SDK wraps the Profiles API.
Installation
To use the Profiles SDK add a script tag to your web site:
<script src="https://mx.wyng.com/js/profiles-sdk.js"></script>
After this the SDK will be available as window.wyng.profiles
.
You must initialize the SDK before using any functions. Initialization requires a Public Access Token for your Data Model, which can be found in Profiles > For Developers in Wyng.
window.wyng.profiles.init('public_access_token');
Usage
identify
A current website user may be matched to a profile using one or more IDs, which we
refer to as the identity context for the Profiles SDK. For example, the Profiles SDK
always adds an auto-generated anonymous visitor ID (uid
in browser localStorage
) to
the identity context, to identify returning anonymous visitors. Additionally, during a
user session. you may have other available user identifiers such as an email address,
customer ID, or HTTP cookie ID.
Your Data Model in Wyng defines all the possible keys which you plan to use to identify users. At any time during a user session, call identify() to add one or more key fields to the identity context. This function does not call the API, but sets the context for subsequent API calls during this session.
Examples
To add a known email address for the current website visitor to the identity context:
window.wyng.profiles.identify('email', 'jane.smith@email.com');
To add multiple key fields to the identity context in one call. The example adds email: john.smith@email.com
and phone: 212-345-6789
. Subsequent SDK calls will match any profile with either of those keys or the default uid
.
window.wyng.profiles.identify({
email: 'jane.smith@email.com',
phone: '212-345-6789',
});
getProfileId
Using the key fields that have been set, there will be one profile that matches the user the best. getProfileId()
will return a Promise that resolves to the id of the profile that matches the user best.
If no matching Profile is found, an error will be thrown. Handling this error is important since certain other calls rely on there being a Profile.
Example
- Using promises
- Using await
window.wyng.profiles.getProfileId().then(
id => { console.log(id, 'My Profile ID'); }
).catch((e) => {
console.warn('Profile does not (yet) exist for this User');
});
try {
const id = await window.wyng.profiles.getProfileId();
console.log(id, 'My Profile ID');
} catch (error) {
console.warn('Profile does not (yet) exist for this User');
}
authenticate
A JWT can get generated to give temporary access to existing Profile data. Use the authenticate method to set this JWT in the SDK for usage when calling get()
or getProfile()
For instructions on how to generate a JWT see the profiles/<profile_id>/identify
endpoint in the consumer-service.
(The value used for the JWT in this example is a sample value. Do not use this value, use the value for the JWT that will be given at runtime)
window.wyng.profiles.authenticate(
'eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJ0ZG1faWQiOiI2MGY5YzFlNzM5NWVhMDAyMDJlYTM2ZjIiLCJwcm9maWxlX2lkIjoiNjFlODZlNmU5ZjU4YzBjZTVkZjcwNDhmIiwiaXNzIjoiY29uc3VtZXIiLCJpYXQiOjE2NDI2MjQ1NTMsImV4cCI6MTY0MjYyNDg1M30.eqOP8YRCcB9f3Za7Xu60wcdkmZCbw1ar10287gWU6nxOnMSMi0bd3ahAA6Au-aXhdsL8o9tWI-cso5AX_CAwDO_SZmYZfLAntokpODOU6td2UuPWeNcmFRHvDpeG5gFZyuCPmSRkGIuUi6vzehB6K5YnsLCCDyuWew0e7ib0a9gJU_E29YyQoUecblEY_KaVWkVKcg5Kdj58S6z2Dts8hQravVWSKjrSISkZ2IKDLpzym0B6IHWEYB8rFq01AroiUliRzj3Zm294hzVTsIUBr4UypTbrrnSnxn9H7Q5rAdLDc01deBgR6rAXnNK7fqUBVj-ARfAnp1fHdUtKHxZlUza4cJgI8Ykutld0JOLZCyIeXTr6EHBLB4n-6_ibDT6deMeTScmbXCijm4ubb891ul2GNpx8SNuU3pfzQLU2qLM5YJabaQBitwBUThFMzawpocTm0YvbwPLCnK9PS2sjdxxyGis5pswmk5gR6RnfxRNwPw0pbE0vVDtvrVUxgP44XSuAvrA2QNTkCB7Yr4j-Vhtkmt1mgecYq8tcanCHFv6lwYAA7hWRKvlTkApf2FccQEaWvbh1waRHvVFrZfCDZxOZMGxZzJ2NROcx8ur9Rv7-4LAvFQuQ6BUvK0Eod9ZulihlfaM4rM2k-gqiBEj1Epg9l4CiN85oltvzeza5oLY'
);
exchangeToken
When Identity Verification is successfully completed, the user receives a JWT from the verification service. This JWT can be exchanged for a Profile JWT to get full profile information.
Arguments:
Argument | Type | Description |
---|---|---|
jwt | string | The JWT to be exchanged for a Profile JWT. |
key_field | string | Id of the key field in the Data Model that matches with the verified identity field in the JWT that is to be exchanged, commonly either a phone number or email address. This field will be used to look up the Profile that matches the current user. |
expire_in | integer - optional | Number of seconds the Profile JWT should be valid for. (Default 1800) |
- Using promises
- Using await
window.wyng.profiles.exchangeToken(
'eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJlbWFpbCI6InJlbmUuc2Ftc29uKzIwMjIuMi43XzVAd3luZy5jb20iLCJleHBlcmllbmNlSWQiOiI2MGY5ZTU4ZWY3ZjZiOTAwMGU4M2YwMTMiLCJ2ZXJpZmllZCI6dHJ1ZSwiaXNzIjoidmVyaWZpY2F0aW9uLXNlcnZpY2UiLCJpYXQiOjE2NDQ0MjYyMTcsImV4cCI6MTY0NDQ0NzgxN30.mvqzBQyDsFokqc5jSKGa6_WOzbZExxaP75MfRBw2HekG0iCAfKwlIzAUCLdwaR_PbMjrz3LLzCRGL4k-KOS9bH3Q42Ya0Jj-wFxS8NicAbd4T6VJVcEm54CsfFPTBV0IKuuTmcKqH8n_mt6w5TgoQDsO8hbDqguNgHQ3qIOJrm6ox_wlV5UreBkGppHLH9_njwQmb7QoNN9yhMwjEQNqymvxjsdvj1ORspKowl0KPStM3N3KcdOcdDcOfd1SEaoEvAFQ-JE31hAJW5n39uMfbaRJQy-WcRViedyPO9ZiY71ajvP_roiYPbILNAiNMUtYIbSE3lHFX8k14u2zZcNF6sDdRFvGtG5oLJzu08RtrnusxwGsEU7hM10i5MIaFter5hYpV35sw3UjglnCK3I0vOIpth8TsnrO_kNifKQY1zCcbPbF1BUet3afviKskdwMeLEUAE_2CYd1jkXLDtnLPJY9xnVlxODa31LrV62uJYTj5eotnOMWn0sVEcaM7w5AMvBzZOdAzuTmGwsfwPpkhqKffCYX6krm3_xquhgurvXbFNTf6Ka87Q_3SjPYnUgsEjHOlpg3dqvUx1cJLcXwhwODqZTO9UQ4yNmEh9-8YrpAOZY5fWcZcr6kvMNGIL9Pyb9Ja754txHw-PXjmF1O68dWvq60YA_MAjymeJhBJv0',
'email'
).then(jwt => {
console.log(jwt);
// Call window.wyng.profiles.get() to get Private Profile Data
}).catch(error => console.error(error));
const jwt = await window.wyng.profiles.exchangeToken(
'eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJlbWFpbCI6InJlbmUuc2Ftc29uKzIwMjIuMi43XzVAd3luZy5jb20iLCJleHBlcmllbmNlSWQiOiI2MGY5ZTU4ZWY3ZjZiOTAwMGU4M2YwMTMiLCJ2ZXJpZmllZCI6dHJ1ZSwiaXNzIjoidmVyaWZpY2F0aW9uLXNlcnZpY2UiLCJpYXQiOjE2NDQ0MjYyMTcsImV4cCI6MTY0NDQ0NzgxN30.mvqzBQyDsFokqc5jSKGa6_WOzbZExxaP75MfRBw2HekG0iCAfKwlIzAUCLdwaR_PbMjrz3LLzCRGL4k-KOS9bH3Q42Ya0Jj-wFxS8NicAbd4T6VJVcEm54CsfFPTBV0IKuuTmcKqH8n_mt6w5TgoQDsO8hbDqguNgHQ3qIOJrm6ox_wlV5UreBkGppHLH9_njwQmb7QoNN9yhMwjEQNqymvxjsdvj1ORspKowl0KPStM3N3KcdOcdDcOfd1SEaoEvAFQ-JE31hAJW5n39uMfbaRJQy-WcRViedyPO9ZiY71ajvP_roiYPbILNAiNMUtYIbSE3lHFX8k14u2zZcNF6sDdRFvGtG5oLJzu08RtrnusxwGsEU7hM10i5MIaFter5hYpV35sw3UjglnCK3I0vOIpth8TsnrO_kNifKQY1zCcbPbF1BUet3afviKskdwMeLEUAE_2CYd1jkXLDtnLPJY9xnVlxODa31LrV62uJYTj5eotnOMWn0sVEcaM7w5AMvBzZOdAzuTmGwsfwPpkhqKffCYX6krm3_xquhgurvXbFNTf6Ka87Q_3SjPYnUgsEjHOlpg3dqvUx1cJLcXwhwODqZTO9UQ4yNmEh9-8YrpAOZY5fWcZcr6kvMNGIL9Pyb9Ja754txHw-PXjmF1O68dWvq60YA_MAjymeJhBJv0',
'email'
);
console.log(jwt);
// window.wyng.profiles.getProfile() will now return the full profile data
getProfile
The getProfile
method gets the full profile information from the Profiles endpoint. If authenticate
has been called, getProfile
will use the provided JWT to authenticate with the Profile endpoint, and getProfile will return both public and private data of the profile. If authenticate
did not get called, only the public data of the profile will be returned.
This method does not recalculate segments or modify the profile in any way, and does not update the Last Activity date (updated_at).
If the user does not have a Profile, an error is thrown. It is important to handle this error, because any first time visitor will not have a Profile, and if the error is not handled correctly, your code may not work as expected for those users.
Examples
- Using promises
- Using await
window.wyng.profiles.getProfile().then(
profile => {
console.log(profile);
}
).catch((e) => {
console.log('Profile does not exist');
});
try {
const profile = await window.wyng.profiles.getProfile();
console.log(profile);
} catch (error) {
console.warn('Profile does not (yet) exist for this User');
}
Potential output (public and private data):
{
"created_at": "2022-01-19T20:02:54.145000",
"parent_profiles":[],
"tdm_id": "60f9c1e7395ea00202ea36f2",
"updated_at": "2022-01-19T20:02:54.145000",
"segments":[],
"fields":{
"email":{
"updated": "2022-01-19T20:02:54.135000",
"value": "rene.samson+2022.1.19_1@wyng.com",
"created": "2022-01-19T20:02:54.135000"
},
"hair_color":{
"updated": "2022-01-19T20:02:54.135000",
"value": "Black",
"created": "2022-01-19T20:02:54.135000"
},
"skin_concerns":{
"updated": "2022-01-19T20:02:54.135000",
"value":[
"Eye Bags",
"Oily Skin"
],
"created": "2022-01-19T20:02:54.135000"
}
}
}
Other potential output (public data only):
{
"tdm_id": "60f9c1e7395ea00202ea36f2",
"segments":[],
}
get
The get method can get the values of the fields of the current Profile. In order to get this the authenticate method must have been called first to set the value of the JWT to be able to authenticate with the Profiles endpoint. If no JWT has been set before calling get, an empty object will be returned
Get will return a Promise to an object containing all fields in the Profile and their current value. If a field is not returned in the object, this means that it is not set:
- Using promises
- Using await
window.wyng.profiles.get().then(fields => {
console.log(fields);
});
const fields = await window.wyng.profiles.get();
console.log(fields);
Potential output:
{
email: "john.smith@email.com",
hair_color: "brown",
skin_concerns: [ "Eye Bags", "Oily Skin" ]
}
set
The set
method can set one or multiple Profile fields, and safe these changes to the Profile. Any key fields defined using the identify method will be used by the set method
It will return a Promise, which allows for actions to be performed after the changes have been saved or on error
It is important to ensure that the init
method has been called before calling set
.
Examples
To set one specific field.
In this example the field hair_color
is set to brown
window.wyng.profiles.set('hair_color', 'brown')
.then((result) => { console.log('Hair Color field successfully saved'); })
.catch((error) => { console.error('Error when saving Hair Color'); });
To set multiple fields in one call (in this example the field hair_color
is set to blond, and eye_color
to blue):
window.wyng.profiles.set({
hair_color: 'blond',
eye_color: 'blue',
});
compare
The compare
method accesses the /profiles/<profile_id>/compare?<field_id>=<field_value> endpoint to compare a field value for the current Profile.
compare
will return a Promise to an object containing the comparison result. When the trueCallback
and/or falseCallback
functions are provided and called, the Promise returned by compare
will be a Promise to the return value of the callback function that gets called.
Arguments:
Argument | Type | Description |
---|---|---|
field_id | string - required | The ID of the Data Model field that the check will be against |
value | string - required | The value to check for |
trueCallback | function - optional | Callback function that will be called when the comparison evaluates True |
falseCallback | function - optional | Callback function that will be called when the comparison evaluates False |
trueCallback
and falseCallback
are optional. Both functions will receive the following arguments: response
, field_id
, value
. Where response
is the response object from the API endpoint. Added to the object will be a profile_exists
flag, that will be false when the SDK found no matching Profile for the values currently set using identify. field_id
is the field_id value as passed in as the first argument to compare
. value
is the value as it was passed in as the second argument to compare
.
Examples
The compare
method can be called using the Promise that it returns, using await
, or using the callback functions. The callback funtions can be used in combination with the Promise, or await
. When using the callback functions, the return value of the callback function will be what is returned as the Promise.
For simplicity the examples below show the use of the compare
method with the trueCallback
and falseCallback
functions separately.
All of the examples will check the Profile if it has the hair_color
set to the value brown
.
- Using promises
- Using await
- Using Callback functions
window.wyng.profiles.compare('hair_color', 'brown').then(response => {
if (!response.profile_exists) {
console.log('Profile does not exist');
// Handle the case of a new Profile here
return;
}
if (!response.has_value) {
console.log('Profile does not have this field');
// Handle the case where the Profile does not have this fields set at all here
return;
}
if (!response.result) {
console.log('Field value on Profile does not match the value "brown"');
// Handle the case where the value does not match
return;
}
console.log('Field has value "brown"');
// Handle the case of matching value
});
const response = await window.wyng.profiles.compare('hair_color', 'brown');
if (!response.profile_exists) {
console.log('Profile does not exist');
// Handle the case of a new Profile here
} else if (!response.has_value) {
console.log('Profile does not have this field');
// Handle the case where the Profile does not have this fields set at all here
} else if (!response.result) {
console.log('Field value on Profile does not match the value "brown"');
// Handle the case where the value does not match
} else {
console.log('Field has value "brown"');
// Handle the case of matching value
}
function trueCallback(response, field_id, value) {
// Handle the case of a matching value
// field_id = 'hair_color';
// value = 'brown';
// response = {
// profile_exists: true,
// has_value: true,
// result: true
// };
console.log('Field has value "brown"');
return;
}
function falseCallback(response, field_id, value) {
if (!response.profile_exists) {
// Handle the case of a new Profile here
console.log('Profile does not exist');
return;
}
if (!response.has_value) {
// Handle the case where the Profile does not have this fields set at all here
console.log('Profile does not have this field');
return;
}
// Handle the case of a non-matching value
console.log('Field value on Profile does not match the value "brown"');
return;
}
window.wyng.profiles.compare('hair_color', 'brown', trueCallback, falseCallback);
setSource
When saving changes to the profile, the source of the changes can be captured. The source can be any string.
Use the setSource
method to modify the source.
If setSource
is not called, the URL of the current page, excluding URL parameters will be used as the source. To disable capturing a source set source to the boolean value false
, or call the disableSource()
method.
Examples
window.wyng.profiles.setSource('Setting the source to this value');
disableSource
To disable setting a source value altogether, use this method.
Examples
window.wyng.profiles.disableSource();
SET field types
SET fields can hold multiple values that can individually be added and removed. The SDK provides a few different ways to work with set field types.
set and prepareSet
The set method can be used to add and remove values from a SET field using the prepareSet helper method. prepareSet transforms values to be added and removed from a SET field to be passed in as the value to the set method. In this example the values 'baseball', and 'football' will be added to the field 'favorite_sports', and 'basketball', and 'hockey' will be removed
Examples
window.wyng.profiles.set(
'favorite_sports',
window.wyng.profiles.prepareSet({
baseball: true,
football: true,
basketball: false,
hockey: false,
})
);
Using the set method to update multiple is also possible:
window.wyng.profiles.set({
hair_color: 'blond',
favorite_sports: window.wyng.profiles.prepareSet({
baseball: true,
football: true,
basketball: false,
hockey: false,
}),
});
add
To add a value to a SET field, it is also possible to use the add
method. The add
method allows for a single value to be added to a single SET field
In the example the value baseball will be added to the field favorite_sports
add()
returns a Promise, which allows for actions to be performed after the value has been added to the SET field.
Example
window.wyng.profiles.add('favorite_sports', 'baseball');
remove
In addition to the add
method, there is a remove
method that allows for the removal of values from a SET field.
In the example the value basketball will be removed from the field favorite_sports
remove()
returns a Promise, which allows for actions to be performed after the value has been removed from the SET field.
Example
window.wyng.profiles.remove('favorite_sports', 'basketball');
Segments
Profiles can belong to segments. Use the following methods to see what segments a user belongs to, and to perform actions based on the segments the user belongs to.
getSegments
Get an array of segments that the profile belongs to. This method returns a Promise which resolves to an array of segment ID's
Calling this method will recalculate this profile's segments and update the Last Activity date (updated_at).
If the user does not have a Profile, an error will be thrown that can be caught. Alternativaly a separate call can be made to getProfileId()
to confirm that indeed the Profile does not exist.
Example
window.wyng.profiles.getSegments().then(segment_ids => {
console.log(segment_ids);
}).catch(error => {
console.error(error, 'Error retrieving segments. Most likely the error means that the user does not have a Profile');
// To check for sure that the error was because of a non existing profile do the following
window.wyng.profiles.getProfileId().then(id => {
console.log('Do not expect to get here. If you do, something else went wrong retrieving the segments');
}).catch(e => {
console.log('Indeed the Profile does not exist');
});
});
hasSegment
Wrapper around getSegments()
. This helper function will get the segments the profile belongs to, check if a specific segment is in the list of segments, call a callback function if it is, or call another callback function if it is not. If there is no profile found for the user, a third callback function, profileDoesNotExist, is called. The third argument (the callback function for when the profile does not belong to segment), and fourth argument (the callback function for when the profile does not exist) are optional
Example
function hasSegment(segment_id, segments) {
console.log('Profile belongs to segment ' + segment_id);
console.log('Profile belongs to the segments:', segments);
}
function doesNotHaveSegment(segment_id, segments) {
console.log('Profile does not belong to segment ' + segment_id);
console.log('Profile belongs to the segments:', segments);
}
function profileDoesNotExist() {
console.log('There is currently no Profile for this user, can not check Profile belongs to the segment');
}
window.wyng.profiles.hasSegment('segment_id_1234', hasSegment, doesNotHaveSegment, profileDoesNotExist);
doesNotHaveSegment
This helper method does the same as hasSegment()
, however instead of calling a callback function when the profile belongs to a segment, it does not have a callback function for when the profile belongs to a segment. It only calls a callback function if the profile does not belong to the segment, and one when the profile does not exist.
The callback function for when the Profile does not exist is optional
Example
function callbackFunction(segment_id, segments) {
console.log('Profile belongs to segment ' + segment_id);
console.log('Profile belongs to the segments:', segments);
}
function profileDoesNotExist() {
console.log('There is currently no Profile for this user, can not check Profile belongs to the segment');
}
window.wyng.profiles.doesNotHaveSegment('segment_id_1234', callbackFunction, profileDoesNotExist);