Skip to content

Commit

Permalink
Merge pull request #2 from mparticle-integrations/feat/initialization
Browse files Browse the repository at this point in the history
feat: initialize ID5 SDK and access/store the ID5 ID
  • Loading branch information
SbDove authored Oct 10, 2024
2 parents 2c5c93d + a49ce15 commit 5e67b8d
Show file tree
Hide file tree
Showing 13 changed files with 443 additions and 287 deletions.
23 changes: 13 additions & 10 deletions .github/workflows/reusable-workflows.yml
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
name: Reusable Workflows

on:
pull_request:
pull_request:

jobs:
pr-branch-check-name:
name: Check PR for semantic branch name
uses: mParticle/mparticle-workflows/.github/workflows/pr-branch-check-name.yml@stable
pr-title-check:
name: Check PR for semantic title
uses: mParticle/mparticle-workflows/.github/workflows/pr-title-check.yml@stable
pr-branch-target-gitflow:
name: Check PR for semantic target branch
uses: mParticle/mparticle-workflows/.github/workflows/pr-branch-target-gitflow.yml@stable
web-kit-pull-request:
name: Run Web Kit PR Workflow
uses: mParticle/mparticle-workflows/.github/workflows/web-kit-pull-request.yml@stable
pr-branch-check-name:
name: Check PR for semantic branch name
uses: mParticle/mparticle-workflows/.github/workflows/pr-branch-check-name.yml@stable
pr-title-check:
name: Check PR for semantic title
uses: mParticle/mparticle-workflows/.github/workflows/pr-title-check.yml@stable
pr-branch-target-gitflow:
name: Check PR for semantic target branch
uses: mParticle/mparticle-workflows/.github/workflows/pr-branch-target-gitflow.yml@stable
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
node_modules/
test/test-bundle.js
.DS_Store
test/end-to-end-testapp/compilation.js
test/end-to-end-testapp/build/compilation.js
dist/
8 changes: 8 additions & 0 deletions package-lock.json

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

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"@semantic-release/exec": "^5.0.0",
"@semantic-release/git": "^9.0.0",
"chai": "^4.2.0",
"crypto-js": "^4.2.0",
"eslint": "^7.25.0",
"eslint-config-prettier": "9.1.0",
"karma": "^5.1.0",
Expand Down
2 changes: 1 addition & 1 deletion src/commerce-handler.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ function CommerceHandler(common) {
this.common = common || {};
}

CommerceHandler.prototype.logCommerceEvent = function(event) {
CommerceHandler.prototype.logCommerceEvent = function() {
/*
Sample ecommerce event schema:
{
Expand Down
102 changes: 101 additions & 1 deletion src/common.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,107 @@
var SHA256 = require('crypto-js/sha256');
function Common() {}

Common.prototype.exampleMethod = function () {
return 'I am an example';
}

module.exports = Common;
Common.prototype.logId5Id = function (id5Id) {
//Checks and saves ID5 ID if it is new
if (id5Id !== this.id5Id) {
this.id5Id = id5Id;
this.id5IdSent = false
}

//Sets user attribute if ID is unsent.
//This function will be updated once the decryption architecture is finalized.
//TO-DO: Log the ID5 ID to correct location

};

Common.prototype.buildPartnerData = function (mParticleUser) {
var pdKeys = {};
var userIdentities = mParticleUser.getUserIdentities();

var email = this.normalizeEmail(userIdentities.userIdentities['email']);
var phone = this.normalizePhone(userIdentities.userIdentities['mobile_number']);

if (!email && !phone) {
return null;
}

if (email) {
pdKeys[1] = SHA256(email);
}

if (phone) {
pdKeys[2]= SHA256(phone);
}

var pdRaw = Object.keys(pdKeys).map(function(key){
return key + '=' + pdKeys[key]
}).join('&');

return btoa(pdRaw);
}

Common.prototype.normalizeEmail = function(email) {
if (!email || !this.validateEmail(email)) {
return null;
}
var parts = email.split("@")
var charactersToRemove = ['+', '.']

if (parts[1] != 'gmail.com') {
return email;
}

parts[0]= this.replace(parts[0], charactersToRemove);

return parts.join('@');
}

Common.prototype.normalizePhone = function(phone) {
if (!phone) {
return null;
}
var charactersToRemove = [' ', '-', '(', ')']
var normalizedPhone = this.replace(phone, charactersToRemove);

if (normalizedPhone[0] !== '+') {
normalizedPhone = '+' + normalizedPhone
}

if (!this.validatePhone(normalizedPhone)) {
return null;
}
return normalizedPhone;
}

Common.prototype.replace = function(string, targets) {
var newString = '';
for(var i = 0; i < string.length; i++){
var char = string[i];
if (!targets.includes(char)){
newString += char
}
}
return newString.toLowerCase();
}

Common.prototype.validateEmail = function(email){
if (!email) {
return false;
}
var emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return emailRegex.test(email);
}

Common.prototype.validatePhone = function(phone) {
if (!phone){
return false;
}
var e164Regex = /^\+?[1-9]\d{1,14}$/;

return e164Regex.test(phone);
}
module.exports = Common;
6 changes: 3 additions & 3 deletions src/event-handler.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,15 @@ A non-ecommerce event has the following schema:
function EventHandler(common) {
this.common = common || {};
}
EventHandler.prototype.logEvent = function(event) {};
EventHandler.prototype.logError = function(event) {
EventHandler.prototype.logEvent = function() {};
EventHandler.prototype.logError = function() {
// The schema for a logError event is the same, but noteworthy differences are as follows:
// {
// EventAttributes: {m: 'name of error passed into MP', s: "Error", t: 'stack trace in string form if applicable'},
// EventName: "Error"
// }
};
EventHandler.prototype.logPageView = function(event) {
EventHandler.prototype.logPageView = function() {
/* The schema for a logPagView event is the same, but noteworthy differences are as follows:
{
EventAttributes: {hostname: "www.google.com", title: 'Test Page'}, // These are event attributes only if no additional event attributes are explicitly provided to mParticle.logPageView(...)
Expand Down
50 changes: 30 additions & 20 deletions src/identity-handler.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,32 +21,42 @@ For more userIdentity types, see https://docs.mparticle.com/developers/sdk/web/i
function IdentityHandler(common) {
this.common = common || {};
}
IdentityHandler.prototype.onUserIdentified = function(mParticleUser) {};
IdentityHandler.prototype.onIdentifyComplete = function(
mParticleUser,
identityApiRequest
) {};
IdentityHandler.prototype.onUserIdentified = function() {};
IdentityHandler.prototype.onIdentifyComplete = function() {};

//Must re-initialize ID5 with partner identities(pd) in the config to collect an updated ID5 ID
IdentityHandler.prototype.onLoginComplete = function(
mParticleUser,
identityApiRequest
) {};
mParticleUser
) {
var partnerData = this.common.buildPartnerData(mParticleUser);

if (partnerData) {
var id5Instance = window.ID5.init({partnerId: this.common.partnerId, pd: partnerData})
var logId5Id = this.common.logId5Id;

id5Instance.onAvailable(function(status){
logId5Id(status.getUserId());
}.bind(logId5Id));
}
};

//Must re-initialize ID5 without partner identities (pd) in the config to revert to an anonymous ID5 ID
IdentityHandler.prototype.onLogoutComplete = function(
mParticleUser,
identityApiRequest
) {};
IdentityHandler.prototype.onModifyComplete = function(
mParticleUser,
identityApiRequest
) {};
) {
var id5Instance = window.ID5.init({partnerId: this.common.partnerId})
var logId5Id = this.common.logId5Id;

id5Instance.onAvailable(function(status){
logId5Id(status.getUserId());
}.bind(logId5Id));
};

IdentityHandler.prototype.onModifyComplete = function() {};

/* In previous versions of the mParticle web SDK, setting user identities on
kits is only reachable via the onSetUserIdentity method below. We recommend
filling out `onSetUserIdentity` for maximum compatibility
*/
IdentityHandler.prototype.onSetUserIdentity = function(
forwarderSettings,
id,
type
) {};
IdentityHandler.prototype.onSetUserIdentity = function() {};

module.exports = IdentityHandler;
44 changes: 25 additions & 19 deletions src/initialization.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,33 +9,39 @@ var initialization = {
userIdentities example: { 1: 'customerId', 2: 'facebookId', 7: '[email protected]' }
additional identityTypes can be found at https://github.com/mParticle/mparticle-sdk-javascript/blob/master-v2/src/types.js#L88-L101
*/
initForwarder: function(forwarderSettings, testMode, userAttributes, userIdentities, processEvent, eventQueue, isInitialized, common, appVersion, appName, customFlags, clientId) {
initForwarder: function(forwarderSettings, testMode, userAttributes, userIdentities, processEvent, eventQueue, isInitialized, common) {
/* `forwarderSettings` contains your SDK specific settings such as apiKey that your customer needs in order to initialize your SDK properly */

if (!testMode) {
/* Load your Web SDK here using a variant of your snippet from your readme that your customers would generally put into their <head> tags
Generally, our integrations create script tags and append them to the <head>. Please follow the following format as a guide:
*/
//ID5 docs on initialization can be found here: https://github.com/id5io/id5-api.js/blob/master/README.md
var id5Script = document.createElement('script');
id5Script.src = 'https://cdn.id5-sync.com/api/1.0/id5-api.js';
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(id5Script);

// var clientScript = document.createElement('script');
// clientScript.type = 'text/javascript';
// clientScript.async = true;
// clientScript.src = 'https://www.clientscript.com/static/clientSDK.js'; // <---- Update this to be your script
// (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(clientScript);
// clientScript.onload = function() {
// if (clientSDKObject && eventQueue.length > 0) {
// // Process any events that may have been queued up while forwarder was being initialized.
// for (var i = 0; i < eventQueue.length; i++) {
// processEvent(eventQueue[i]);
// }
// // now that each queued event is processed, we empty the eventQueue
// eventQueue = [];
// }
// clientSDKObject.initialize(forwarderSettings.apiKey);
// };
common.id5Id = null;
common.id5IdSent = false;
common.partnerId = forwarderSettings.partnerId;

id5Script.onload = function() {
isInitialized = true;

var id5Instance = window.ID5.init({partnerId: common.partnerId})

id5Instance.onAvailable(function(status){
common.logId5Id(status.getUserId());
}.bind(common));
};
} else {
// For testing, you should fill out this section in order to ensure any required initialization calls are made,
// clientSDKObject.initialize(forwarderSettings.apiKey)
isInitialized = true;

var id5Instance = window.ID5.init({partnerId: common.partnerId})

id5Instance.onAvailable(function(status){
common.logId5Id(status.getUserId());
}.bind(common));
}
}
};
Expand Down
6 changes: 3 additions & 3 deletions src/session-handler.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
var sessionHandler = {
onSessionStart: function(event) {
onSessionStart: function() {

},
onSessionEnd: function(event) {
onSessionEnd: function() {

}
};
Expand Down
17 changes: 3 additions & 14 deletions src/user-attribute-handler.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,8 @@ For any additional methods, see http://docs.mparticle.com/developers/sdk/javascr
function UserAttributeHandler(common) {
this.common = common || {};
}
UserAttributeHandler.prototype.onRemoveUserAttribute = function(
key,
mParticleUser
) {};
UserAttributeHandler.prototype.onSetUserAttribute = function(
key,
value,
mParticleUser
) {};
UserAttributeHandler.prototype.onConsentStateUpdated = function(
oldState,
newState,
mParticleUser
) {};
UserAttributeHandler.prototype.onRemoveUserAttribute = function() {};
UserAttributeHandler.prototype.onSetUserAttribute = function() {};
UserAttributeHandler.prototype.onConsentStateUpdated = function() {};

module.exports = UserAttributeHandler;
2 changes: 1 addition & 1 deletion test/end-to-end-testapp/settings.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
var SDKsettings = {
apiKey: 'testAPIKey'
partnerId: 1234
/* fill in SDKsettings with any particular settings or options your sdk requires in order to
initialize, this may be apiKey, projectId, primaryCustomerType, etc. These are passed
into the src/initialization.js file as the
Expand Down
Loading

0 comments on commit 5e67b8d

Please sign in to comment.