jpush-sdk-cube
Version:
JPush's officially supported Node.js client library.
469 lines (404 loc) • 14.9 kB
JavaScript
/**
* PushPayload
*/
var JError = require('./JPushError');
var JUtil = require('./util');
function PushPayload(client) {
this.client = client;
this.payload = {};
}
function setPlatform() {
if (arguments.length < 1) {
throw new JError.InvalidArgumentError("platform's args cannot all be null");
}
var platform, i;
if (arguments.length == 1 && arguments[0] === ALL) {
platform = ALL;
} else if (arguments.length == 1 && typeof arguments[0] == 'object') {
platform = [];
for(i=0; i<arguments[0].length; i++) {
if (VALID_DEVICE_TYPES.indexOf(arguments[0][i]) != -1) {
if (platform.indexOf(arguments[0][i]) == -1) {
platform.push(arguments[0][i]);
}
} else {
throw new JError.InvalidArgumentError("Invalid device type '" + arguments[0][i] + "', platform can only be set to 'android', 'ios' or 'winphone'");
}
}
} else {
platform = [];
for(i=0; i<arguments.length; i++) {
if (VALID_DEVICE_TYPES.indexOf(arguments[i]) != -1) {
if (platform.indexOf(arguments[i]) == -1) {
platform.push(arguments[i]);
}
} else {
throw new JError.InvalidArgumentError("Invalid device type '" + arguments[i] + "', platform can only be set to 'android', 'ios' or 'winphone'");
}
}
}
this.payload = JUtil.extend(this.payload, {'platform' : platform});
return this;
}
function buildAudience(args, title) {
if (args.length < 1) {
throw new JError.InvalidArgumentError("Should be set at least ont " + title);
}
var payload = [], i;
if (args.length == 1 && typeof args[0] === 'string') {
var tags_t = args[0].split(',');
for (i=0; i<tags_t.length; i++) {
if (tags_t[i].trim().length > 0) {
payload.push(tags_t[i].trim());
}
}
if (payload.length < 1) {
throw new JError.InvalidArgumentError("Should be set at least ont " + title);
}
} else if (args.length == 1 && Array.isArray(args[0])) {
for (i=0; i< args[0].length; i++) {
if (typeof args[0][i] != 'string') {
throw new JError.InvalidArgumentError("Invalid " + title + ' at index ' + i + ', ' + title + ' can only be set to the String');
}
payload.push(args[0][i]);
}
} else {
for (i=0; i<args.length; i++) {
if (typeof args[i] != 'string') {
throw new JError.InvalidArgumentError("Invalid " + title + ' at argument ' + i + ', ' + title + ' can only be set to the String');
}
payload.push(args[i]);
}
}
return payload;
}
function alias() {
return {'alias' : buildAudience(arguments, 'alias')};
}
function tag() {
return {'tag' : buildAudience(arguments, 'tag')};
}
function tag_and() {
return {'tag_and' : buildAudience(arguments, 'tag_and')};
}
function registration_id () {
return {'registration_id' : buildAudience(arguments, 'registration_id')};
}
function setAudience() {
if (arguments.length < 1) {
throw new JError.InvalidArgumentError("audience must be set");
}
var audience;
if (arguments.length == 1 && arguments[0] === ALL) {
audience = ALL;
} else {
audience = {};
for (var i=0; i<arguments.length; i++) {
audience = JUtil.extend(audience, arguments[i]);
}
}
this.payload = JUtil.extend(this.payload, {'audience' : audience});
return this;
}
function android(alert, title, builder_id, extras) {
if (!alert || typeof alert != 'string') {
throw new JError.InvalidArgumentError("android.alert is require and can only be set to the String");
}
var android = {'alert' : alert};
if (title != null) {
if (typeof title != 'string') {
throw new JError.InvalidArgumentError("Invalid android.title, it can only be set to the String");
}
android['title'] = title;
}
if (builder_id != null) {
if (typeof builder_id != 'number') {
throw new JError.InvalidArgumentError("Invalid android.builder_id, it can only be set to the Number");
}
android['builder_id'] = builder_id;
}
if (extras != null) {
if (typeof extras != 'object') {
throw new JError.InvalidArgumentError("Invalid android.extras");
}
android['extras'] = extras;
}
return {'android' : android};
}
function ios(alert, sound, badge, contentAvailable, extras, category) {
if (!alert || typeof alert != 'string') {
throw new JError.InvalidArgumentError("ios.alert is require and can only be set to the String");
}
var ios = {'alert' : alert};
if (sound != null) {
if (typeof sound != 'string') {
throw new JError.InvalidArgumentError("Invalid ios.sound, it can only be set to the String");
}
if (sound != DISABLE_SOUND) {
ios['sound'] = sound;
}
} else {
ios['sound'] = "";
}
if (badge != null) {
if (badge != DISABLE_BADGE) {
ios['badge'] = badge;
}
} else {
ios['badge'] = '+1';
}
if (contentAvailable != null) {
if (typeof contentAvailable != 'boolean') {
throw new JError.InvalidArgumentError("Invalid ios.contentAvailable, it can only be set to the Boolean");
}
if (contentAvailable) {
ios['content-available'] = 1;
}
}
if (extras != null) {
if (typeof extras != 'object') {
throw new JError.InvalidArgumentError("Invalid ios.extras");
}
ios['extras'] = extras;
}
if (category != null) {
ios['category'] = category;
}
return {"ios" : ios};
}
function winphone(alert, title, openPage, extras) {
if (!alert || typeof alert != 'string') {
throw new JError.InvalidArgumentError("winphone.alert is require and can only be set to the String");
}
var winphone = {'alert' : alert};
if (title != null) {
if (typeof title != 'string') {
throw new JError.InvalidArgumentError("Invalid winphone.title, it can only be set to the String");
}
winphone['title'] = title;
}
if (openPage != null) {
if (typeof openPage != 'string') {
throw new JError.InvalidArgumentError("Invalid winphone.openPage, it can only be set to the String");
}
winphone['_open_page'] = openPage;
}
if (extras != null) {
if (typeof extras != 'object') {
throw new JError.InvalidArgumentError("Invalid winphone.extras");
}
winphone['extras'] = extras;
}
return {'winphone' : winphone};
}
function setNotification() {
if (arguments.length < 1) {
throw new JError.InvalidArgumentError("Invalid notification");
}
var notification = {};
var offset = 0;
if (typeof arguments[0] === 'string') {
notification['alert'] = arguments[0];
offset = 1;
}
for (; offset < arguments.length; offset++) {
if (typeof arguments[offset] != 'object') {
throw new JError.InvalidArgumentError("Invalid notification argument at index " + offset);
}
notification = JUtil.extend(notification, arguments[offset]);
}
this.payload = JUtil.extend(this.payload, {'notification' : notification});
return this;
}
function setMessage(msg_content, title, content_type, extras) {
if (msg_content == null || typeof msg_content != 'string') {
throw new JError.InvalidArgumentError("message.msg_content is require and can only be set to the String");
}
var message = {'msg_content' : msg_content};
if (title != null) {
if (typeof title !== 'string') {
throw new JError.InvalidArgumentError("Invalid message.title, it can only be set to the String");
}
message['title'] = title;
}
if (content_type != null) {
if (typeof content_type !== 'string') {
throw new JError.InvalidArgumentError("Invalid message.content_type, it can only be set to the String");
}
message['content_type'] = content_type;
}
if (extras != null) {
if (typeof extras != 'object') {
throw new JError.InvalidArgumentError("Invalid message.extras");
}
message['extras'] = extras;
}
this.payload = JUtil.extend(this.payload, {'message' : message});
return this;
}
function generateSendno() {
return(MIN_SENDNO + Math.round(Math.random() * (MAX_SENDNO - MIN_SENDNO)));
}
function setOptions(sendno, time_to_live, override_msg_id, apns_production, big_push_duration) {
if (sendno == null && time_to_live == null && override_msg_id == null && apns_production == null && big_push_duration == null) {
throw new JError.InvalidArgumentError("option's args cannot all be null.");
}
var options = {};
if (sendno != null) {
if (typeof sendno !== 'number') {
throw new JError.InvalidArgumentError("Invalid options.sendno, it can only be set to the Number");
}
options['sendno'] = sendno;
} else {
options['sendno'] = generateSendno();
}
if (time_to_live != null) {
if (typeof time_to_live !== 'number') {
throw new JError.InvalidArgumentError("Invalid options.time_to_live, it can only be set to the Number");
}
options['time_to_live'] = time_to_live;
}
if (override_msg_id != null) {
if (typeof override_msg_id !== 'number') {
throw new JError.InvalidArgumentError("Invalid options.override_msg_id, it can only be set to the Number");
}
options['override_msg_id'] = override_msg_id;
}
if (apns_production != null) {
if (typeof apns_production !== 'boolean') {
throw new JError.InvalidArgumentError("Invalid options.apns_production, it can only be set to the Boolean");
}
options['apns_production'] = apns_production;
} else {
options['apns_production'] = false;
}
if (big_push_duration != null) {
if (typeof big_push_duration !== 'number') {
throw new JError.InvalidArgumentError("Invalid options.big_push_duration, it can only be set to the Number");
}
if (big_push_duration >1440 || big_push_duration <= 0) {
throw new JError.InvalidArgumentError("Invalid options.big_push_duration, it should bigger than 0 and less than 1440");
}
options['big_push_duration'] = big_push_duration;
}
this.payload = JUtil.extend(this.payload, {'options' : options});
return this;
}
function toJSON() {
/*
if (this.payload.notification && this.payload.notification.ios) {
this.payload.notification.ios = JUtil.extend({'sound':'', badge:1}, this.payload.notification.ios);
}
*/
this.payload.options = JUtil.extend({'sendno':generateSendno(), 'apns_production':false}, this.payload.options);
return JSON.stringify(this.payload);
}
function send(callback) {
validate(this.payload);
var body = this.toJSON();
return this.client.sendPush(body, callback);
}
function sendValidate(callback) {
validate(this.payload);
var body = this.toJSON();
return this.client.validate(body, callback);
}
/**
* Verify the payload legitimacy, it will call by this.send()
* @param payload
*/
function validate(payload) {
var notification = payload.notification,
message = payload.message;
if (!notification && !message) {
throw new JError.InvalidArgumentError('Either or both notification and message must be set.');
}
}
function calculateLength(str) {
var ch, st, re = [];
for (var i = 0; i < str.length; i++ ) {
ch = str.charCodeAt(i);
st = [];
do {
st.push( ch & 0xFF );
ch = ch >> 8;
}
while ( ch );
re = re.concat( st.reverse() );
}
// return an array of bytes
return re.length;
}
function isIosExceedLength() {
var ios,
notification = this.payload.notification,
message = this.payload.message;
var alert = notification.alert ? notification.alert : '';
ios = calculateLength(JSON.stringify(JUtil.extend({'alert': alert}, notification.ios)));
if (message != null) {
var msgLen = calculateLength(JSON.stringify(message));
return msgLen >= 1000;
}
return ios >= 2000;
}
function isGlobalExceedLength(){
var android = 0, winphone = 0, ios = false;
var notification = this.payload.notification,
message = this.payload.message,
platform = this.payload.platform;
var hasIOS = true;
if (platform != ALL) {
hasIOS = false;
for (var i=0; i<platform.length; i++) {
if (platform[i] == 'ios') {
hasIOS = true;
break;
}
}
}
if (hasIOS) {
ios = this.isIosExceedLength();
}
if (notification != null) {
var alert = notification.alert ? notification.alert : '';
winphone = calculateLength(JSON.stringify(JUtil.extend({'alert': alert}, notification.winphone)));
android = calculateLength(JSON.stringify(JUtil.extend({'alert': alert}, notification.android)));
}
if (message != null) {
var msg_length = calculateLength(JSON.stringify(message));
winphone += msg_length;
android += msg_length;
}
return ios || winphone > 1000 || android > 1000;
}
// ------ PushPayload prototype
PushPayload.prototype.setPlatform = setPlatform;
PushPayload.prototype.setAudience = setAudience;
PushPayload.prototype.setNotification = setNotification;
PushPayload.prototype.setMessage = setMessage;
PushPayload.prototype.setOptions = setOptions;
PushPayload.prototype.toJSON = toJSON;
PushPayload.prototype.send = send;
PushPayload.prototype.isIosExceedLength = isIosExceedLength;
PushPayload.prototype.isGlobalExceedLength = isGlobalExceedLength;
PushPayload.prototype.sendValidate = sendValidate;
// ------ private constant define ------
var VALID_DEVICE_TYPES = ["ios", "android", "winphone"];
var DISABLE_SOUND = 'DISABLE_SOUND'
var DISABLE_BADGE = -1;
var MIN_SENDNO = 100000;
var MAX_SENDNO = 4294967294;
var ALL = 'all';
// ------ exports constants and methods -------
exports.ALL = ALL;
exports.DISABLE_SOUND = DISABLE_SOUND;
exports.DISABLE_BADGE = DISABLE_BADGE;
exports.tag = tag;
exports.tag_and = tag_and;
exports.alias = alias;
exports.registration_id = registration_id;
exports.ios = ios;
exports.android = android;
exports.winphone = winphone;
//class
exports.PushPayload = PushPayload;