Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

sns-mobile

Package Overview
Dependencies
Maintainers
1
Versions
8
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

sns-mobile - npm Package Compare versions

Comparing version 1.1.0 to 1.2.0

261

lib/interface.js

@@ -23,3 +23,13 @@ 'use strict';

ATTRIBUTES_UPDATED: 'attributesUpdated',
ATTRIBUTES_UPDATE_FAILED: 'attributesUpdateFailed'
ATTRIBUTES_UPDATE_FAILED: 'attributesUpdateFailed',
TOPIC_CREATED: 'topicCreated',
CREATE_TOPIC_FAILED: 'createTopicFailed',
TOPIC_DELETED: 'topicDeleted',
DELETE_TOPIC_FAILED: 'deleteTopicFailed',
SUBSCRIBED: 'subscribed',
SUBSCRIBE_FAILED: 'subscribeFailed',
UNSUBSCRIBED: 'unsubscribed',
UNSUBSCRIBE_FAILED: 'unsubscribeFailed',
PUBLISH_FAILED: 'publishFailed',
PUBLISHED_MESSAGE: 'publishedMessage'
};

@@ -176,3 +186,3 @@

};
this.sns.setEndpointAttributes(params, function(err, res) {
this.sns.setEndpointAttributes(params, function(err) {
if (!err) {

@@ -336,4 +346,245 @@ self.emit(EMITTED_EVENTS.ATTRIBUTES_UPDATED, endpointArn, attributes);

/**
* Send a message to an Android or iOS device.
* Create a topic.
* @param {String} name
* @param {Function} callback
*/
Interface.prototype.createTopic = function(name, callback) {
var params = {
Name: name
};
var self = this;
self.sns.createTopic(params, function(err, res) {
if (err) {
self.emit(EMITTED_EVENTS.CREATE_TOPIC_FAILED, name, err);
return callback(err);
}
if (!res || !res.TopicArn) {
return callback(new Error('Response or TopicArn is null'));
}
self.emit(EMITTED_EVENTS.TOPIC_CREATED, res.TopicArn, name);
callback(null, res.TopicArn);
});
};
/**
* Delete a topic.
* @param {String} topicArn
* @param {Function} callback
*/
Interface.prototype.deleteTopic = function(topicArn, callback) {
var params = {
TopicArn: topicArn
};
var self = this;
self.sns.deleteTopic(params, function(err) {
if (err) {
self.emit(EMITTED_EVENTS.DELETE_TOPIC_FAILED, topicArn, err);
return callback(err);
}
self.emit(EMITTED_EVENTS.TOPIC_DELETED, topicArn);
callback();
});
};
/**
* Get all topics for this account.
* @param {Function} callback
*/
Interface.prototype.getTopics = function(callback) {
var topics = [];
var self = this;
var nextToken;
async.doWhilst(function(next) {
self._getTopics(nextToken, function(err, res) {
if (err) {
return next(err);
}
nextToken = res.NextToken;
if (res.Topics && res.Topics.length) {
topics = topics.concat(res.Topics);
}
next();
});
}, function() {
return !!nextToken;
}, function(err) {
if (err) {
return callback(err);
}
callback(null, topics);
});
};
/**
* Get topics with the given NextToken (for paging).
* @param {String} nextToken
* @param {Function} callback
*/
Interface.prototype._getTopics = function(nextToken, callback) {
var params = {};
if (nextToken) {
params.NextToken = nextToken;
}
this.sns.listTopics(params, callback);
};
/**
* Get subscriptions; either all subscriptions for this account or those for the topic ARN specified.
* @param {String} topicArn
* @param {Function} callback
*/
Interface.prototype.getSubscriptions = function(topicArn, callback) {
if (typeof topicArn === 'function') {
callback = topicArn;
topicArn = undefined;
}
var subscriptions = [];
var self = this;
var nextToken;
async.doWhilst(function(next) {
self._getSubscriptions(nextToken, topicArn, function(err, res) {
if (err) {
return next(err);
}
nextToken = res.NextToken;
if (res.Subscriptions && res.Subscriptions.length) {
subscriptions = subscriptions.concat(res.Subscriptions);
}
next();
});
}, function() {
return !!nextToken;
}, function(err) {
if (err) {
return callback(err);
}
callback(null, subscriptions);
});
};
/**
* Get subscriptions with the given NextToken (for paging).
* @param {String} nextToken
* @param {String} topicArn
* @param {Function} callback
*/
Interface.prototype._getSubscriptions = function(nextToken, topicArn, callback) {
var params = {};
if (nextToken) {
params.NextToken = nextToken;
}
if (!topicArn) {
this.sns.listSubscriptions(params, callback);
return;
}
params.TopicArn = topicArn;
this.sns.listSubscriptionsByTopic(params, callback);
};
/**
* Subscribe an endpoint to a topic.
* @param {String} endpointArn
* @param {String} topicArn
* @param {Function} callback
*/
Interface.prototype.subscribe = function(endpointArn, topicArn, callback) {
var params = {
Endpoint: endpointArn,
TopicArn: topicArn,
Protocol: 'application'
};
var self = this;
self.sns.subscribe(params, function(err, res) {
if (err) {
self.emit(EMITTED_EVENTS.SUBSCRIBE_FAILED, endpointArn, topicArn, err);
return callback(err);
}
if (!res || !res.SubscriptionArn) {
return callback(new Error('Response or SubscriptionArn is null'));
}
self.emit(EMITTED_EVENTS.SUBSCRIBED, res.SubscriptionArn, endpointArn, topicArn);
callback(null, res.SubscriptionArn);
});
};
/**
* Unsubscribe an endpoint from a topic via its SubscriptionArn.
* @param {String} subscriptionArn
* @param {Function} callback
*/
Interface.prototype.unsubscribe = function(subscriptionArn, callback) {
var params = {
SubscriptionArn: subscriptionArn
};
var self = this;
self.sns.unsubscribe(params, function(err) {
if (err) {
self.emit(EMITTED_EVENTS.UNSUBSCRIBE_FAILED, subscriptionArn, err);
return callback(err);
}
self.emit(EMITTED_EVENTS.UNSUBSCRIBED, subscriptionArn);
callback();
});
};
/**
* Publish a message to a topic identified by its topic ARN.
* Message is JSON object.
* @param {String} topicArn
* @param {Object} message
* @param {Function} callback
*/
Interface.prototype.publishToTopic = function(topicArn, message, callback) {
if (!validateMessageStructure(message)) {
return callback(new Error('Argument "message" must be in SNS multi-platform publishing format.'));
}
var self = this;
self.sns.publish({
Message: JSON.stringify(message),
TopicArn: topicArn,
MessageStructure: 'json',
}, function(err, res) {
if (err) {
self.emit(EMITTED_EVENTS.PUBLISH_FAILED, topicArn, err);
return callback(err);
}
if (!res || !res.MessageId) {
return callback(new Error('Response or MessageId is null'));
}
self.emit(EMITTED_EVENTS.PUBLISHED_MESSAGE, topicArn, res.MessageId);
callback(null, res.MessageId);
});
function validateMessageStructure(message) {
if (!message.default) {
return false;
}
if (typeof message.default !== 'string') {
return false;
}
return true;
}
};
/**
* Send a message to an Android or iOS device identified by its Endpoint ARN.
* Message is JSON object.
* @param {String} endpointArn

@@ -475,4 +726,4 @@ * @param {Object} message

}
} else if (message != null && typeof message === 'object') {
if(message.GCM || message.ADM || message.default) {
} else if (message && typeof message === 'object') {
if (message.GCM || message.ADM || message.default) {
callback(null, message);

@@ -479,0 +730,0 @@ } else {

13

package.json
{
"name": "sns-mobile",
"version": "1.1.0",
"description": "Push notifications to Android, Kindle Fire, and iOS devices easily using this module.",
"version": "1.2.0",
"description": "Send push notifications to Android, Kindle Fire, and iOS devices easily.",
"main": "index.js",
"scripts": {
"test": "mocha test/"
"test": "mocha test/",
"test-debug": "mocha --debug-brk test/"
},

@@ -21,3 +22,7 @@ "bugs": {

"gcm",
"kindle",
"fire",
"push",
"ios",
"android",
"notification",

@@ -28,3 +33,3 @@ "simple notification service"

"async": "0.2.10",
"aws-sdk": "2.0.0-rc3"
"aws-sdk": "2.1.5"
},

@@ -31,0 +36,0 @@ "devDependencies": {

@@ -8,2 +8,8 @@ # Important Update

## Installation
```sh
npm install sns-mobile
```
## Setting Up a User for SNS

@@ -36,3 +42,3 @@ To use Amazon SNS you need a Secret Access Key and an Access Key Id. Getting these will require you to create a user under the IAM section of AWS and attach a User Policy with the following Policy Document:

```javascript
var SNS = require('sns-push-mobile'),
var SNS = require('sns-mobile'),
EVENTS = SNS.EVENTS;

@@ -74,2 +80,8 @@

## Running Tests
```sh
SNS_KEY_ID="<your_sns_key_id>" SNS_ACCESS_KEY="<your_sns_access_key>" SNS_ANDROID_ARN="arn:aws:sns:..." npm test
```
## Events Emitted

@@ -91,2 +103,12 @@ Instances created will emit events as listed below and callbacks should have the shown format. Event strings can be accessed as shown below.

// EVENTS.ATTRIBUTES_UPDATED
// EVENTS.TOPIC_CREATED
// EVENTS.CREATE_TOPIC_FAILED
// EVENTS.TOPIC_DELETED
// EVENTS.DELETE_TOPIC_FAILED
// EVENTS.SUBSCRIBED
// EVENTS.SUBSCRIBE_FAILED
// EVENTS.UNSUBSCRIBED
// EVENTS.UNSUBSCRIBE_FAILED
// EVENTS.PUBLISH_FAILED
// EVENTS.PUBLISHED_MESSAGE

@@ -162,3 +184,62 @@ var myApp = new SNS({

#### topicCreated
```
function (topicArn, topicName) {}
```
Emitted when a topic has been created successfully.
#### createTopicFailed
```
function (topicName) {}
```
Emitted when an attempt to create a topic has failed.
#### topicDeleted
```
function (topicArn) {}
```
Emitted when a topic has been deleted successfully.
#### deleteTopicFailed
```
function (topicArn) {}
```
Emitted when an attempt to delete a topic has failed.
#### subscribed
```
function (subscriptionArn, endpointArn, topicArn) {}
```
Emitted when an endpoint has been subscribed to a topic successfully.
#### subscribeFailed
```
function (endpointArn, topicArn, err) {}
```
Emitted when an attempt to subscribe an endpoint to a topic has failed.
#### unsubscribed
```
function (subscriptionArn) {}
```
Emitted when an endpoint has been unsubscribed from a topic successfully.
#### unsubscribeFailed
```
function (subscriptionArn, err) {}
```
Emitted when an attempt to unsubscribe an endpoint from a topic has failed.
#### publishedMessage
```
function (topicArn, messageId) {}
```
Emitted when a message has been published to a topic successfully.
#### publishFailed
```
function (topicArn, err) {}
```
Emitted when an attempt to publish a message to a topic has failed.
## API

@@ -201,5 +282,14 @@

#### getTopics(callback)
Get all topics by paging through them. The callback(err, topics) receives an Array containing topic objects.
#### getSubscriptions(topicArn, callback)
Get all subscriptions for the topic with the given topicArn by paging through them. The callback(err, subscriptions) receives an Array containing subscription objects.
#### addUser(deviceToken, [data], callback)
Add a device/user to SNS with optional extra data. Callback has format fn(err, endpointArn).
#### createTopic(name, callback)
Create a new topic with the given name. The callback has the format fn(err, topicArn).
#### setAttributes(endpointArn, attributes, callback)

@@ -217,5 +307,28 @@ Update an existing endpoint's attributes. Attributes is an object with the following optional properties:

#### deleteTopic(topicArn, callback)
Delete the topic with the given topicArn. The callback has the format fn(err).
#### sendMessage(endpointArn, message, callback)
Send a message to a user. The _message_ parameter can be a String, or an Object with the formats below. The callback format is callback(err, messageId).
#### subscribe(endpointArn, topicArn, callback)
Subscribe an endpoint to a topic. The callback has the format fn(err, subscriptionArn).
#### unsubscribe(subscriptionArn, callback)
Unsubscribe an endpoint from a topic via the given subscriptionArn. The callback has the format fn(err).
#### publishToTopic(topicArn, message, callback)
Publish a message a topic. The callback has the format fn(err, messageId).
Please note that the message *must* be in the final Amazon SNS format as
specified [here](http://docs.aws.amazon.com/sns/latest/dg/mobile-push-send-custommessage.html#mobile-push-send-multiplatform), i.e. it
*must* contain a key called `default` and platform-specific messages *must* already be JSON-stringified. Example:
```json
{
"default": "Default message which must be present when publishing a message to a topic. Will only be used if a message is not present for one of the notification platforms.",
"APNS": "{\"aps\":{\"alert\": \"Check out these awesome deals!\",\"url\":\"www.amazon.com\"} }",
"GCM":"{\"data\":{\"message\":\"Check out these awesome deals!\",\"url\":\"www.amazon.com\"}}"
}
```
You can read about Amazon SNS message formats [here](http://docs.aws.amazon.com/sns/latest/dg/mobile-push-send-custommessage.html).

@@ -225,3 +338,3 @@

```
```js
{

@@ -238,3 +351,3 @@ aps: {

```
```js
{

@@ -258,5 +371,6 @@ data: {

Thanks to these peeps for contributions:
Thanks to these awesome folks for contributions:
* [abiskop](https://github.com/abiskop)
* [iclems](https://github.com/iclems)
* [race](https://github.com/race)
console.warn('Ensure that SNS_ACCESS_KEY, SNS_KEY_ID and SNS_ANDROID_ARN env vars are set for these tests!\n');
var assert = require('assert'),
SNS = require('../lib/Interface');
SNS = require('../lib/interface');

@@ -20,2 +20,5 @@ var SNS_KEY_ID = process.env['SNS_KEY_ID'],

var theTopicArnThatThisTestCreated;
var theSubscriptionArnThatThisTestCreated;
it('Should have events and supported platforms exposed on the interface', function() {

@@ -31,4 +34,4 @@ assert(SNS.SUPPORTED_PLATFORMS);

apiVersion: '2010-03-31',
accessKeyId: SNS_ACCESS_KEY,
secretAccessKey: SNS_KEY_ID,
accessKeyId: SNS_KEY_ID,
secretAccessKey: SNS_ACCESS_KEY,
platformApplicationArn: ANDROID_ARN

@@ -45,4 +48,4 @@ });

apiVersion: '2010-03-31',
accessKeyId: SNS_ACCESS_KEY,
secretAccessKey: SNS_KEY_ID,
accessKeyId: SNS_KEY_ID,
secretAccessKey: SNS_ACCESS_KEY,
platformApplicationArn: ANDROID_ARN

@@ -63,4 +66,4 @@ });

apiVersion: '2010-03-31',
accessKeyId: SNS_ACCESS_KEY,
secretAccessKey: SNS_KEY_ID,
accessKeyId: SNS_KEY_ID,
secretAccessKey: SNS_ACCESS_KEY,
platformApplicationArn: ANDROID_ARN

@@ -189,3 +192,3 @@ });

assert(res);
assert(typeof res === 'string');
assert.strictEqual(typeof res, 'string');
done();

@@ -195,2 +198,122 @@ })

});
it('Should create a topic.', function(done) {
sns.createTopic('this_is_a_test_dummy_486438735', function(err, topicArn) {
assert(!err);
assert(topicArn);
theTopicArnThatThisTestCreated = topicArn;
done();
});
});
it('Should list topics.', function(done) {
sns.getTopics(function(err, topics) {
assert(!err);
assert(topics);
assert(topics.length > 0);
var theTopicThatWasCreatedEarlier = topics.filter(function(topic) {
return topic.TopicArn === theTopicArnThatThisTestCreated;
})[0];
assert(theTopicThatWasCreatedEarlier)
done();
});
});
it('Should subscribe a user to a topic.', function(done) {
sns.addUser('yetanotherfakedeviceid', JSON.stringify({
username: 'anotherfakeuser'
}), function(err, endpointArn) {
sns.subscribe(endpointArn, theTopicArnThatThisTestCreated, function(err, subscriptionArn) {
assert(!err);
assert(subscriptionArn);
theSubscriptionArnThatThisTestCreated = subscriptionArn;
done();
});
});
});
it('Should list all subscriptions.', function(done) {
sns.getSubscriptions(function(err, subscriptions) {
assert(!err);
assert(subscriptions);
assert(subscriptions.length > 0);
var theSubscriptionThatWasCreatedEarlier = subscriptions.filter(function(subscription) {
return subscription.SubscriptionArn === theSubscriptionArnThatThisTestCreated;
})[0];
assert(theSubscriptionThatWasCreatedEarlier)
done();
});
});
it('Should list subscriptions by topic.', function(done) {
sns.getSubscriptions(theTopicArnThatThisTestCreated, function(err, subscriptions) {
assert(!err);
assert(subscriptions);
assert(subscriptions.length > 0);
var theSubscriptionThatWasCreatedEarlier = subscriptions.filter(function(subscription) {
return subscription.SubscriptionArn === theSubscriptionArnThatThisTestCreated;
})[0];
assert(theSubscriptionThatWasCreatedEarlier)
done();
});
});
it('Should fail to publish a message to a topic if message body is missing "default" key.', function(done) {
sns.publishToTopic(theTopicArnThatThisTestCreated, {
foo: 'missing top-level key "default"'
}, function(err, res) {
assert(err);
assert.equal(err.message, 'Argument "message" must be in SNS multi-platform publishing format.');
done();
})
});
it('Should fail to publish a message to a topic if "default" value in message body is not a string.', function(done) {
sns.publishToTopic(theTopicArnThatThisTestCreated, {
'default': {
that: 'is_not_a_string_but_an_object'
}
}, function(err, res) {
assert(err);
assert.equal(err.message, 'Argument "message" must be in SNS multi-platform publishing format.');
done();
})
});
it('Should publish a message to a topic.', function(done) {
var messageBody = {
'default': JSON.stringify({
data: 'Hello Topic',
moreData: 'Hello Topic'
}),
'APNS': JSON.stringify({
aps: {
alert: 'test dummy text'
}
}),
'GCM': JSON.stringify({
some: 'value'
})
}
sns.publishToTopic(theTopicArnThatThisTestCreated, messageBody, function(err, res) {
assert(!err);
assert(res);
assert.strictEqual(typeof res, 'string');
done();
})
});
it('Should unsubscribe a user from a topic.', function(done) {
sns.unsubscribe(theSubscriptionArnThatThisTestCreated, function(err) {
assert(!err);
done();
});
});
it('Should delete a topic.', function(done) {
sns.deleteTopic(theTopicArnThatThisTestCreated, function(err) {
assert(!err);
done();
});
});
});

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc