{"_id":"@calvinckho/node-pushnotifications","_rev":"1-9f57adda460cf034dd893ce6472b9444","name":"@calvinckho/node-pushnotifications","dist-tags":{"latest":"1.4.0"},"versions":{"1.4.0":{"name":"@calvinckho/node-pushnotifications","description":"A cross-platform push service for node.js","version":"1.4.0","author":{"name":"calvinckho","email":"ch235@cornell.edu"},"scripts":{"coveralls":"cat ./coverage/lcov.info | coveralls","test-cover":"nyc --reporter=lcov mocha test/ -- --require @babel/register --recursive; open-cli ./coverage/lcov-report/index.html","test":"mocha test/ --require @babel/register --recursive","build":"babel src -d lib","lint":"eslint {src,test}/**/*.js","format":"prettier --write \"**/*.{js,json,md,yml}\"","ci":"npm run build && npm run test-cover && npm run lint","prepublishOnly":"npm run lint && npm test && npm run build","release":"release-it"},"keywords":["notifications","push","push notifications","apple","ios","iphone","ipad","apns","google","android","gcm","fcm","amazon","kindle","adm","microsoft","windows","wphone","windows phone","wns","mpns","webpush"],"main":"index.js","bugs":{"url":"https://github.com/calvinckho/node-pushnotifications","email":"ch235@cornell.edu"},"repository":{"type":"git","url":"git+https://github.com/calvinckho/node-pushnotifications.git"},"dependencies":{"@parse/node-apn":"3.1.0","node-adm":"0.9.1","node-gcm":"1.0.2","ramda":"0.27.0","web-push":"3.4.4","wns":"0.5.4"},"devDependencies":{"@babel/cli":"7.10.1","@babel/core":"7.10.2","@babel/preset-env":"7.10.2","@babel/register":"7.10.1","chai":"4.2.0","coveralls":"3.1.0","dirty-chai":"2.0.1","eslint":"7.2.0","eslint-config-airbnb-base":"14.2.0","eslint-config-prettier":"6.11.0","eslint-plugin-import":"2.21.2","eslint-plugin-prettier":"3.1.3","husky":"4.2.5","mocha":"8.0.1","nyc":"15.1.0","opn-cli":"5.0.0","prettier":"2.0.5","pretty-quick":"2.0.1","release-it":"13.6.5","sinon":"1.17.7","sinon-chai":"3.5.0"},"engines":{"node":">=6.x.x"},"eslintConfig":{"ecmaVersion":6,"env":{"es6":true,"node":true}},"husky":{"hooks":{"pre-commit":"pretty-quick --staged"}},"homepage":"https://github.com/appfeel/node-pushnotifications","license":"MIT","contributors":[{"name":"Alexander Friedl","email":"mail@alexanderfriedl.com","url":"https://github.com/alex-friedl"}],"gitHead":"0e6cf47b80e33f7298f84870798856726e7f9f7c","_id":"@calvinckho/node-pushnotifications@1.4.0","_nodeVersion":"10.22.0","_npmVersion":"6.14.6","dist":{"integrity":"sha512-cQY0KX7p8LZGOiYPRVGUmUSXZMmzdSGAtGgMDsD5TPLh5rZAgcFibEMRGRTixP0JXdEs8RXUVi+8+Zh+nYCQpw==","shasum":"cb3485e89e4881a6a2bb0ef93247bbd8e5f9fe06","tarball":"https://registry.npmjs.org/@calvinckho/node-pushnotifications/-/node-pushnotifications-1.4.0.tgz","fileCount":21,"unpackedSize":185210,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfG20aCRA9TVsSAnZWagAA3c4P/2J/s5yR3YjWlzrpyCZj\nhVZioWkYZaBsXGl4DGm7HPEHx9CmeUm7egoh+Zbb3y03PzfLborEzpBe+Xci\nduVcRglvbXwCbt7BtYSlfH/HTlaNjvSk7rZOYBPxWd4iehxEBe4CkHn/5Ma7\nNWOo3vV73JHrIFqVIx0vlXlvHQjcqgoDx9M1FwHwyBn1geXhRJgPsxlFN0Mn\nsYR3wuXNsHxTxAvt17QrWRkmT5VGjq4+jkZJrhDeTlyW310+FWzhNCYnd1w0\nnSzcO3uFec1R8SPbmPeLXXMFdDD6lx3svp98i70OQ0cNTQsxk/qaAzxHxR3+\nXZSq8XgQK+qN12Uip25dj8Qt64q/4iG6AOb7ERFqgc8t+RPoLBddOr9vyQFx\nUaYjjHAAOtcq2mgnadAwVtnzBOeOVvO/s2euHOOionSQPgSqBH3ZgHsuFY8d\nKNZxe9WRAwbm/MlPspiZaYUTtp5Mni2bpny9ntHRjpG12VMb/dCI9K9ElX88\nT77E9ZLqSDVoUEa7LeCT/+Rdz0Q34/PDoOLWtGIsIbghTJc0qv0D9P5CbXr2\nRBbYtipp+PgLbOaWtdacFNEbfDq/mWU1I6d6EPPSIi3ToDyRJBqyeQKizFeL\nM5w//eTChMdLepyy4KXcwCXJWe3jSwfz+hIHnUq68jz4enbFl04pQz5h7Eed\nEFzL\r\n=UQRW\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCcA172TdodN1oWyxTi0FTE1WHuaEu7yKqQbYbx0DL58AIgPbpLGZ3SZHhM0FRUFXHsB4283FQaxyorQWMcSGHfH/E="}]},"maintainers":[{"name":"calvinckho","email":"ch235@cornell.edu"}],"_npmUser":{"name":"calvinckho","email":"ch235@cornell.edu"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/node-pushnotifications_1.4.0_1595632921988_0.4009022722047715"},"_hasShrinkwrap":false}},"time":{"created":"2020-07-24T23:22:01.950Z","1.4.0":"2020-07-24T23:22:02.280Z","modified":"2022-04-04T21:33:36.505Z"},"maintainers":[{"name":"calvinckho","email":"ch235@cornell.edu"}],"description":"A cross-platform push service for node.js","homepage":"https://github.com/appfeel/node-pushnotifications","keywords":["notifications","push","push notifications","apple","ios","iphone","ipad","apns","google","android","gcm","fcm","amazon","kindle","adm","microsoft","windows","wphone","windows phone","wns","mpns","webpush"],"repository":{"type":"git","url":"git+https://github.com/calvinckho/node-pushnotifications.git"},"contributors":[{"name":"Alexander Friedl","email":"mail@alexanderfriedl.com","url":"https://github.com/alex-friedl"}],"author":{"name":"calvinckho","email":"ch235@cornell.edu"},"bugs":{"url":"https://github.com/calvinckho/node-pushnotifications","email":"ch235@cornell.edu"},"license":"MIT","readme":"# Node Push Notifications\n\nA node.js module for interfacing with Apple Push Notification, Google Cloud Messaging, Windows Push Notification, Web-Push Notification and Amazon Device Messaging services.\n\n[![License](http://img.shields.io/badge/license-MIT-blue.svg?style=flat)](https://npmjs.org/package/node-pushnotifications)\n[![NPM version](http://img.shields.io/npm/v/node-pushnotifications.svg?style=flat)](https://npmjs.org/package/node-pushnotifications)\n[![Downloads](http://img.shields.io/npm/dm/node-pushnotifications.svg?style=flat)](https://npmjs.org/package/node-pushnotifications)\n[![Build Status](http://img.shields.io/travis/appfeel/node-pushnotifications.svg?style=flat)](https://travis-ci.org/appfeel/node-pushnotifications)\n[![Coverage Status](https://coveralls.io/repos/github/appfeel/node-pushnotifications/badge.svg?branch=master)](https://coveralls.io/github/appfeel/node-pushnotifications?branch=master)\n[![Dependencies](https://david-dm.org/appfeel/node-pushnotifications/status.svg)](https://david-dm.org/appfeel/node-pushnotifications)\n[![code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square)](https://github.com/prettier/prettier)\n\n- [Installation](#installation)\n- [Requirements](#requirements)\n- [Features](#features)\n- [Usage](#usage)\n- [GCM](#gcm)\n- [APN](#apn)\n- [WNS](#wns)\n- [ADM](#adm)\n- [Web-Push](#web-push)\n- [Resources](#resources)\n- [LICENSE](#license)\n\n## Installation\n\n```bash\nnpm install node-pushnotifications --save\n```\n\n## Requirements\n\nNode version >= 6.x.x\n\n## Features\n\n- Powerful and intuitive.\n- Multi platform push notifications.\n- Automatically detects destination device type.\n- Unified error handling.\n- Written in ES6, compatible with ES5 through babel transpilation.\n\n## Usage\n\n### 1. Import and setup push module\n\nInclude the settings for each device type. You should only include the settings for the devices that you expect to have. I.e. if your app is only available for android or for ios, you should only include `gcm` or `apn` respectively.\n\n```js\nimport PushNotifications from 'node-pushnotifications';\n\nconst settings = {\n    gcm: {\n        id: null,\n        phonegap: false, // phonegap compatibility mode, see below (defaults to false)\n        ...\n    },\n    apn: {\n        token: {\n            key: './certs/key.p8', // optionally: fs.readFileSync('./certs/key.p8')\n            keyId: 'ABCD',\n            teamId: 'EFGH',\n        },\n        production: false // true for APN production environment, false for APN sandbox environment,\n        ...\n    },\n    adm: {\n        client_id: null,\n        client_secret: null,\n        ...\n    },\n    wns: {\n        client_id: null,\n        client_secret: null,\n        notificationMethod: 'sendTileSquareBlock',\n        ...\n    },\n    web: {\n        vapidDetails: {\n            subject: '< \\'mailto\\' Address or URL >',\n            publicKey: '< URL Safe Base64 Encoded Public Key >',\n            privateKey: '< URL Safe Base64 Encoded Private Key >',\n        },\n        gcmAPIKey: 'gcmkey',\n        TTL: 2419200,\n        contentEncoding: 'aes128gcm',\n        headers: {}\n    },\n    isAlwaysUseFCM: false, // true all messages will be sent through node-gcm (which actually uses FCM)\n};\nconst push = new PushNotifications(settings);\n```\n\n- GCM options: see [node-gcm](https://github.com/ToothlessGear/node-gcm#custom-gcm-request-options)\n- APN options: see [node-apn](https://github.com/node-apn/node-apn/blob/master/doc/provider.markdown)\n- ADM options: see [node-adm](https://github.com/umano/node-adm)\n- WNS options: see [wns](https://github.com/tjanczuk/wns)\n- Web-push options: see [web-push](https://github.com/web-push-libs/web-push)\n\n* `isAlwaysUseFCM`: use node-gcm to send notifications to GCM (by default), iOS, ADM and WNS.\n\n_iOS:_ It is recommended to use [provider authentication tokens](https://developer.apple.com/library/content/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/CommunicatingwithAPNs.html). You need the .p8 certificate that you can obtain in your [account membership](https://cloud.githubusercontent.com/assets/8225312/20380437/599a767c-aca2-11e6-82bd-3cbfc2feee33.png). You should ask for an _Apple Push Notification Authentication Key (Sandbox & Production)_ or _Apple Push Notification service SSL (Sandbox & Production)_. However, you can also use certificates. See [node-apn](https://github.com/node-apn/node-apn/wiki/Preparing-Certificates) to see how to prepare cert.pem and key.pem.\n\n### 2. Define destination device ID\n\nYou can send to multiple devices, independently of platform, creating an array with different destination device IDs.\n\n```js\n// Single destination\nconst registrationIds = 'INSERT_YOUR_DEVICE_ID';\n\n// Multiple destinations\nconst registrationIds = [];\nregistrationIds.push('INSERT_YOUR_DEVICE_ID');\nregistrationIds.push('INSERT_OTHER_DEVICE_ID');\n```\n\n**Android:**\n\n- If you provide more than 1.000 registration tokens, they will automatically be splitted in 1.000 chunks (see [this issue in gcm repo](https://github.com/ToothlessGear/node-gcm/issues/42))\n- You are able to send to device groups or other custom recipients instead of using a list of device tokens (see [node-gcm docs](https://github.com/ToothlessGear/node-gcm#recipients)). Documentation can be found in the GCM section..\n\nExample:\n\n```javascript\nconst data = { ...data, recipients };\n```\n\n### 3. Send the notification\n\nCreate a JSON object with a title and message and send the notification.\n\n```js\nconst data = {\n    title: 'New push notification', // REQUIRED for Android\n    topic: 'topic', // REQUIRED for iOS (apn and gcm)\n    /* The topic of the notification. When using token-based authentication, specify the bundle ID of the app.\n     * When using certificate-based authentication, the topic is usually your app's bundle ID.\n     * More details can be found under https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/sending_notification_requests_to_apns\n     */\n    body: 'Powered by AppFeel',\n    custom: {\n        sender: 'AppFeel',\n    },\n    priority: 'high', // gcm, apn. Supported values are 'high' or 'normal' (gcm). Will be translated to 10 and 5 for apn. Defaults to 'high'\n    collapseKey: '', // gcm for android, used as collapseId in apn\n    contentAvailable: true, // gcm, apn. node-apn will translate true to 1 as required by apn.\n    delayWhileIdle: true, // gcm for android\n    restrictedPackageName: '', // gcm for android\n    dryRun: false, // gcm for android\n    icon: '', // gcm for android\n    image: '', // gcm for android\n    style: '', // gcm for android\n    picture: '', // gcm for android\n    tag: '', // gcm for android\n    color: '', // gcm for android\n    clickAction: '', // gcm for android. In ios, category will be used if not supplied\n    locKey: '', // gcm, apn\n    locArgs: '', // gcm, apn\n    titleLocKey: '', // gcm, apn\n    titleLocArgs: '', // gcm, apn\n    retries: 1, // gcm, apn\n    encoding: '', // apn\n    badge: 2, // gcm for ios, apn\n    sound: 'ping.aiff', // gcm, apn\n    android_channel_id: '', // gcm - Android Channel ID\n    notificationCount: 0, // fcm for android. badge can be used for both fcm and apn\n    alert: { // apn, will take precedence over title and body\n        title: 'title',\n        body: 'body'\n        // details: https://github.com/node-apn/node-apn/blob/master/doc/notification.markdown#convenience-setters\n    },\n    silent: false, // apn, will override badge, sound, alert and priority if set to true\n    /*\n     * A string is also accepted as a payload for alert\n     * Your notification won't appear on ios if alert is empty object\n     * If alert is an empty string the regular 'title' and 'body' will show in Notification\n     */\n    // alert: '',\n    launchImage: '', // apn and gcm for ios\n    action: '', // apn and gcm for ios\n    category: '', // apn and gcm for ios\n    // mdm: '', // apn and gcm for ios. Use this to send Mobile Device Management commands.\n    // https://developer.apple.com/library/content/documentation/Miscellaneous/Reference/MobileDeviceManagementProtocolRef/3-MDM_Protocol/MDM_Protocol.html\n    urlArgs: '', // apn and gcm for ios\n    truncateAtWordEnd: true, // apn and gcm for ios\n    mutableContent: 0, // apn\n    threadId: '', // apn\n    pushType: undefined, // apn. valid values are 'alert' and 'background' (https://github.com/parse-community/node-apn/blob/master/doc/notification.markdown#notificationpushtype)\n    expiry: Math.floor(Date.now() / 1000) + 28 * 86400, // unit is seconds. if both expiry and timeToLive are given, expiry will take precedence\n    timeToLive: 28 * 86400,\n    headers: [], // wns\n    launch: '', // wns\n    duration: '', // wns\n    consolidationKey: 'my notification', // ADM\n};\n\n// You can use it in node callback style\npush.send(registrationIds, data, (err, result) => {\n    if (err) {\n        console.log(err);\n    } else {\n\t    console.log(result);\n    }\n});\n\n// Or you could use it as a promise:\npush.send(registrationIds, data)\n    .then((results) => { ... })\n    .catch((err) => { ... });\n```\n\n- `err` will be null if all went fine, otherwise will return the error from the respective provider module.\n- `result` will contain an array with the following objects (one object for each device type found in device registration id's):\n\n```js\n[\n    {\n        method: 'gcm', // The method used send notifications and which this info is related to\n        multicastId: [], // (only Android) Array with unique ID (number) identifying the multicast message, one identifier for each chunk of 1.000 notifications)\n        success: 0, // Number of notifications that have been successfully sent. It does not mean that the notification has been deliveried.\n        failure: 0, // Number of notifications that have been failed to be send.\n        message: [{\n            messageId: '', // (only for android) String specifying a unique ID for each successfully processed message or undefined if error\n            regId: value, // The current registrationId (device token id). Beware: For Android this may change if Google invalidates the previous device token. Use \"originalRegId\" if you are interested in when this changed occurs.\n            originalRegId: value, // (only for android) The registrationId that was sent to the push.send() method. Compare this with field \"regId\" in order to know when the original registrationId (device token id) gets changed.\n            error: new Error('unknown'), // If any, there will be an Error object here for depuration purposes (when possible it will come form source libraries aka apn, node-gcm)\n            errorMsg: 'some error', // If any, will include the error message from the respective provider module\n        }],\n    },\n    {\n        method: 'apn',\n        ... // Same structure here, except for message.orignalRegId\n    },\n    {\n        method: 'wns',\n        ... // Same structure here, except for message.orignalRegId\n    },\n    {\n        method: 'adm',\n        ... // Same structure here, except for message.orignalRegId\n    },\n    {\n        method: 'webPush',\n        ... // Same structure here, except for message.orignalRegId\n    },\n]\n```\n\n## GCM\n\n**NOTE:** If you provide more than 1.000 registration tokens, they will automatically be splitted in 1.000 chunks (see [this issue in gcm repo](https://github.com/ToothlessGear/node-gcm/issues/42))\n\nThe following parameters are used to create a GCM message. See https://developers.google.com/cloud-messaging/http-server-ref#table5 for more info:\n\n```js\n    // Set default custom data from data\n    let custom;\n    if (typeof data.custom === 'string') {\n        custom = {\n            message: data.custom,\n        };\n    } else if (typeof data.custom === 'object') {\n        custom = Object.assign({}, data.custom);\n    } else {\n        custom = {\n            data: data.custom,\n        };\n    }\n\n    custom.title = custom.title || data.title;\n    custom.message = custom.message || data.body;\n    custom.sound = custom.sound || data.sound;\n    custom.icon = custom.icon || data.icon;\n    custom.msgcnt = custom.msgcnt || data.badge;\n    if (opts.phonegap === true && data.contentAvailable) {\n        custom['content-available'] = 1;\n    }\n\n    const message = new gcm.Message({ // See https://developers.google.com/cloud-messaging/http-server-ref#table5\n        collapseKey: data.collapseKey,\n        priority: data.priority === 'normal' ? data.priority : 'high',\n        contentAvailable: data.contentAvailable || false,\n        delayWhileIdle: data.delayWhileIdle || false, // Deprecated from Nov 15th 2016 (will be ignored)\n        timeToLive: data.expiry - Math.floor(Date.now() / 1000) || data.timeToLive || 28 * 86400,\n        restrictedPackageName: data.restrictedPackageName,\n        dryRun: data.dryRun || false,\n        data: data.custom,\n        notification: {\n            title: data.title, // Android, iOS (Watch)\n            body: data.body, // Android, iOS\n            icon: data.icon, // Android\n\t    image: data.image, // Android\n\t    style: data.style, // Android\n   \t    picture: data.picture, // Android\n            sound: data.sound, // Android, iOS\n            badge: data.badge, // iOS\n            tag: data.tag, // Android\n            color: data.color, // Android\n            click_action: data.clickAction || data.category, // Android, iOS\n            body_loc_key: data.locKey, // Android, iOS\n            body_loc_args: data.locArgs, // Android, iOS\n            title_loc_key: data.titleLocKey, // Android, iOS\n            title_loc_args: data.titleLocArgs, // Android, iOS\n\t    android_channel_id: data.android_channel_id, // Android\n        },\n    }\n```\n\n_data is the parameter in `push.send(registrationIds, data)`_\n\n- [See node-gcm fields](https://github.com/ToothlessGear/node-gcm#usage)\n\n**Note:** parameters are duplicated in data and in notification, so in fact they are being send as:\n\n```js\n    data: {\n        title: 'title',\n        message: 'body',\n        sound: 'mySound.aiff',\n        icon: undefined,\n        msgcnt: undefined\n        // Any custom data\n        sender: 'appfeel-test',\n    },\n    notification: {\n        title: 'title',\n        body: 'body',\n        icon: undefined,\n\timage: undefined,\n\tstyle: undefined,\n\tpicture: undefined,\n        sound: 'mySound.aiff',\n        badge: undefined,\n        tag: undefined,\n        color: undefined,\n        click_action: undefined,\n        body_loc_key: undefined,\n        body_loc_args: undefined,\n        title_loc_key: undefined,\n        title_loc_args: undefined,\n\tandroid_channel_id: undefined\n    }\n```\n\nIn that way, they can be accessed in android in the following two ways:\n\n```java\n    String title = extras.getString(\"title\");\n    title = title != null ? title : extras.getString(\"gcm.notification.title\");\n```\n\n### Send to custom recipients (device groups or topics)\n\nIn order to override the default behaviour of sending the notifications to a list of device tokens,\nyou can pass a `recipients` field with your desired recipients. Supported fields are `to` and `condition` as documented in the [node-gcm docs](https://github.com/ToothlessGear/node-gcm#recipients).\n\nExample:\n\n```javascript\nconst dataWithRecipientTo = { ...yourData, recipients: { to: 'topicName' } };\nconst dataWithRecipientCondition = { ...yourData, recipients: { condition: 'topicName' } };\n\npush.send(registrationIds, dataWithRecipientTo)\n    .then((results) => { ... })\n    .catch((err) => { ... });\n```\n\nBe aware that the presence of a valid `data.recipient` field will take precendence over any Android device tokens passed with the `registrationIds`.\n\n### PhoneGap compatibility mode\n\nIn case your app is written with Cordova / Ionic and you are using the [PhoneGap PushPlugin](https://github.com/phonegap/phonegap-plugin-push/),\nyou can use the `phonegap` setting in order to adapt to the recommended behaviour described in\n[https://github.com/phonegap/phonegap-plugin-push/blob/master/docs/PAYLOAD.md#android-behaviour](https://github.com/phonegap/phonegap-plugin-push/blob/master/docs/PAYLOAD.md#android-behaviour).\n\n```js\nconst settings = {\n  gcm: {\n    id: '<yourId>',\n    phonegap: true,\n  },\n};\n```\n\n## APN\n\nThe following parameters are used to create an APN message:\n\n```js\n{\n    retryLimit: data.retries || -1,\n    expiry: data.expiry || ((data.timeToLive || 28 * 86400) + Math.floor(Date.now() / 1000)),\n    priority: data.priority === 'normal' ? 5 : 10,\n    encoding: data.encoding,\n    payload: data.custom || {},\n    badge: data.silent === true ? undefined : data.badge,\n    badge: data.sound === true ? undefined : data.sound,\n    alert: data.sound === true ? undefined : data.alert || {\n        title: data.title,\n        body: data.body,\n        'title-loc-key': data.titleLocKey,\n        'title-loc-args': data.titleLocArgs,\n        'loc-key': data.locKey,\n        'loc-args': data.locArgs,\n        'launch-image': data.launchImage,\n        action: data.action,\n    },\n    topic: data.topic, // Required\n    category: data.category || data.clickAction,\n    contentAvailable: data.contentAvailable,\n    mdm: data.mdm,\n    urlArgs: data.urlArgs,\n    truncateAtWordEnd: data.truncateAtWordEnd,\n    collapseId: data.collapseKey,\n    mutableContent: data.mutableContent || 0,\n    threadId: data.threadId,\n    pushType: data.pushType\n}\n```\n\n_data is the parameter in `push.send(registrationIds, data)`_\n\n- [See node-apn fields](https://github.com/node-apn/node-apn/blob/master/doc/notification.markdown)\n- **Please note** that `topic` is required ([see node-apn docs](https://github.com/node-apn/node-apn/blob/master/doc/notification.markdown#notificationtopic)). When using token-based authentication, specify the bundle ID of the app.\n  When using certificate-based authentication, the topic is usually your app's bundle ID.\n  More details can be found under https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/sending_notification_requests_to_apns\n\n### Silent push notifications\n\niOS supports silent push notifications which are not displayed to the user but only used to transmit data.\n\nSilent push notifications must not include sound, badge or alert and have normal priority.\n\nBy setting the `silent` property to `true` the values for `sound`, `badge` and `alert` will be overridden to `undefined`.\n\nPriority will be overridden to `normal`.\n\n```js\nconst silentPushData = {\n    topic: 'yourTopic',\n    contentAvailable: true,\n    silent: true,\n    payload: {\n        yourKey: 'yourValue',\n        ...\n    }\n}\n```\n\n## WNS\n\nThe following fields are used to create a WNS message:\n\n```js\nconst notificationMethod = settings.wns.notificationMethod;\nconst opts = Object.assign({}, settings.wns);\nopts.headers = data.headers || opts.headers;\nopts.launch = data.launch || opts.launch;\nopts.duration = data.duration || opts.duration;\n\ndelete opts.notificationMethod;\ndelete data.headers;\ndelete data.launch;\ndelete data.duration;\n\nwns[notificationMethod](regId, data, opts, (err, response) => { ... });\n\n```\n\n_data is the parameter in `push.send(registrationIds, data)`_\n\n- [See wns fileds](https://github.com/tjanczuk/wns)\n\n**Note:** Please keep in mind that if `data.accessToken` is supplied, each push notification will be sent after the previous one has been **responded**. This is because Microsoft may send a new `accessToken` in the response and it should be used in successive requests. This can slow down the whole process depending on the number of devices to send.\n\n## ADM\n\nThe following parameters are used to create an ADM message:\n\n```js\nconst data = Object.assign({}, _data); // _data is the data passed as method parameter\nconst consolidationKey = data.consolidationKey;\nconst expiry = data.expiry;\nconst timeToLive = data.timeToLive;\n\ndelete data.consolidationKey;\ndelete data.expiry;\ndelete data.timeToLive;\n\nconst ADMmesssage = {\n  expiresAfter:\n    expiry - Math.floor(Date.now() / 1000) || timeToLive || 28 * 86400,\n  consolidationKey,\n  data,\n};\n```\n\n_data is the parameter in `push.send(registrationIds, data)`_\n\n- [See node-adm fields](https://github.com/umano/node-adm#usage)\n\n## Web-Push\n\nData can be passed as a simple string payload. If you do not pass a string, the parameter value will be stringified beforehand.\nSettings are directly forwarded to `webPush.sendNotification`.\n\n```js\nconst payload = typeof data === 'string' ? data : JSON.stringify(data);\nwebPush.sendNotification(regId, payload, settings.web);\n```\n\nA working server example implementation can be found at [https://github.com/alex-friedl/webpush-example/blob/master/server/index.js](https://github.com/alex-friedl/webpush-example/blob/master/server/index.js)\n\n## Resources\n\n- [Crossplatform integration example using this library and a React Native app](https://github.com/alex-friedl/crossplatform-push-notifications-example)\n- [Web-Push client/server example](https://github.com/alex-friedl/webpush-example)\n- [Node Push Notify from alexlds](https://github.com/alexlds/node-push-notify)\n\n## LICENSE\n\n```\nThe MIT License (MIT)\n\nCopyright (c) 2016 AppFeel\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n```\n\n_<p style=\"font-size: small;\" align=\"right\"><a color=\"#232323;\" href=\"http://appfeel.com\">Made in Barcelona with <span color=\"#FCB\"><3</span> and <span color=\"#BBCCFF\">Code</span></a></p>_\n","readmeFilename":"README.md"}