Comparing version 1.2.0 to 1.3.0
# Change Log | ||
All notable changes to this project will be documented in this file. | ||
## 1.3.0 (April 19, 2023) | ||
- Adds Profile, Events, Reports and Campaign API's. | ||
### 1.2.0 (September 13, 2021) | ||
@@ -5,0 +8,0 @@ |
@@ -1,32 +0,36 @@ | ||
const REGIONS = require('./regions'); | ||
const request = require('request'); | ||
const querystring = require('querystring'); | ||
const REGIONS = require("./regions"); | ||
const fetch = require("node-fetch"); | ||
const querystring = require("querystring"); | ||
const API_HOSTNAME = "api.clevertap.com"; | ||
API_VERSION = 1; | ||
const API_HOSTNAME = "api.clevertap.com"; | ||
const API_VERSION = 1; | ||
const CREATE = "create", | ||
ESTIMATE = "estimate", | ||
LIST = "list", | ||
RESULT = "result", | ||
STOP = "stop"; | ||
const CREATE = "create"; | ||
const ESTIMATE = "estimate"; | ||
const LIST = "list"; | ||
const RESULT = "result"; | ||
const STOP = "stop"; | ||
const TARGET_ACTIONS = [CREATE, ESTIMATE, LIST, RESULT, STOP]; | ||
const CleverTapAPI = function (CleverTapAccountId, CleverTapAccountPasscode, CleverTapAccountRegion) { | ||
if (!CleverTapAccountId) { | ||
throw new Error("Please provide a CleverTap Account Id"); | ||
} | ||
const CleverTapAPI = function ( | ||
CleverTapAccountId, | ||
CleverTapAccountPasscode, | ||
CleverTapAccountRegion | ||
) { | ||
if (!CleverTapAccountId) { | ||
throw new Error("Please provide a CleverTap Account Id"); | ||
} | ||
if (!CleverTapAccountPasscode) { | ||
throw new Error("Please provide a CleverTap Account Passcode"); | ||
} | ||
if (!CleverTapAccountPasscode) { | ||
throw new Error("Please provide a CleverTap Account Passcode"); | ||
} | ||
if (!REGIONS.regionIsValid(CleverTapAccountRegion)) { | ||
throw new Error("Please provide a valid CleverTap Account Region"); | ||
} | ||
if (!REGIONS.regionIsValid(CleverTapAccountRegion)) { | ||
throw new Error("Please provide a valid CleverTap Account Region"); | ||
} | ||
this.accountId = CleverTapAccountId; | ||
this.accountPasscode = CleverTapAccountPasscode; | ||
this.apiEndpoint = `https://${CleverTapAccountRegion}.${API_HOSTNAME}/${API_VERSION}`; | ||
this.accountId = CleverTapAccountId; | ||
this.accountPasscode = CleverTapAccountPasscode; | ||
this.apiEndpoint = `https://${CleverTapAccountRegion}.${API_HOSTNAME}/${API_VERSION}`; | ||
}; | ||
@@ -41,241 +45,356 @@ | ||
CleverTapAPI.prototype.upload = function(data, options, callback) { | ||
CleverTapAPI.prototype._call = function (endpoint, options, callback) { | ||
if (options.debug) { | ||
console.log( | ||
`CleverTap: calling endpoint ${endpoint} with options ${JSON.stringify( | ||
options | ||
)}` | ||
); | ||
} | ||
if (!data || data.length <= 0) { | ||
return []; | ||
} | ||
callback = callback || function (res) {}; | ||
var batchSize = 100, // default: API allows max 100 records per request | ||
totalRecords = data.length, | ||
completedRecords = 0, | ||
recordsBatchIdx = 0, | ||
responses = []; | ||
const headers = options.headers || {}; | ||
const url = `${this.apiEndpoint}/${endpoint}`; | ||
const method = options.method || "GET"; | ||
if (typeof(options) === 'function' || !options) { | ||
callback = options; | ||
options = {}; | ||
} | ||
// add the authentication headers | ||
headers["X-CleverTap-Account-Id"] = this.accountId; | ||
headers["X-CleverTap-Passcode"] = this.accountPasscode; | ||
headers["Content-Type"] = "application/json"; | ||
if (options.batchSize && options.batchSize < batchSize) { | ||
batchSize = options.batchSize; | ||
} | ||
const fetchOptions = { | ||
method: method, | ||
headers, | ||
body: options.data ? JSON.stringify(options.data) : undefined, | ||
}; | ||
var processNextBatch = () => { | ||
fetch(url, fetchOptions) | ||
.then((response) => response.json()) | ||
.then((body) => { | ||
callback(body || {}); | ||
}) | ||
.catch((error) => { | ||
callback("error", error); | ||
}); | ||
}; | ||
var batch = []; | ||
CleverTapAPI.prototype._fetch = function (type, query, options, callback) { | ||
if (!query) { | ||
return []; | ||
} | ||
// determine the records for this batch | ||
for (var bidx = recordsBatchIdx; bidx < totalRecords && bidx < recordsBatchIdx + batchSize; bidx++) { | ||
batch.push(data[bidx]); | ||
} | ||
var cursor = null; | ||
var records = []; | ||
if (batch.length > 0) { | ||
//API allows max 5000 records per request | ||
const maxBatchSize = 5000; | ||
options.data = {"d":batch}; | ||
options.method = "POST"; | ||
var batchSize = 10; // default to 10 | ||
this._call('upload', options, (res) => { | ||
if (typeof options === "function" || !options) { | ||
callback = options; | ||
options = {}; | ||
} | ||
completedRecords += batch.length; | ||
if (options.batchSize) { | ||
batchSize = options.batchSize; | ||
} | ||
if (res) { | ||
responses.push(res); | ||
} | ||
batchSize = batchSize > maxBatchSize ? maxBatchSize : batchSize; | ||
if (completedRecords < totalRecords) { | ||
processNextBatch(); | ||
} else if (callback) { | ||
callback(responses); | ||
} | ||
}); | ||
const fetchNext = () => { | ||
let endpoint; | ||
let new_records = null; | ||
recordsBatchIdx += batch.length; | ||
} | ||
}; | ||
if (options.debug) { | ||
console.log( `CleverTap: Uploading ${data.length} records in ${Math.ceil(totalRecords/batchSize)} batch(es)`); | ||
if (!cursor) { | ||
const args = { batch_size: batchSize, query: JSON.stringify(query) }; | ||
endpoint = `${type}.json?${querystring.stringify(args)}`; | ||
} else { | ||
endpoint = `${type}.json?cursor=${cursor}`; | ||
} | ||
processNextBatch(); | ||
this._call(endpoint, options, (res) => { | ||
if (res) { | ||
cursor = res.cursor || res.next_cursor; | ||
new_records = res.records; | ||
}; | ||
CleverTapAPI.prototype.profile = function(options, callback) { | ||
if (typeof(options) === 'function' || !options) { | ||
callback = options; | ||
options = {}; | ||
} | ||
if(!options.email && !options.identity && !options.objectId) { | ||
if (callback) { | ||
callback({}); | ||
if (new_records) { | ||
Array.prototype.push.apply(records, new_records); | ||
} | ||
} | ||
} else { | ||
cursor = null; | ||
} | ||
var endpoint = "profile.json"; | ||
if (cursor) { | ||
fetchNext(); | ||
} else if (callback) { | ||
callback(records); | ||
} | ||
}); | ||
}; | ||
if (options.email) { | ||
endpoint += "?email="+options.email; | ||
} | ||
fetchNext(); | ||
}; | ||
else if (options.identity) { | ||
endpoint += "?identity="+options.identity; | ||
} | ||
CleverTapAPI.prototype.profile = function (options, callback) { | ||
if (typeof options === "function" || !options) { | ||
callback = options; | ||
options = {}; | ||
} | ||
else if (options.objectId) { | ||
endpoint += "?objectId="+options.objectId; | ||
if (!options.email && !options.identity && !options.objectId) { | ||
if (callback) { | ||
callback({}); | ||
} | ||
} | ||
this._call(endpoint, options, (res) => { | ||
var endpoint = "profile.json"; | ||
if (callback) { | ||
callback(res); | ||
} | ||
}); | ||
}; | ||
if (options.email) { | ||
endpoint += "?email=" + options.email; | ||
} else if (options.identity) { | ||
endpoint += "?identity=" + options.identity; | ||
} else if (options.objectId) { | ||
endpoint += "?objectId=" + options.objectId; | ||
} | ||
CleverTapAPI.prototype.profiles = function(query, options, callback) { | ||
return this._fetch("profiles", query, options, callback); | ||
this._call(endpoint, options, (res) => { | ||
if (callback) { | ||
callback(res); | ||
} | ||
}); | ||
}; | ||
CleverTapAPI.prototype.events = function(query, options, callback) { | ||
return this._fetch("events", query, options, callback); | ||
CleverTapAPI.prototype.profiles = function (query, options, callback) { | ||
return this._fetch("profiles", query, options, callback); | ||
}; | ||
CleverTapAPI.prototype.upload = function (data, options, callback) { | ||
if (typeof options === "function" || !options) { | ||
callback = options; | ||
options = {}; | ||
} | ||
CleverTapAPI.prototype.targets = function(options, callback) { | ||
if (typeof(options) === 'function' || !options) { | ||
callback = options; | ||
options = {}; | ||
if (!data || data.length <= 0) { | ||
if (callback) { | ||
callback({}); | ||
} | ||
return []; | ||
} | ||
var action = options.action; | ||
var batchSize = 100; // default: API allows max 100 records per request | ||
var totalRecords = data.length; | ||
var completedRecords = 0; | ||
var recordsBatchIdx = 0; | ||
var responses = []; | ||
if(!action || this.TARGET_ACTIONS.indexOf(action) < 0) { | ||
if (options.debug) { | ||
console.log(`Invalid push target action ${action}`); | ||
} | ||
if (options.batchSize && options.batchSize < batchSize) { | ||
batchSize = options.batchSize; | ||
} | ||
if (callback) { | ||
callback(null); | ||
} | ||
var processNextBatch = () => { | ||
var batch = []; | ||
// determine the records for this batch | ||
for ( | ||
var bidx = recordsBatchIdx; | ||
bidx < totalRecords && bidx < recordsBatchIdx + batchSize; | ||
bidx++ | ||
) { | ||
batch.push(data[bidx]); | ||
} | ||
var endpoint = `targets/${action}.json`; | ||
if (batch.length > 0) { | ||
options.data = { d: batch }; | ||
options.method = "POST"; | ||
this._call(endpoint, options, (res) => { | ||
this._call("upload", options, (res) => { | ||
completedRecords += batch.length; | ||
if (callback) { | ||
callback(res); | ||
if (res) { | ||
responses.push(res); | ||
} | ||
}); | ||
}; | ||
if (completedRecords < totalRecords) { | ||
processNextBatch(); | ||
} else if (callback) { | ||
callback(responses); | ||
} | ||
}); | ||
CleverTapAPI.prototype._fetch = function (type, query, options, callback) { | ||
if (!query) { | ||
return []; | ||
recordsBatchIdx += batch.length; | ||
} | ||
}; | ||
var cursor = null, | ||
records = []; | ||
if (options.debug) { | ||
console.log( | ||
`CleverTap: Uploading ${data.length} records in ${Math.ceil( | ||
totalRecords / batchSize | ||
)} batch(es)` | ||
); | ||
} | ||
//API allows max 5000 records per request | ||
const maxBatchSize = 5000; | ||
processNextBatch(); | ||
}; | ||
var batchSize = 10;// default to 10 | ||
if (typeof(options) === 'function' || !options) { | ||
callback = options; | ||
options = {}; | ||
CleverTapAPI.prototype.profileCounts = function (data, options, callback) { | ||
if (typeof options === "function" || !options) { | ||
callback = options; | ||
options = {}; | ||
} | ||
this._call( | ||
"counts/profiles.json", | ||
{ ...options, data, method: "POST" }, | ||
(res) => { | ||
if (callback) { | ||
callback(res); | ||
} | ||
} | ||
); | ||
}; | ||
if (options.batchSize) { | ||
batchSize = options.batchSize; | ||
} | ||
CleverTapAPI.prototype.delete = function (query, options, callback) { | ||
this._call( | ||
"delete/profiles.json", | ||
{ | ||
...options, | ||
method: "POST", | ||
data: query, | ||
}, | ||
callback | ||
); | ||
}; | ||
batchSize = (batchSize > maxBatchSize) ? maxBatchSize : batchSize; | ||
CleverTapAPI.prototype.demerge = function (query, options, callback) { | ||
this._call( | ||
"demerge/profiles.json", | ||
{ | ||
...options, | ||
method: "POST", | ||
data: query, | ||
}, | ||
callback | ||
); | ||
}; | ||
const fetchNext = () => { | ||
CleverTapAPI.prototype.subscribe = function (query, options, callback) { | ||
this._call( | ||
"subscribe", | ||
{ | ||
...options, | ||
method: "POST", | ||
data: query, | ||
}, | ||
callback | ||
); | ||
}; | ||
let endpoint | ||
let new_records = null | ||
CleverTapAPI.prototype.disassociate = function (query, options, callback) { | ||
this._call( | ||
"disassociate", | ||
{ | ||
...options, | ||
method: "POST", | ||
data: query, | ||
}, | ||
callback | ||
); | ||
}; | ||
if(!cursor) { | ||
const args = {'batch_size': batchSize, 'query': JSON.stringify(query)} | ||
endpoint = `${type}.json?${querystring.stringify(args)}` | ||
CleverTapAPI.prototype.events = function (query, options, callback) { | ||
return this._fetch("events", query, options, callback); | ||
}; | ||
} else { | ||
endpoint = `${type}.json?cursor=${cursor}` | ||
} | ||
this._call(endpoint, options, (res) => { | ||
if (res) { | ||
cursor = res.cursor || res.next_cursor; | ||
new_records = res.records; | ||
if(new_records) { | ||
Array.prototype.push.apply(records, new_records); | ||
} | ||
} else { | ||
cursor = null; | ||
} | ||
if (cursor) { | ||
fetchNext(); | ||
} else if (callback) { | ||
callback(records); | ||
} | ||
}); | ||
}; | ||
fetchNext(); | ||
CleverTapAPI.prototype.getEventsCount = function (data, options, callback) { | ||
if (typeof options === "function" || !options) { | ||
callback = options; | ||
options = {}; | ||
} | ||
this._call( | ||
"counts/events.json", | ||
{ ...options, data, method: "POST" }, | ||
(res) => { | ||
if (callback) { | ||
callback(res); | ||
} | ||
} | ||
); | ||
}; | ||
CleverTapAPI.prototype.targets = function (options, callback) { | ||
if (typeof options === "function" || !options) { | ||
callback = options; | ||
options = {}; | ||
} | ||
CleverTapAPI.prototype._call = function (endpoint, options, callback) { | ||
var action = options.action; | ||
if (!action || this.TARGET_ACTIONS.indexOf(action) < 0) { | ||
if (options.debug) { | ||
console.log( `CleverTap: calling endpoint ${endpoint} with options ${JSON.stringify(options)}`); | ||
console.log(`Invalid push target action ${action}`); | ||
} | ||
callback = callback || function(res) {}; | ||
if (callback) { | ||
callback(null); | ||
} | ||
} | ||
const headers = options.headers || {}, | ||
url = `${this.apiEndpoint}/${endpoint}`, | ||
method = options.method || "GET"; | ||
var endpoint = `targets/${action}.json`; | ||
// add the authentication headers | ||
headers['X-CleverTap-Account-Id'] = this.accountId; | ||
headers['X-CleverTap-Passcode'] = this.accountPasscode; | ||
this._call(endpoint, options, (res) => { | ||
if (callback) { | ||
callback(res); | ||
} | ||
}); | ||
}; | ||
const requestOptions = { | ||
url: url, | ||
method: method, | ||
headers: headers, | ||
json: true, | ||
}; | ||
CleverTapAPI.prototype.getMessageReports = function (query, options, callback) { | ||
this._call( | ||
"message/report.json", | ||
{ | ||
...options, | ||
method: "POST", | ||
data: query, | ||
}, | ||
callback | ||
); | ||
}; | ||
if (options.data) { | ||
requestOptions['json'] = options.data; | ||
} | ||
CleverTapAPI.prototype.realTimeCounts = function (query, options, callback) { | ||
this._call( | ||
"now.json", | ||
{ | ||
...options, | ||
method: "POST", | ||
data: query, | ||
}, | ||
callback | ||
); | ||
}; | ||
request(requestOptions, function (error, response, body){ | ||
if (error) { | ||
callback(error); | ||
} else { | ||
callback(response.body || {}); | ||
} | ||
}); | ||
CleverTapAPI.prototype.topPropertyCounts = function (query, options, callback) { | ||
this._call( | ||
"counts/top.json", | ||
{ | ||
...options, | ||
method: "POST", | ||
data: query, | ||
}, | ||
callback | ||
); | ||
}; | ||
CleverTapAPI.prototype.trends = function (query, options, callback) { | ||
this._call( | ||
"counts/trends.json", | ||
{ | ||
...options, | ||
method: "POST", | ||
data: query, | ||
}, | ||
callback | ||
); | ||
}; | ||
module.exports = CleverTapAPI; |
@@ -9,276 +9,338 @@ /** | ||
const CleverTapAPI = require("./clevertap-api"); | ||
const REGIONS = require('./regions'); | ||
const REGIONS = require("./regions"); | ||
const CREATE = "create", | ||
ESTIMATE = "estimate", | ||
LIST = "list", | ||
RESULT = "result", | ||
STOP = "stop"; | ||
const CREATE = "create"; | ||
const ESTIMATE = "estimate"; | ||
const LIST = "list"; | ||
const RESULT = "result"; | ||
const STOP = "stop"; | ||
const TARGET_ACTIONS = [CREATE, ESTIMATE, LIST, RESULT, STOP]; | ||
const CleverTap = function (CleverTapAccountId, CleverTapAccountPasscode, CleverTapAccountRegion) { | ||
if (!CleverTapAccountId) { | ||
throw new Error("Please provide a CleverTap Account Id"); | ||
} | ||
/* Reference Doc https://developer.clevertap.com/docs/api-reference */ | ||
if (!CleverTapAccountPasscode) { | ||
throw new Error("Please provide a CleverTap Account Passcode"); | ||
} | ||
const CleverTap = function ( | ||
CleverTapAccountId, | ||
CleverTapAccountPasscode, | ||
CleverTapAccountRegion | ||
) { | ||
if (!CleverTapAccountId) { | ||
throw new Error("Please provide a CleverTap Account Id"); | ||
} | ||
if (!REGIONS.regionIsValid(CleverTapAccountRegion)) { | ||
throw new Error("Please provide a valid CleverTap Account Region"); | ||
} | ||
if (!CleverTapAccountPasscode) { | ||
throw new Error("Please provide a CleverTap Account Passcode"); | ||
} | ||
this.api = new CleverTapAPI(CleverTapAccountId, CleverTapAccountPasscode, CleverTapAccountRegion); | ||
if (!REGIONS.regionIsValid(CleverTapAccountRegion)) { | ||
throw new Error("Please provide a valid CleverTap Account Region"); | ||
} | ||
this.api = new CleverTapAPI( | ||
CleverTapAccountId, | ||
CleverTapAccountPasscode, | ||
CleverTapAccountRegion | ||
); | ||
}; | ||
/** | ||
upload(data, options, callback) | ||
profile(options, callback) | ||
Sends an array of event and/or profile objects to CleverTap | ||
Retrieve an individual user profile by ID. | ||
data: Array | ||
options: Object; optional values {"debug":1, "batchSize":50}, debug enables some logging; maximum and default batchSize is 100 | ||
Supported ID values are email, a custom identity value you have set on the profile via the SDKs or the Server API, | ||
or the unique CleverTap objectID used by CleverTap to identify the user profile. | ||
The CleverTap objectID is available via the SDKs as well as displayed in the user profile on the CleverTap dashboard. | ||
options: Object; required value is one of email "email":"foo@foo.com", identity "identity":"1234567" or objectId "objectId":"-1a063854f83a4c6484285039ecff87cb". | ||
optional values "debug":1, debug enables some logging. | ||
callback:function(result:Object), optional | ||
returns a Promise, callback optional | ||
*/ | ||
CleverTap.prototype.profile = function (options, callback) { | ||
if (typeof options === "function" || !options) { | ||
callback = options; | ||
options = {}; | ||
} | ||
Sample data: | ||
var data = [ | ||
{"type":"event", | ||
"identity":"6264372124", | ||
"ts":Math.floor((new Date).getTime()/1000), | ||
"evtName":"choseNewFavoriteFood", | ||
"evtData":{ | ||
"value":"sushi" | ||
}, | ||
}, | ||
var error = null; | ||
{"type":"profile", | ||
"identity":"6264372124", | ||
"profileData":{ | ||
"favoriteColor":"green", | ||
"Age":30, | ||
"Phone":"+14155551234", | ||
"Email":"peter@foo.com", | ||
}, | ||
}, | ||
]; | ||
if (!options.email && !options.identity && !options.objectId) { | ||
error = "profile requires email, identity or objectId"; | ||
} | ||
Result format: | ||
{ | ||
"status":<success, partial, fail>, | ||
"processed":<count>, | ||
"unprocessed": [{"status":"fail", "code":<error code>, "error":<error msg>, "record":<record>}] | ||
} | ||
return new Promise((resolve, reject) => { | ||
if (error) { | ||
console.error(error); | ||
if (callback && typeof callback === "function") { | ||
callback(null); | ||
} | ||
reject(error); | ||
return; | ||
} | ||
Sample result: | ||
{ | ||
"status": "success", | ||
"processed": 1, | ||
"unprocessed": [] | ||
} | ||
this.api.profile(options, (res) => { | ||
resolve(res); | ||
for data sizes > than the specified (or default) batchSize, responses will be an Array of response objects. | ||
if (callback && typeof callback === "function") { | ||
callback(res); | ||
} | ||
}); | ||
}); | ||
}; | ||
/** | ||
profiles(query, options, callback) | ||
For more see https://support.clevertap.com/server/uploading-profiles-and-actions/ | ||
Queries the CleverTap Server API for user profiles defined by query | ||
query: Object | ||
options: Object; optional values {"debug":1, "batchSize":100}, debug enables some logging; default batchSize is 10, maximum batch size is 5000 | ||
callback:function(result:Array<Object>), optional | ||
returns a Promise, callback optional | ||
*/ | ||
CleverTap.prototype.upload = function(data, options, callback) { | ||
CleverTap.prototype.profiles = function (query, options, callback) { | ||
var error = _validate("profiles", query); | ||
var error = _validate("upload", data); | ||
if (typeof options === "function" || !options) { | ||
callback = options; | ||
options = {}; | ||
} | ||
if (typeof(options) === 'function' || !options) { | ||
callback = options; | ||
options = {}; | ||
return new Promise((resolve, reject) => { | ||
if (error) { | ||
console.error(error); | ||
if (callback && typeof callback === "function") { | ||
callback(null); | ||
} | ||
reject(error); | ||
return; | ||
} | ||
return new Promise( (resolve, reject) => { | ||
if (error) { | ||
console.error(error); | ||
if (callback && typeof callback === 'function') { | ||
callback(null); | ||
} | ||
reject(error); | ||
return; | ||
} | ||
this.api.profiles(query, options, (res) => { | ||
resolve(res); | ||
this.api.upload(data, options, (res) => { | ||
// if there is only one reponse return response object rather than array | ||
try { | ||
if(res.length === 1) { | ||
res = res[0]; | ||
} | ||
} catch(e) { | ||
// no-op | ||
} | ||
resolve(res); | ||
if(callback && typeof callback === 'function') { | ||
callback(res); | ||
} | ||
}); | ||
if (callback && typeof callback === "function") { | ||
callback(res); | ||
} | ||
}); | ||
}); | ||
}; | ||
/** | ||
upload(data, options, callback) | ||
profile(options, callback) | ||
Sends an array of event and/or profile objects to CleverTap | ||
Retrieve an individual user profile by ID. | ||
Supported ID values are email, a custom identity value you have set on the profile via the SDKs or the Server API, | ||
or the unique CleverTap objectID used by CleverTap to identify the user profile. | ||
The CleverTap objectID is available via the SDKs as well as displayed in the user profile on the CleverTap dashboard. | ||
options: Object; required value is one of email "email":"foo@foo.com", identity "identity":"1234567" or objectId "objectId":"-1a063854f83a4c6484285039ecff87cb". | ||
optional values "debug":1, debug enables some logging. | ||
data: Array | ||
options: Object; optional values {"debug":1, "batchSize":50}, debug enables some logging; maximum and default batchSize is 100 | ||
callback:function(result:Object), optional | ||
returns a Promise, callback optional | ||
Sample response: | ||
{ | ||
"status": "success", | ||
"record": { | ||
"email": "saifali9690@gmail.com", | ||
"profileData": { | ||
"Last Score": 308, | ||
"High Score": 308, | ||
"Replayed": true | ||
}, | ||
"events": { | ||
"App Launched": { | ||
"count": 10, | ||
"first_seen": 1457271567, | ||
"last_seen": 1458041215 | ||
}, | ||
"Charged": { | ||
"count": 6, | ||
"first_seen": 1457962417, | ||
"last_seen": 1458041276 | ||
} | ||
} | ||
} | ||
} | ||
For more see https://support.clevertap.com/server/downloading-profiles-and-actions/#user-profile-by-id | ||
*/ | ||
CleverTap.prototype.profile = function(options, callback) { | ||
if (typeof(options) === 'function' || !options) { | ||
callback = options; | ||
options = {}; | ||
} | ||
CleverTap.prototype.upload = function (data, options, callback) { | ||
var error = _validate("upload", data); | ||
var error = null; | ||
if (typeof options === "function" || !options) { | ||
callback = options; | ||
options = {}; | ||
} | ||
if(!options.email && !options.identity && !options.objectId) { | ||
error = "profile requires email, identity or objectId"; | ||
return new Promise((resolve, reject) => { | ||
if (error) { | ||
console.error(error); | ||
if (callback && typeof callback === "function") { | ||
callback(null); | ||
} | ||
reject(error); | ||
return; | ||
} | ||
return new Promise( (resolve, reject) => { | ||
if (error) { | ||
console.error(error); | ||
if (callback && typeof callback === 'function') { | ||
callback(null); | ||
} | ||
reject(error); | ||
return; | ||
this.api.upload(data, options, (res) => { | ||
// if there is only one reponse return response object rather than array | ||
try { | ||
if (res.length === 1) { | ||
res = res[0]; | ||
} | ||
} catch (e) { | ||
// no-op | ||
} | ||
this.api.profile(options, (res) => { | ||
resolve(res); | ||
resolve(res); | ||
if(callback && typeof callback === 'function') { | ||
callback(res); | ||
} | ||
}); | ||
if (callback && typeof callback === "function") { | ||
callback(res); | ||
} | ||
}); | ||
}); | ||
}; | ||
/** | ||
/*uploadDeviceTokens Api | ||
uploadDeviceTokens enables to add an existing device token to a CleverTap user profile. | ||
*/ | ||
CleverTap.prototype.uploadDeviceTokens = function (query, options, callback) { | ||
return this.upload(query, options, callback); | ||
}; | ||
profiles(query, options, callback) | ||
/*getProfilesCount Api | ||
CleverTap Api to get the count of profiles | ||
*/ | ||
CleverTap.prototype.getProfilesCount = function (query, options, callback) { | ||
var error = _validate("profiles", query); | ||
Queries the CleverTap Server API for user profiles defined by query | ||
if (typeof options === "function" || !options) { | ||
callback = options; | ||
options = {}; | ||
} | ||
query: Object | ||
options: Object; optional values {"debug":1, "batchSize":100}, debug enables some logging; default batchSize is 10, maximum batch size is 5000 | ||
callback:function(result:Array<Object>), optional | ||
return new Promise((resolve, reject) => { | ||
if (error) { | ||
console.error(error); | ||
if (callback && typeof callback === "function") { | ||
callback(null); | ||
} | ||
reject(error); | ||
return; | ||
} | ||
//Call the events API with the query | ||
this.api.profileCounts(query, options, (res) => { | ||
resolve(res); | ||
//Call the callback function if provided | ||
if (callback && typeof callback === "function") { | ||
callback(res); | ||
} | ||
}); | ||
}); | ||
}; | ||
returns a Promise, callback optional | ||
/*Delete Api | ||
Deletes a user profile from the CleverTap system. | ||
*/ | ||
CleverTap.prototype.delete = function (query, options, callback) { | ||
//Validate the query object for the "profiles" endpoint | ||
var error = _validate("profiles", query); | ||
Sample queries: | ||
var query = { | ||
"event_name":"App Launched", | ||
"from": 20150810, | ||
"to": 20151025 | ||
} | ||
if (typeof options === "function" || !options) { | ||
callback = options; | ||
options = {}; | ||
} | ||
var query = { | ||
"event_name": "choseNewFavoriteFood", | ||
"props": [{"name":"value","operator":"contains", "value":"piz"}], | ||
"from": 20150810, | ||
"to": 20151025 | ||
} | ||
return new Promise((resolve, reject) => { | ||
if (error) { | ||
console.error(error); | ||
if (callback && typeof callback === "function") { | ||
callback(null); | ||
} | ||
reject(error); | ||
return; | ||
} | ||
this.api.delete(query, options, (res) => { | ||
resolve(res); | ||
//Call the callback function if provided | ||
if (callback && typeof callback === "function") { | ||
callback(res); | ||
} | ||
}); | ||
}); | ||
}; | ||
Available query operators are: “equals”, “greater_than”, “greater_than_equals”, “less_than”, “less_than_equals”, “contains”. | ||
The operator is optional and defaults to “equals”. | ||
/*Demerge Api | ||
Demerges a user profile from another profile in the CleverTap system | ||
*/ | ||
CleverTap.prototype.demerge = function (query, options, callback) { | ||
//Validate the query object for the "profiles" endpoint | ||
var error = _validate("profiles", query); | ||
Sample result: | ||
[ | ||
{ | ||
"push_token" : "95f98af6ad9a5e714a56c5bf527a78cb1e3eda18d2f23bc8591437d0d8ae71a3" , | ||
"identity" : "5555555555" , | ||
"profileData": {"favoriteFood": "pizza"}, | ||
"platformInfo" : [ | ||
{ "platform" : "iOS" , | ||
"objectId" : "-1a063854f83a4c6484285039ecff87cb"} , | ||
{ "platform" : "Web" , | ||
"objectId" : "a8ffcbc9-a747-4ee3-a791-c5e58ad03097"} | ||
] | ||
} | ||
] | ||
if (typeof options === "function" || !options) { | ||
callback = options; | ||
options = {}; | ||
} | ||
For more see https://support.clevertap.com/server/downloading-profiles-and-actions/#user-profiles | ||
return new Promise((resolve, reject) => { | ||
if (error) { | ||
console.error(error); | ||
if (callback && typeof callback === "function") { | ||
callback(null); | ||
} | ||
reject(error); | ||
return; | ||
} | ||
this.api.demerge(query, options, (res) => { | ||
resolve(res); | ||
//Call the callback function if provided | ||
if (callback && typeof callback === "function") { | ||
callback(res); | ||
} | ||
}); | ||
}); | ||
}; | ||
/*subscribe Api | ||
subscribe Api provides the ability to set a phone number or email status as subscribed or unsubscribed. | ||
*/ | ||
CleverTap.prototype.profiles = function(query, options, callback) { | ||
CleverTap.prototype.subscribe = function (query, options, callback) { | ||
//Validate the query for profiles | ||
var error = _validate("profiles", query); | ||
//Set the callback function if `options` is a function or not provided | ||
if (typeof options === "function" || !options) { | ||
callback = options; | ||
options = {}; | ||
} | ||
var error = _validate("profiles", query); | ||
if (typeof(options) === 'function' || !options) { | ||
callback = options; | ||
options = {}; | ||
return new Promise((resolve, reject) => { | ||
if (error) { | ||
console.error(error); | ||
if (callback && typeof callback === "function") { | ||
callback(null); | ||
} | ||
reject(error); | ||
return; | ||
} | ||
//Call the API with the provided query | ||
this.api.subscribe(query, options, (res) => { | ||
resolve(res); | ||
//Call the callback function if provided | ||
if (callback && typeof callback === "function") { | ||
callback(res); | ||
} | ||
}); | ||
}); | ||
}; | ||
return new Promise( (resolve, reject) => { | ||
if (error) { | ||
console.error(error); | ||
if (callback && typeof callback === 'function') { | ||
callback(null); | ||
} | ||
reject(error); | ||
return; | ||
} | ||
/*disassociate Api | ||
disassociate API enables you to disconnect a phone number from a user profile. | ||
*/ | ||
CleverTap.prototype.disassociate = function (query, options, callback) { | ||
//Validate the Query for profiles | ||
var error = _validate("profiles", query); | ||
//Set the callback function if `options` is a function or not provided | ||
if (typeof options === "function" || !options) { | ||
callback = options; | ||
options = {}; | ||
} | ||
this.api.profiles(query, options, (res) => { | ||
resolve(res); | ||
if(callback && typeof callback === 'function') { | ||
callback(res); | ||
} | ||
}); | ||
return new Promise((resolve, reject) => { | ||
if (error) { | ||
console.error(error); | ||
if (callback && typeof callback === "function") { | ||
callback(null); | ||
} | ||
reject(error); | ||
return; | ||
} | ||
//Call the Api with the provided Query | ||
this.api.disassociate(query, options, (res) => { | ||
resolve(res); | ||
//Call the callback function if provided | ||
if (callback && typeof callback === "function") { | ||
callback(res); | ||
} | ||
}); | ||
}); | ||
}; | ||
@@ -297,83 +359,177 @@ | ||
returns a Promise, callback optional | ||
*/ | ||
CleverTap.prototype.events = function (query, options, callback) { | ||
var error = _validate("events", query); | ||
Sample queries: | ||
var query = { | ||
"event_name":"App Launched", | ||
"from": 20150810, | ||
"to": 20151025 | ||
} | ||
if (typeof options === "function" || !options) { | ||
callback = options; | ||
options = {}; | ||
} | ||
var query = { | ||
"event_name": "choseNewFavoriteFood", | ||
"props": [{"name":"value","operator":"contains", "value":"piz"}], | ||
"from": 20150810, | ||
"to": 20151025 | ||
} | ||
return new Promise((resolve, reject) => { | ||
if (error) { | ||
console.error(error); | ||
if (callback && typeof callback === "function") { | ||
callback(null); | ||
} | ||
reject(error); | ||
return; | ||
} | ||
this.api.events(query, options, (res) => { | ||
resolve(res); | ||
Available query operators are: “equals”, “greater_than”, “greater_than_equals”, “less_than”, “less_than_equals”, “contains”. | ||
The operator is optional and defaults to “equals”. | ||
if (callback && typeof callback === "function") { | ||
callback(res); | ||
} | ||
}); | ||
}); | ||
}; | ||
Sample result: | ||
[ | ||
{ | ||
"profile": { | ||
"objectId": "a8ffcbc9-a747-4ee3-a791-c5e58ad03097", | ||
"platform": "Web", | ||
"email": "peter@foo.com", | ||
"profileData": { "favoriteColor" : "blue"}, | ||
"identity" : "5555555555", | ||
"id": 33 | ||
}, | ||
"ts": 20151023140416, | ||
"event_props": { "value" : "pizza"} | ||
}, | ||
{ | ||
"profile": { | ||
"objectId": "a8ffcbc9-a747-4ee3-a791-c5e58ad03097", | ||
"platform": "Web", | ||
"email": "peter@foo.com", | ||
"profileData": { "favoriteColor" : "blue"}, | ||
"identity": "5555555555", | ||
"id": 33 | ||
}, | ||
"ts": 20151024121636, | ||
"event_props" : { "value" : "pizza"} | ||
} | ||
] | ||
/*getEventCount Api | ||
CleverTap Api to get the count of event | ||
*/ | ||
CleverTap.prototype.getEventsCount = function (query, options, callback) { | ||
//Validate the query for profiles | ||
var error = _validate("events", query); | ||
For more see https://support.clevertap.com/server/downloading-profiles-and-actions/#user-actions | ||
if (typeof options === "function" || !options) { | ||
callback = options; | ||
options = {}; | ||
} | ||
return new Promise((resolve, reject) => { | ||
if (error) { | ||
console.error(error); | ||
if (callback && typeof callback === "function") { | ||
callback(null); | ||
} | ||
reject(error); | ||
return; | ||
} | ||
//Call the events API with the query | ||
this.api.getEventsCount(query, options, (res) => { | ||
resolve(res); | ||
//Call the callback function if provided | ||
if (callback && typeof callback === "function") { | ||
callback(res); | ||
} | ||
}); | ||
}); | ||
}; | ||
/*getMessageReports Api | ||
The Get Message Reports API lets you download a list of messages sent by CleverTap. | ||
*/ | ||
CleverTap.prototype.events = function(query, options, callback) { | ||
CleverTap.prototype.getMessageReports = function (query, options, callback) { | ||
var error = null; //_validate("profiles", query); | ||
if (typeof options === "function" || !options) { | ||
callback = options; | ||
options = {}; | ||
} | ||
var error = _validate("profiles", query); | ||
return new Promise((resolve, reject) => { | ||
if (error) { | ||
console.error(error); | ||
if (callback && typeof callback === "function") { | ||
callback(null); | ||
} | ||
reject(error); | ||
return; | ||
} | ||
this.api.getMessageReports(query, options, (res) => { | ||
resolve(res); | ||
if (callback && typeof callback === "function") { | ||
callback(res); | ||
} | ||
}); | ||
}); | ||
}; | ||
if (typeof(options) === 'function' || !options) { | ||
callback = options; | ||
options = {}; | ||
/*realTimeCounts Api | ||
This realTimeCounts Api enables you to get a real-time count of active users in the past five minutes in your app. | ||
*/ | ||
CleverTap.prototype.realTimeCounts = function (query, options, callback) { | ||
//Validate the query | ||
var error = null; //_validate("profiles", query); | ||
if (typeof options === "function" || !options) { | ||
callback = options; | ||
options = {}; | ||
} | ||
return new Promise((resolve, reject) => { | ||
if (error) { | ||
console.error(error); | ||
if (callback && typeof callback === "function") { | ||
callback(null); | ||
} | ||
reject(error); | ||
return; | ||
} | ||
this.api.realTimeCounts(query, options, (res) => { | ||
resolve(res); | ||
if (callback && typeof callback === "function") { | ||
callback(res); | ||
} | ||
}); | ||
}); | ||
}; | ||
return new Promise( (resolve, reject) => { | ||
if (error) { | ||
console.error(error); | ||
if (callback && typeof callback === 'function') { | ||
callback(null); | ||
} | ||
reject(error); | ||
return; | ||
} | ||
/*topPropertyCounts Api | ||
This Api is used to retrieve counts for the most and least frequently occurring properties for a particular event in a specified duration. | ||
*/ | ||
CleverTap.prototype.topPropertyCounts = function (query, options, callback) { | ||
var error = null; //_validate("profiles", query); | ||
this.api.events(query, options, (res) => { | ||
if (typeof options === "function" || !options) { | ||
callback = options; | ||
options = {}; | ||
} | ||
resolve(res); | ||
return new Promise((resolve, reject) => { | ||
if (error) { | ||
console.error(error); | ||
if (callback && typeof callback === "function") { | ||
callback(null); | ||
} | ||
reject(error); | ||
return; | ||
} | ||
this.api.topPropertyCounts(query, options, (res) => { | ||
resolve(res); | ||
if (callback && typeof callback === "function") { | ||
callback(res); | ||
} | ||
}); | ||
}); | ||
}; | ||
if(callback && typeof callback === 'function') { | ||
callback(res); | ||
} | ||
}); | ||
/*trends Api | ||
This Api is used to retrieve daily, weekly, and monthly event trends in a specified duration. | ||
*/ | ||
CleverTap.prototype.trends = function (query, options, callback) { | ||
var error = null; //_validate("profiles", query); | ||
if (typeof options === "function" || !options) { | ||
callback = options; | ||
options = {}; | ||
} | ||
return new Promise((resolve, reject) => { | ||
if (error) { | ||
console.error(error); | ||
if (callback && typeof callback === "function") { | ||
callback(null); | ||
} | ||
reject(error); | ||
return; | ||
} | ||
this.api.trends(query, options, (res) => { | ||
resolve(res); | ||
if (callback && typeof callback === "function") { | ||
callback(res); | ||
} | ||
}); | ||
}); | ||
}; | ||
/** | ||
@@ -400,179 +556,197 @@ | ||
CleverTap.prototype.targets = function(action, payload, options, callback) { | ||
if (typeof(options) === 'function' || !options) { | ||
callback = options; | ||
options = {}; | ||
} | ||
CleverTap.prototype.targets = function (action, payload, options, callback) { | ||
if (typeof options === "function" || !options) { | ||
callback = options; | ||
options = {}; | ||
} | ||
var error = null; | ||
if (!action || this.TARGET_ACTIONS.indexOf(action) < 0) { | ||
error = `Invalid push target action ${action}`; | ||
} | ||
var error = null; | ||
if (!action || this.TARGET_ACTIONS.indexOf(action) < 0) { | ||
error = `Invalid push target action ${action}`; | ||
} | ||
var _action = action; | ||
var _action = action; | ||
if (action == this.TARGET_ESTIMATE) { | ||
payload['estimate_only'] = true; | ||
action = this.TARGET_CREATE; | ||
} | ||
if (action == this.TARGET_ESTIMATE) { | ||
payload["estimate_only"] = true; | ||
action = this.TARGET_CREATE; | ||
} | ||
options.action = action; | ||
options.action = action; | ||
if (!error) { | ||
error = _validate(_action, payload); | ||
} | ||
if (!error) { | ||
error = _validate(_action, payload); | ||
} | ||
options.data = payload; | ||
options.data = payload; | ||
options.method = "POST"; | ||
options.method = "POST"; | ||
return new Promise( (resolve, reject) => { | ||
if (error) { | ||
console.error(error); | ||
if (callback && typeof callback === 'function') { | ||
callback(null); | ||
} | ||
reject(error); | ||
return; | ||
} | ||
return new Promise((resolve, reject) => { | ||
if (error) { | ||
console.error(error); | ||
if (callback && typeof callback === "function") { | ||
callback(null); | ||
} | ||
reject(error); | ||
return; | ||
} | ||
this.api.targets(options, (res) => { | ||
this.api.targets(options, (res) => { | ||
resolve(res); | ||
resolve(res); | ||
if(callback && typeof callback === 'function') { | ||
callback(res); | ||
} | ||
}); | ||
if (callback && typeof callback === "function") { | ||
callback(res); | ||
} | ||
}); | ||
}); | ||
}; | ||
var _validate = (type, data) => { | ||
var error = null; | ||
var error = null; | ||
if (type === CREATE || type === ESTIMATE) { | ||
if (!data) { | ||
return `Push targets action ${type} requires a payload`; | ||
} | ||
if (type === CREATE || type === ESTIMATE) { | ||
if (!data) { | ||
return `Push targets action ${type} requires a payload`; | ||
} | ||
if (!data.name) { | ||
return `Push targets action ${type} requires a name`; | ||
} | ||
if (!data.name) { | ||
return `Push targets action ${type} requires a name`; | ||
} | ||
if (!data.where && !data.segment) { | ||
return `Push targets action ${type} requires a where or segment value`; | ||
} | ||
if (!data.where && !data.segment) { | ||
return `Push targets action ${type} requires a where or segment value`; | ||
} | ||
if (data.where && data.segment) { | ||
return `Push targets action ${type} does not support both a where value and a segment value, specify one or the other`; | ||
} | ||
if (data.where && data.segment) { | ||
return `Push targets action ${type} does not support both a where value and a segment value, specify one or the other`; | ||
} | ||
if (data.segment) { | ||
if (data.segment !== "all") { | ||
return `Push targets action ${type} segment value must be all`; | ||
} | ||
} | ||
if (data.segment) { | ||
if (data.segment !== "all") { | ||
return `Push targets action ${type} segment value must be all`; | ||
} | ||
} | ||
if (!data.content) { | ||
return `Push targets action ${type} requires a content dict`; | ||
} | ||
if (!data.content) { | ||
return `Push targets action ${type} requires a content dict`; | ||
} | ||
if (data.content) { | ||
if (!data.content.title || !data.content.body) { | ||
return `Push targets action ${type} content dict requires a title and a body`; | ||
} | ||
} | ||
if (data.content) { | ||
if (!data.content.title || !data.content.body) { | ||
return `Push targets action ${type} content dict requires a title and a body`; | ||
} | ||
} | ||
if (!data.devices) { | ||
return `Push targets action ${type} requires a devices array`; | ||
} | ||
return error; | ||
if (!data.devices) { | ||
return `Push targets action ${type} requires a devices array`; | ||
} | ||
if (type === LIST) { | ||
// no-op | ||
return error; | ||
return error; | ||
} | ||
} | ||
if (type === LIST) { | ||
// no-op | ||
return error; | ||
} | ||
if (type === RESULT || type === STOP) { | ||
if (!data || !data.id) { | ||
error = `Push targets action ${type} requires a target id`; | ||
} | ||
return error; | ||
if (type === RESULT || type === STOP) { | ||
if (!data || !data.id) { | ||
error = `Push targets action ${type} requires a target id`; | ||
} | ||
return error; | ||
} | ||
if (type === "events") { | ||
if(!data || typeof(data) !== "object") { | ||
error = `CleverTap.${type}: query must be an object: ${JSON.stringify(data)}`; | ||
} | ||
if (type === "events") { | ||
if (!data || typeof data !== "object") { | ||
error = `CleverTap.${type}: query must be an object: ${JSON.stringify( | ||
data | ||
)}`; | ||
} | ||
} | ||
if (type === "profiles") { | ||
if(!data || typeof(data) !== "object") { | ||
error = `CleverTap.${type}: query must be an object: ${JSON.stringify(data)}`; | ||
} | ||
if (type === "profiles") { | ||
if (!data || typeof data !== "object") { | ||
error = `CleverTap.${type}: query must be an object: ${JSON.stringify( | ||
data | ||
)}`; | ||
} | ||
} | ||
if (type === "upload") { | ||
data = data ? data : []; | ||
if (type === "upload") { | ||
data = data ? data : []; | ||
var identity = null, | ||
profileData = null; | ||
recordType = null; | ||
var identity = null, | ||
profileData = null, | ||
recordType = null; | ||
const validRecordTypes = ["event", "profile"]; | ||
const validRecordTypes = ["event", "profile", "token"]; | ||
for (var record of data) { | ||
for (var record of data) { | ||
identity = | ||
record.identity || record.FBID || record.GPID || record.objectId; | ||
if (!identity) { | ||
error = `upload record must contain an identity, FBID, GPID or objectId field: ${JSON.stringify( | ||
record | ||
)}`; | ||
break; | ||
} | ||
identity = record.identity || record.FBID || record.GPID || record.objectId; | ||
if(!identity) { | ||
error = `upload record must contain an identity, FBID, GPID or objectId field: ${JSON.stringify(record)}`; | ||
break; | ||
} | ||
recordType = record.type; | ||
if (validRecordTypes.indexOf(recordType) === -1) { | ||
error = `CleverTap.${type}: record type must be 'profile' or 'event': ${JSON.stringify( | ||
record | ||
)}`; | ||
break; | ||
} | ||
if (recordType === "profile") { | ||
profileData = record.profileData; | ||
if (!profileData || typeof profileData !== "object") { | ||
error = `CleverTap.${type}: record with type '${recordType}' must contain a 'profileData' object: ${JSON.stringify( | ||
record | ||
)}`; | ||
break; | ||
} | ||
} | ||
recordType = record.type; | ||
if(validRecordTypes.indexOf(recordType) === -1) { | ||
error = `CleverTap.${type}: record type must be 'profile' or 'event': ${JSON.stringify(record)}`; | ||
break; | ||
} | ||
if(recordType === "profile") { | ||
profileData = record.profileData; | ||
if(!profileData || typeof(profileData) !== "object") { | ||
error = `CleverTap.${type}: record with type '${recordType}' must contain a 'profileData' object: ${JSON.stringify(record)}`; | ||
break; | ||
} | ||
} | ||
if(recordType === "event") { | ||
evtData = record.evtData; | ||
if(!evtData || typeof(evtData) !== "object") { | ||
error = `CleverTap.${type}: record with type '${recordType}' must contain a 'evtData' object: ${JSON.stringify(record)}`; | ||
break; | ||
} | ||
} | ||
if (recordType === "event") { | ||
evtData = record.evtData; | ||
if (!evtData || typeof evtData !== "object") { | ||
error = `CleverTap.${type}: record with type '${recordType}' must contain a 'evtData' object: ${JSON.stringify( | ||
record | ||
)}`; | ||
break; | ||
} | ||
} | ||
} | ||
} | ||
return error; | ||
return error; | ||
}; | ||
const init = (CleverTapAccountId, CleverTapAccountPasscode, CleverTapAccountRegion) => { | ||
if (!CleverTapAccountRegion) { | ||
CleverTapAccountRegion = REGIONS.CLEVERTAP_REGIONS.EUROPE | ||
console.log("CleverTap Account Region not provided; defaulting to Europe (eu1) region"); | ||
} | ||
else if (!REGIONS.regionIsValid(CleverTapAccountRegion)) { | ||
throw new Error(`the CleverTap Account Region provided: ${CleverTapAccountRegion} - is invalid`); | ||
} | ||
return new CleverTap(CleverTapAccountId, CleverTapAccountPasscode, CleverTapAccountRegion); | ||
const init = ( | ||
CleverTapAccountId, | ||
CleverTapAccountPasscode, | ||
CleverTapAccountRegion | ||
) => { | ||
if (!CleverTapAccountRegion) { | ||
CleverTapAccountRegion = REGIONS.CLEVERTAP_REGIONS.EUROPE; | ||
console.log( | ||
"CleverTap Account Region not provided; defaulting to Europe (eu1) region" | ||
); | ||
} else if (!REGIONS.regionIsValid(CleverTapAccountRegion)) { | ||
throw new Error( | ||
`the CleverTap Account Region provided: ${CleverTapAccountRegion} - is invalid` | ||
); | ||
} | ||
return new CleverTap( | ||
CleverTapAccountId, | ||
CleverTapAccountPasscode, | ||
CleverTapAccountRegion | ||
); | ||
}; | ||
module.exports = { | ||
REGIONS: REGIONS.CLEVERTAP_REGIONS, | ||
"init": init | ||
REGIONS: REGIONS.CLEVERTAP_REGIONS, | ||
init: init, | ||
}; |
const CLEVERTAP_REGIONS = { | ||
EUROPE: 'eu1', | ||
INDIA: 'in1', | ||
SINGAPORE: 'sg1', | ||
US: 'us1' | ||
} | ||
EUROPE: "eu1", | ||
INDIA: "in1", | ||
SINGAPORE: "sg1", | ||
US: "us1", | ||
INDONESIA: "aps3", | ||
MIDDLEEAST: "mec1", | ||
}; | ||
const VALID_REGIONS = [CLEVERTAP_REGIONS.EUROPE, CLEVERTAP_REGIONS.INDIA, CLEVERTAP_REGIONS.SINGAPORE, CLEVERTAP_REGIONS.US] | ||
const VALID_REGIONS = [ | ||
CLEVERTAP_REGIONS.EUROPE, | ||
CLEVERTAP_REGIONS.INDIA, | ||
CLEVERTAP_REGIONS.SINGAPORE, | ||
CLEVERTAP_REGIONS.US, | ||
CLEVERTAP_REGIONS.INDONESIA, | ||
CLEVERTAP_REGIONS.MIDDLEEAST, | ||
]; | ||
const regionIsValid = (region) => { | ||
return region && VALID_REGIONS.includes(region) | ||
} | ||
return region && VALID_REGIONS.includes(region); | ||
}; | ||
module.exports = { | ||
CLEVERTAP_REGIONS, | ||
VALID_REGIONS, | ||
regionIsValid | ||
} | ||
CLEVERTAP_REGIONS, | ||
VALID_REGIONS, | ||
regionIsValid, | ||
}; |
{ | ||
"name": "clevertap", | ||
"version": "1.2.0", | ||
"version": "1.3.0", | ||
"description": "CleverTap API library for node", | ||
@@ -28,4 +28,4 @@ "main": "./lib/clevertap", | ||
"dependencies": { | ||
"querystring": "^0.2.0", | ||
"request": "^2.69.0" | ||
"node-fetch": "^2.6.9", | ||
"querystring": "^0.2.0" | ||
}, | ||
@@ -36,4 +36,4 @@ "engines": { | ||
"devDependencies": { | ||
"mocha": "^2.4.5" | ||
"mocha": "^10.2.0" | ||
} | ||
} |
391
README.md
@@ -24,149 +24,311 @@ # clevertap-node | ||
SINGAPORE: 'sg1', | ||
US: 'us1' | ||
US: 'us1', | ||
INDONESIA: 'aps3', | ||
MIDDLEEAST: 'mec1' | ||
*/ | ||
const clevertap = CleverTap.init(YOUR_CLEVERTAP_ACCOUNT_ID, YOUR_CLEVERTAP_ACCOUNT_PASSCODE, CleverTap.CLEVERTAP_REGIONS.EUROPE); | ||
const clevertap = CleverTap.init(YOUR_CLEVERTAP_ACCOUNT_ID, YOUR_CLEVERTAP_ACCOUNT_PASSCODE, CleverTap.REGIONS.EUROPE); | ||
// the library supports both callbacks and Promises | ||
// upload an array of event/profile records callback style | ||
clevertap.upload(data, {"debug":1, batchSize:50}, (res) => {console.log(res)}); | ||
/* Upload Profile or events */ | ||
var data = [ | ||
{ | ||
type: "event", | ||
identity: "6264372124", | ||
evtName: "choseNewFavoriteFood", | ||
evtData: { | ||
value: "sushi", | ||
}, | ||
}, | ||
// or if you prefer Promises | ||
clevertap.upload(data, {"debug":1, batchSize:50}).then( (res) => {console.log(res)} ); | ||
{ | ||
type: "profile", | ||
identity: "6264372124", | ||
ts: t, | ||
profileData: { | ||
favoriteColor: "green", | ||
Age: 30, | ||
Phone: "+14155551234", | ||
Email: "peter@foo.com", | ||
}, | ||
}, | ||
// query for events | ||
var query = {"event_name":"choseNewFavoriteFood", | ||
"props": | ||
[{"name":"value","operator":"contains", "value":"piz"}], | ||
"from": 20210101, | ||
"to": 20210701 | ||
}; | ||
{ | ||
type: "event", | ||
FBID: "34322423", | ||
evtName: "Product viewed", | ||
evtData: { | ||
"Product name": "Casio Chronograph Watch", | ||
Category: "Mens Watch", | ||
Price: 59.99, | ||
Currency: "USD", | ||
}, | ||
}, | ||
//callback style | ||
clevertap.events(query, {debug:1, batchSize:500}, (res) => {console.log(res)}); | ||
{ | ||
type: "profile", | ||
objectId: "-2ce3cca260664f70b82b1c6bb505f462", | ||
profileData: { favoriteFood: "hot dogs" }, | ||
}, | ||
{ | ||
type: "event", | ||
objectId: "-2ce3cca260664f70b82b1c6bb505f462", | ||
evtName: "choseNewFavoriteFood", | ||
evtData: {}, | ||
}, | ||
{ | ||
type: "event", | ||
identity: "jack@gmail.com", | ||
ts: t, | ||
evtName: "Charged", | ||
evtData: { | ||
Amount: 300, | ||
Currency: "USD", | ||
"Payment mode": "Credit Card", | ||
Items: [ | ||
{ | ||
Category: "books", | ||
"Book name": "The millionaire next door", | ||
Quantity: 1, | ||
}, | ||
{ | ||
Category: "books", | ||
"Book name": "Achieving inner zen", | ||
Quantity: 4, | ||
}, | ||
], | ||
}, | ||
}, | ||
]; | ||
// callback style | ||
clevertap.upload(data, { debug: 1, batchSize: 1000 }, (res) => { | ||
console.log(res); | ||
}); | ||
// or if you prefer Promises | ||
clevertap.events(query, {debug:1, batchSize:500}).then( (res) => {console.log(res)} ); | ||
clevertap.upload(data, { debug: 1, batchSize: 1000 }).then((res) => { | ||
console.log(res); | ||
}); | ||
//query for user profiles | ||
var query = {"event_name":"choseNewFavoriteFood", | ||
"from": 20210101, | ||
"to": 20210701 | ||
} | ||
/* Get Events data */ | ||
var eventsQuery = { | ||
event_name: "choseNewFavoriteFood", | ||
props: [{ name: "value", operator: "contains", value: "piz" }], | ||
from: 20150810, | ||
to: 20151025, | ||
}; | ||
// callback style | ||
clevertap.events(eventsQuery, { debug: 1, batchSize: 6000 }, (res) => { | ||
console.log(res); | ||
}); | ||
// or if you prefer Promises | ||
clevertap.events(eventsQuery, { debug: 1, batchSize: 6000 }).then((res) => { | ||
console.log(res); | ||
}); | ||
/* Get profile info */ | ||
//callback style | ||
clevertap.profiles(query, {debug:1, batchSize:200}, (res) => {console.log(res)}); | ||
clevertap.profile( | ||
{ objectId: "-2ce3cca260664f70b82b1c6bb505f462", debug: 1 }, | ||
(res) => { | ||
console.log(res); | ||
} | ||
); | ||
// or if you prefer Promises | ||
clevertap.profiles(query, {debug:1, batchSize:200}).then( (res) => {console.log(res)} ); | ||
clevertap | ||
.profile({ objectId: "-2ce3cca260664f70b82b1c6bb505f462", debug: 1 }) | ||
.then((res) => { | ||
console.log(res); | ||
}); | ||
// send a push notification | ||
var createPayload = { | ||
"name": "green freedom", | ||
"when": "now", | ||
"where": { | ||
"event_name": "App Launched", | ||
"from": 20210101, | ||
"to": 20210701, | ||
}, | ||
"content":{ | ||
"title":"Hello!", | ||
"body":"Strictly Green Lantern fans only!", | ||
"platform_specific": { | ||
"ios": { | ||
"deep_link": "judepereira.com", | ||
"sound_file": "judepereira.wav", | ||
"category": "reactive", | ||
"badge_count": 1, | ||
"foo": "bar_ios" | ||
}, | ||
"android": { | ||
"background_image": "http://judepereira.com/a.jpg", | ||
"default_sound": true, | ||
"deep_link": "judepereira.com", | ||
"foo": "bar_android", | ||
"wzrk_cid":"BRTesting" | ||
} | ||
} | ||
}, | ||
"devices": [ | ||
"android", | ||
"ios" | ||
], | ||
} | ||
var profilesQuery = { | ||
event_name: "choseNewFavoriteFood", | ||
props: [{ name: "value", operator: "contains", value: "piz" }], | ||
from: 20150810, | ||
to: 20151025, | ||
}; | ||
//callback style | ||
clevertap.targets(clevertap.TARGET_CREATE, createPayload, {"debug":1}, (res) => {console.log(res)} ); | ||
clevertap.profiles(profilesQuery, { debug: 1, batchSize: 200 }, (res) => { | ||
console.log(res); | ||
}); | ||
// or if you prefer Promises | ||
clevertap.targets(clevertap.TARGET_CREATE, createPayload, {"debug":1}).then( (res) => {console.log(res)} ); | ||
clevertap.profiles(profilesQuery, { debug: 1, batchSize: 200 }).then((res) => { | ||
console.log(res); | ||
}); | ||
//Estimate a target compaigns | ||
/* Campaign API's - CREATE, ESTIMATE, LIST, RESULT, STOP, TARGET_ACTIONS */ | ||
var estimatePayload = { | ||
"name": "green freedom", | ||
"when": "now", | ||
//This flag should be add in the the payload for target estimate api | ||
"estimate_only": true, | ||
"where": { | ||
"event_name": "App Launched", | ||
"from": 20210101, | ||
"to": 20210701, | ||
name: "green freedom", | ||
when: "now", | ||
where: { | ||
event_name: "App Launched", | ||
from: 20160101, | ||
to: 20160317, | ||
}, | ||
content: { | ||
title: "Hello!", | ||
body: "Strictly Green Lantern fans only!", | ||
platform_specific: { | ||
ios: { | ||
deep_link: "judepereira.com", | ||
sound_file: "judepereira.wav", | ||
category: "reactive", | ||
badge_count: 1, | ||
foo: "bar_ios", | ||
}, | ||
android: { | ||
background_image: "http://judepereira.com/a.jpg", | ||
default_sound: true, | ||
deep_link: "judepereira.com", | ||
foo: "bar_android", | ||
}, | ||
}, | ||
"content":{ | ||
"title":"Hello!", | ||
"body":"Strictly Green Lantern fans only!", | ||
"platform_specific": { | ||
"ios": { | ||
"deep_link": "judepereira.com", | ||
"sound_file": "judepereira.wav", | ||
"category": "reactive", | ||
"badge_count": 1, | ||
"foo": "bar_ios" | ||
}, | ||
"android": { | ||
"background_image": "http://judepereira.com/a.jpg", | ||
"default_sound": true, | ||
"deep_link": "judepereira.com", | ||
"foo": "bar_android", | ||
"wzrk_cid":"BRTesting" | ||
} | ||
} | ||
}, | ||
devices: ["android", "ios"], | ||
}; | ||
//callback style | ||
clevertap.targets( | ||
clevertap.TARGET_ESTIMATE, | ||
estimatePayload, | ||
{ debug: 1 }, | ||
(res) => { | ||
console.log(res); | ||
} | ||
); | ||
// or if you prefer Promises | ||
clevertap | ||
.targets(clevertap.TARGET_ESTIMATE, estimatePayload, { debug: 1 }) | ||
.then((res) => { | ||
console.log(res); | ||
}); | ||
var createPayload = { | ||
name: "green freedom", | ||
when: "now", | ||
where: { | ||
event_name: "App Launched", | ||
from: 20160101, | ||
to: 20160317, | ||
}, | ||
content: { | ||
title: "Hello!", | ||
body: "Strictly Green Lantern fans only!", | ||
platform_specific: { | ||
ios: { | ||
deep_link: "judepereira.com", | ||
sound_file: "judepereira.wav", | ||
category: "reactive", | ||
badge_count: 1, | ||
foo: "bar_ios", | ||
}, | ||
android: { | ||
background_image: "http://judepereira.com/a.jpg", | ||
default_sound: true, | ||
deep_link: "judepereira.com", | ||
foo: "bar_android", | ||
}, | ||
}, | ||
"devices": [ | ||
"android", | ||
"ios" | ||
], | ||
} | ||
}, | ||
devices: ["ios"], | ||
}; | ||
//callback style | ||
clevertap.targets(clevertap.TARGET_ESTIMATE, estimatePayload, {"debug":1}, (res) => {console.log(res)} ); | ||
clevertap.targets( | ||
clevertap.TARGET_CREATE, | ||
createPayload, | ||
{ debug: 1 }, | ||
(res) => { | ||
console.log(res); | ||
} | ||
); | ||
// or if you prefer Promises | ||
clevertap.targets(clevertap.TARGET_ESTIMATE, estimatePayload, {"debug":1}).then( (res) => {console.log(res)} ); | ||
clevertap | ||
.targets(clevertap.TARGET_CREATE, createPayload, { debug: 1 }) | ||
.then((res) => { console.log(res); }); | ||
//List all target compaigns in a date range | ||
var listPayload = {"from": 20210101, "to": 20210701} | ||
var listPayload = { from: 20160101, to: 20160317 }; | ||
//callback style | ||
clevertap.targets(clevertap.TARGET_LIST, listPayload, {"debug":1}, (res) => {console.log(res)} ); | ||
clevertap.targets(clevertap.TARGET_LIST, listPayload, { debug: 1 }, (res) => { console.log(res); }); | ||
// or if you prefer Promises | ||
clevertap.targets(clevertap.TARGET_LIST, listPayload, {"debug":1}).then( (res) => {console.log(res)} ); | ||
clevertap | ||
.targets(clevertap.TARGET_LIST, listPayload, { debug: 1 }) | ||
.then((res) => {console.log(res);}); | ||
//Stop a specific target compaign | ||
var stopPayload = {"id": 1629904249} | ||
var stopPayload = { id: 1458261857 }; | ||
//callback style | ||
clevertap.targets(clevertap.TARGET_STOP, stopPayload, {"debug":1}, (res) => {console.log(res)} ); | ||
clevertap.targets(clevertap.TARGET_STOP, stopPayload, { debug: 1 }, (res) => {console.log(res);}); | ||
// or if you prefer Promises | ||
clevertap.targets(clevertap.TARGET_STOP, createPayload, {"debug":1}).then( (res) => {console.log(res)} ); | ||
clevertap | ||
.targets(clevertap.TARGET_STOP, stopPayload, { debug: 1 }) | ||
.then((res) => { console.log(res);}); | ||
//Resule out a target compaign | ||
var resultPayload = {"id": 1629904249} | ||
var resultPayload = { id: 1458261857 }; | ||
//callback style | ||
clevertap.targets(clevertap.TARGET_RESULT, resultPayload, {"debug":1}, (res) => {console.log(res)} ); | ||
clevertap.targets( | ||
clevertap.TARGET_RESULT, | ||
resultPayload, | ||
{ debug: 1 }, | ||
(res) => {console.log(res);} | ||
); | ||
// or if you prefer Promises | ||
clevertap.targets(clevertap.TARGET_RESULT, resultPayload, {"debug":1}).then( (res) => {console.log(res)} ); | ||
clevertap | ||
.targets(clevertap.TARGET_RESULT, resultPayload, { debug: 1 }) | ||
.then((res) => {console.log(res);}); | ||
/* Report API's */ | ||
// Get Message Reports | ||
var getMessageReportspayload = { from: "20171101", to: "20171225" }; | ||
clevertap | ||
.getMessageReports(getMessageReportspayload, { debug: 1 }) | ||
.then((res) => {console.log(res);}); | ||
// This endpoint enables you to get a real-time count of active users in the past five minutes in your app | ||
var realTimeCountspayload = { user_type: true }; | ||
clevertap.realTimeCounts(realTimeCountspayload, { debug: 1 }).then((res) => {console.log(res);}); | ||
// This endpoint is used to retrieve counts for the most and least frequently occurring properties for a particular event in a specified duration | ||
var topPropertyCountspayload = { | ||
event_name: "Charged", | ||
from: 20161229, | ||
to: 20170129, | ||
groups: { | ||
foo: { | ||
property_type: "event_properties", | ||
name: "Amount", | ||
}, | ||
bar: { | ||
property_type: "profile_fields", | ||
name: "Customer Type", | ||
top_n: 2, | ||
order: "asc", | ||
}, | ||
}, | ||
}; | ||
clevertap | ||
.topPropertyCounts(topPropertyCountspayload, { debug: 1 }) | ||
.then((res) => {console.log(res);}); | ||
// This endpoint is used to retrieve daily, weekly, and monthly event trends in a specified duration. | ||
var trendspayload = { | ||
event_name: "Charged", | ||
from: 20161224, | ||
to: 20170103, | ||
unique: false, | ||
sum_event_prop: "Amount", | ||
groups: { | ||
foo: { | ||
trend_type: "daily", | ||
}, | ||
bar: { | ||
trend_type: "weekly", | ||
}, | ||
foobar: { | ||
trend_type: "monthly", | ||
}, | ||
}, | ||
}; | ||
clevertap.trends(trendspayload, { debug: 1 }).then((res) => {console.log(res);}); | ||
``` | ||
@@ -176,3 +338,3 @@ | ||
Also please see our [Server API documentation](https://support.clevertap.com/server/overview/). | ||
Also please see our [Server API documentation](https://developer.clevertap.com/docs/api-overview). | ||
@@ -183,3 +345,2 @@ ## Tests | ||
npm test // all tests | ||
npm run testpush // just push specific tests | ||
``` |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
39034
992
344
3
+ Addednode-fetch@^2.6.9
+ Addednode-fetch@2.7.0(transitive)
+ Addedtr46@0.0.3(transitive)
+ Addedwebidl-conversions@3.0.1(transitive)
+ Addedwhatwg-url@5.0.0(transitive)
- Removedrequest@^2.69.0
- Removedajv@6.12.6(transitive)
- Removedasn1@0.2.6(transitive)
- Removedassert-plus@1.0.0(transitive)
- Removedasynckit@0.4.0(transitive)
- Removedaws-sign2@0.7.0(transitive)
- Removedaws4@1.13.2(transitive)
- Removedbcrypt-pbkdf@1.0.2(transitive)
- Removedcaseless@0.12.0(transitive)
- Removedcombined-stream@1.0.8(transitive)
- Removedcore-util-is@1.0.2(transitive)
- Removeddashdash@1.14.1(transitive)
- Removeddelayed-stream@1.0.0(transitive)
- Removedecc-jsbn@0.1.2(transitive)
- Removedextend@3.0.2(transitive)
- Removedextsprintf@1.3.0(transitive)
- Removedfast-deep-equal@3.1.3(transitive)
- Removedfast-json-stable-stringify@2.1.0(transitive)
- Removedforever-agent@0.6.1(transitive)
- Removedform-data@2.3.3(transitive)
- Removedgetpass@0.1.7(transitive)
- Removedhar-schema@2.0.0(transitive)
- Removedhar-validator@5.1.5(transitive)
- Removedhttp-signature@1.2.0(transitive)
- Removedis-typedarray@1.0.0(transitive)
- Removedisstream@0.1.2(transitive)
- Removedjsbn@0.1.1(transitive)
- Removedjson-schema@0.4.0(transitive)
- Removedjson-schema-traverse@0.4.1(transitive)
- Removedjson-stringify-safe@5.0.1(transitive)
- Removedjsprim@1.4.2(transitive)
- Removedmime-db@1.52.0(transitive)
- Removedmime-types@2.1.35(transitive)
- Removedoauth-sign@0.9.0(transitive)
- Removedperformance-now@2.1.0(transitive)
- Removedpsl@1.15.0(transitive)
- Removedpunycode@2.3.1(transitive)
- Removedqs@6.5.3(transitive)
- Removedrequest@2.88.2(transitive)
- Removedsafe-buffer@5.2.1(transitive)
- Removedsafer-buffer@2.1.2(transitive)
- Removedsshpk@1.18.0(transitive)
- Removedtough-cookie@2.5.0(transitive)
- Removedtunnel-agent@0.6.0(transitive)
- Removedtweetnacl@0.14.5(transitive)
- Removeduri-js@4.4.1(transitive)
- Removeduuid@3.4.0(transitive)
- Removedverror@1.10.0(transitive)