Comparing version 1.1.0 to 1.1.1
115
lib/mpns.js
@@ -16,17 +16,16 @@ // Copyright Jeff Wilcox | ||
var url = require('url'); | ||
var http = require('http'); | ||
// NOTES: | ||
// | ||
// This library is designed for Windows Phone 7.1 and 8.0 OS. To send push to | ||
// a 7.0 device, the developer must not include the param value (toast) or | ||
// any of the advanced back background tile images (tiles). | ||
// Important note about Windows Phone 7.5: | ||
// --- | ||
// This library supports functions unique to Mango. If you provide the | ||
// Mango-specific values (param, backBackgroundImage, etc.) to a | ||
// Windows Phone 7 (original 7.0 or NoDo) device, the toast/tile will | ||
// not be accepted. | ||
// Suggested fallback values if you're storing results in a document/db. | ||
// See also: http://msdn.microsoft.com/en-us/library/ff941100%28v=VS.92%29.aspx | ||
var HTTP_412_MINIMUM_DELAY = 61; // minutes | ||
var ERROR_MINIMUM_DELAY = 5; // minutes | ||
var HTTP_412_MINIMUM_DELAY_MINUTES = 61; | ||
var ERROR_MINIMUM_DELAY_MINUTES = 5; | ||
var url = require('url'); | ||
var http = require('http'); | ||
var Toast = function(options) { | ||
@@ -81,3 +80,3 @@ return new PushMessage('toast', '2', 'toast', options); | ||
var result = { }; | ||
var err = null; | ||
var err = undefined; | ||
@@ -91,5 +90,7 @@ var req = http.request(options, function(res) { | ||
if (res.headers) { | ||
result.deviceConnectionStatus = res.headers['x-deviceconnectionstatus']; | ||
result.notificationStatus = res.headers['x-notificationstatus']; | ||
result.subscriptionStatus = res.headers['x-subscriptionstatus']; | ||
renameFieldsOfInterest(res.headers, result, { | ||
'x-deviceconnectionstatus': 'deviceConnectionStatus', | ||
'x-notificationstatus': 'notificationStatus', | ||
'x-subscriptionstatus' : 'subscriptionStatus' | ||
}); | ||
} | ||
@@ -100,22 +101,44 @@ | ||
if (res.statusCode == '412') { | ||
result.minutesToDelay = HTTP_412_MINIMUM_DELAY; // Must be at least an hour. | ||
err = result; | ||
} | ||
switch (res.statusCode) { | ||
// The device is in an inactive state. | ||
case 412: | ||
result.minutesToDelay = HTTP_412_MINIMUM_DELAY_MINUTES; // Must be at least an hour. | ||
err = result; | ||
break; | ||
if (res.statusCode == '404') { | ||
result.shouldDeleteChannel = true; | ||
err = result; | ||
// Invalid subscriptions. | ||
case 400: | ||
case 401: | ||
case 404: | ||
result.shouldDeleteChannel = true; | ||
err = result; | ||
break; | ||
// Method Not Allowed (bug in this library) | ||
case 405: | ||
err = result; | ||
break; | ||
case 406: | ||
err = result; | ||
err.error = 'Per-day throttling limit reached.'; | ||
break; | ||
case 503: | ||
err = result; | ||
result.minutesToDelay = ERROR_MINIMUM_DELAY_MINUTES; | ||
err.error = 'The Push Notification Service is unable to process the request.'; | ||
break; | ||
} | ||
if (callback) { | ||
callback(err, result); | ||
} | ||
if (callback) | ||
callback(err, err === undefined ? result : undefined); | ||
}).on('error', function(e) { | ||
result.minutesToDelay = ERROR_MINIMUM_DELAY; // Just a recommendation. | ||
result.minutesToDelay = ERROR_MINIMUM_DELAY_MINUTES; // Just a recommendation. | ||
err = result; | ||
err.error = e; | ||
if (callback) { | ||
callback(err, result); | ||
} | ||
if (callback) | ||
callback(err); | ||
}); | ||
@@ -130,3 +153,3 @@ }); | ||
function copyOfInterest(source, destination, fieldsOfInterest) { | ||
if (source && destination && fieldsOfInterest && fieldsOfInterest.length > 0) { | ||
if (source && destination && fieldsOfInterest && fieldsOfInterest.length) { | ||
for (var i = 0; i < fieldsOfInterest.length; i++) { | ||
@@ -141,2 +164,13 @@ var key = fieldsOfInterest[i]; | ||
function renameFieldsOfInterest(source, destination, map) { | ||
if (source && destination && map) { | ||
for (var key in map) { | ||
var newKey = map[key]; | ||
if (source[key]) { | ||
destination[newKey] = source[key]; | ||
} | ||
} | ||
} | ||
} | ||
PushMessage.prototype.getXmlPayload = function() { | ||
@@ -154,4 +188,4 @@ this.validate(); | ||
PushMessage.prototype.validate = function() { | ||
if (this.pushType != 'toast' && this.pushType != 'tile') { | ||
throw new Error("Only 'toast' and 'tile' push types are currently supported."); | ||
if (this.pushType != 'toast' && this.pushType != 'tile' && this.pushType != 'raw') { | ||
throw new Error("Only 'toast', 'tile' and 'raw' push types are currently supported."); | ||
} | ||
@@ -226,2 +260,6 @@ }; | ||
var pushUri = Array.prototype.shift.apply(args); | ||
if (typeof pushUri !== 'string') | ||
throw new Error('The pushUri parameter must be the push notification channel URI string.'); | ||
var params = []; | ||
@@ -242,4 +280,13 @@ if (typeof args[0] === 'object') { | ||
if (type == 'toast' && typeof params.text1 !== 'string') | ||
throw new Error('The text1 toast parameter must be set and a string.'); | ||
if (type == 'tile' && params.length == 0) | ||
throw new Error('At least 1 tile parameter must be set.'); | ||
var callback = args[0]; | ||
if (callback && typeof callback !== 'function') | ||
throw new Error('The callback parameter, if specified, must be the callback function.'); | ||
var instance = new objectType(params); | ||
@@ -267,4 +314,6 @@ instance.send(pushUri, callback); | ||
// These object constructors are effectively deprecated. Consider using | ||
// sendToast, sendTile or sendRawNotification methods going forward. | ||
exports.liveTile = LiveTile; | ||
exports.toast = Toast; | ||
exports.rawNotification = RawNotification; |
{ | ||
"name": "mpns", | ||
"description": "A Node.js interface to the Microsoft Push Notification Service (MPNS) for Windows Phone.", | ||
"version": "1.1.0", | ||
"version": "1.1.1", | ||
"author": "Jeff Wilcox <jeffwilcox+github@gmail.com>", | ||
@@ -6,0 +6,0 @@ "contributors": [ |
@@ -134,2 +134,6 @@ #mpns | ||
1.1.1: | ||
* Adds parameter validation that will throw, for robustness. | ||
1.1.0: | ||
@@ -136,0 +140,0 @@ |
Sorry, the diff of this file is not supported yet
17931
258
162