Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
2d27b44
fix: prevent send worker to stuck on db error
sampaiodiego Jul 31, 2018
a1ce16d
feat: Actionable Notifications
Sep 6, 2018
6dc8907
Update ADVANCED.md
shivang007 Sep 6, 2018
3bd5614
Update ADVANCED.md
shivang007 Sep 6, 2018
96251e8
Merge pull request #1 from Fasal-Tech/actionable-notifications
shivang007 Sep 6, 2018
edb7fe8
Merge pull request #348 from Fasal-Tech/master
Oct 2, 2018
3501de8
feat: force-start
Oct 23, 2018
39d6121
Merge pull request #2 from Fasal-Tech/force-start
shivang007 Oct 23, 2018
c0c6b64
Force restart requires phonegap-plugin-push version 1.9.0 or higher
Oct 23, 2018
8301ba7
Merge pull request #3 from Fasal-Tech/force-start
shivang007 Oct 23, 2018
fcd344e
Added example
shivang007 Oct 23, 2018
1c42bc7
Merge pull request #352 from Fasal-Tech/master
Oct 24, 2018
ef3323c
Merge pull request #344 from RocketChat/fix-db
Oct 24, 2018
13fcadc
typo fixed
theBstar Oct 26, 2018
bd86c66
android channel integration
da314pc Jan 22, 2019
22b87cd
android channel integration
da314pc Jan 22, 2019
9206495
Update README.md
da314pc Jan 23, 2019
0a7fb56
Update README.md
da314pc Jan 23, 2019
3b3b0ee
Update server.js
da314pc Jan 23, 2019
2028a92
Update server.js
da314pc Jan 23, 2019
27560b1
Update server.js
da314pc Feb 5, 2019
234eeb1
Merge pull request #359 from da314pc/master
da314pc Feb 5, 2019
2fec0be
Update README.md
Feb 20, 2019
35a684c
fix: memory leak in feedback
zodern Mar 5, 2019
df45b9e
Update README.md
Aug 8, 2020
460633c
Bump semantic-release from 10.0.1 to 17.2.3
dependabot[bot] Nov 18, 2020
d300fee
Bump qs from 6.2.3 to 6.5.3
dependabot[bot] Dec 6, 2022
9ceac30
Merge pull request #387 from Meteor-Community-Packages/dependabot/npm…
StorytellerCZ Sep 23, 2023
81ec90c
Merge pull request #353 from theBstar/patch-1
StorytellerCZ Sep 23, 2023
ec075c9
Merge pull request #364 from zodern/fix/memory-leak
StorytellerCZ Sep 23, 2023
d2c6384
Merge branch 'master' into dependabot/npm_and_yarn/semantic-release-1…
StorytellerCZ Sep 24, 2023
b52c77f
Merge pull request #381 from Meteor-Community-Packages/dependabot/npm…
StorytellerCZ Sep 24, 2023
7190bff
Fix package.lock
StorytellerCZ Sep 24, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 92 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# DEPRECATED: This package is no longer maintained

<img alt="Gi-SoftWare" src="https://raw.githubusercontent.com/raix/push/master/docs/logo.png" width="20%" height="20%">

raix:push Push notifications
Expand All @@ -23,6 +25,92 @@ Status:

We are using [semantic-release](https://github.com/semantic-release/semantic-release) following the [AngularJS Commit Message Conventions](https://docs.google.com/document/d/1QrDFcIiPjSLDn3EL15IJygNPiHORgU1_OOAqWjiDU5Y/edit) - Following this pattern will result in better versioning, better changelog and shorter release cycle.

## Updates For Android 8.0

Meteor must be version 1.6.1

Cordova Android must be version 6.3.0
Cordova IOS must be version 4.5.0

Meteor release 1.6.1 https://docs.meteor.com/changelog.html#changes-10
"The cordova-lib package has been updated to version 7.1.0, cordova-android has been updated to version 6.4.0 (plus one additional commit), and cordova-ios has been updated to version 4.5.4"

To verify the correct installation ADD phonegap-plugin-push@2.1.2 to your cordova plugins file.

After your app builds, Make the following changes to your build.gradle file. The simpliest solution to modify this file is in android studio.

The correct gradle file to modify has this line at the begining of the file:

apply plugin: 'com.android.application'

Add this two your dependencies:

```js
classpath 'com.google.gms:google-services:4.1.0' // I added both of these
classpath 'com.google.firebase:firebase-core:11.0.1' // I added both of these
```
At the end of your build.gradle file add:

```js
apply plugin: 'com.google.gms.google-services'
```
In case your run into errors with conflicting google libraries add:

```js
configurations.all {
resolutionStrategy {
force 'com.android.support:support-v4:27.1.0'
}
}

configurations {
all*.exclude group: 'com.android.support', module: 'support-v13'
}
```
Other errors refer to:

https://github.com/phonegap/phonegap-plugin-push/blob/master/docs/INSTALLATION.md#co-existing-with-plugins-that-use-firebase


Changes for the API:
On the client make sure you add a android channel:

```js
PushNotification.createChannel(
() => {
console.log('createChannel');
},
() => {
console.log('error');
},
{
id: Meteor.userId(), //Use any Id you prefer, but the same Id for this channel must be sent from the server,
description: 'Android Channel', //And any description your prefer
importance: 3,
vibration: true
}
);
```

Server changes:
Add the android_channel_id so the Push message like below:

```js
Push.send({
from: 'test',
title: 'test',
text: 'hello',
android_channel_id:this.userId, //The android channel should match the id on the client
query: {
userId: this.userId
},
gcm: {
style: 'inbox',
summaryText: 'There are %n% notifications'
},
});
```

## Install
```bash
$ meteor add raix:push
Expand Down Expand Up @@ -218,6 +306,10 @@ Adds metadata to a particular Application/Token record.

For more internal or advanced features read [ADVANCED.md](docs/ADVANCED.md)

## For maintainers

We have a slack channel to keep communication tight between contributors - it's on https://meteoropensourcecomm.slack.com in channel `#raixpush`

Kind regards

Morten (aka RaiX)
140 changes: 139 additions & 1 deletion docs/ADVANCED.md
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ The 4th parameter is a selection query for determining who the message should be

`delayUntil` is an optional Date. If set, sending will be delayed until then.

The query selector is used against a Mongo Collection created by the push packahe called `Push.appCollection`. This collection stores the userIds, pushIds, and tokens of all devices that register with the server. With a desired selection query chosen a minimal `Push.send` takes the following form (using one of the queries).
The query selector is used against a Mongo Collection created by the push package called `Push.appCollection`. This collection stores the userIds, pushIds, and tokens of all devices that register with the server. With a desired selection query chosen a minimal `Push.send` takes the following form (using one of the queries).

```js
Push.send({
Expand Down Expand Up @@ -323,3 +323,141 @@ When a client calls send on Push, the Push's allow and deny callbacks are called
}
});
```

## Action Buttons

Your notification can include a maximum of three action buttons. You register the event callback name for each of your actions, then when a user clicks on one of notification's buttons, the event corresponding to that button is fired and the listener you have registered is invoked. For instance, here is a setup with three actions `snoozeAction6Hour` `snoozeAction1Day` and `closeAlert`.

```javascript
window.Notification = {};

// data contains the push payload just like a notification event
Notification.snoozeAction6Hour = function(data) {
data.additionalData.snoozeHours = 6;
Meteor.call('snoozeRuleAlerts', data, function() {});
};

Notification.snoozeAction1Day = function(data) {
data.additionalData.snoozeHours = 24;
Meteor.call('snoozeRuleAlerts', data, function() {});
};

//closing function for alert
Notification.closeAlert = function() {};
```

If you wish to include an icon along with the button name, they must be placed in the `res/drawable` directory of your Android project. Then you can send the following JSON from GCM/FCM:

```json
{
"title": "Snooze Notification",
"message": "Snooze your daily requirement alerts for a specific amount of time.",
"query": {
"userId": 123456789
},
"actions": [
{
"icon": "halfDay",
"title": "6 hours",
"callback": "Notification.snoozeAction6Hour",
"foreground": true
},
{
"icon": "oneDay",
"title": "1 Day",
"callback": "Notification.snoozeAction1Day",
"foreground": true
},
{
"icon": "discard",
"title": "Cancel",
"callback": "Notification.closeAlert",
"foreground": false
}
]
}
```
This will produce the following notification in your tray:

![action_combo](https://cloud.githubusercontent.com/assets/353180/9313435/02554d2a-44f1-11e5-8cd9-0aadd1e02b18.png)

If your user clicks on the main body of the notification, then your app will be opened. However, if they click on either of the action buttons the app will open (or start) and the specified event will be triggered with the callback name. In this case it is `emailGuests` and `snooze`, respectively. If you set the `foreground` property to `true`, the app will be brought to the front, if `foreground` is `false` then the callback is run without the app being brought to the foreground.

#### Actionable Notification for IOS

You must setup the possible actions when you initialize the plugin:
```javascript
var categories = {
"snoozeRule": {
"yes": {
"callback": "Notification.snoozeAction6Hour",
"title": "6 Hours",
"foreground": false,
"destructive": false
},
"no": {
"callback": "Notification.snoozeAction1Day",
"title": "1 Day",
"foreground": false,
"destructive": false
},
"maybe": {
"callback": "Notification.closeAlert",
"title": "Cancel",
"foreground": false,
"destructive": false
}
},
"delete": {
"yes": {
"callback": "Notification.delete",
"title": "Delete",
"foreground": true,
"destructive": false
},
"no": {
"callback": "Notification.closeAlert",
"title": "Cancel",
"foreground": true,
"destructive": false
}
}
};

Push.Configure({
ios: {
"alert": true,
"badge": true,
"sound": true,
"clearBadge": true,
"categories": categories
}
});
```

Each category is a named object, snoozeRule and delete in this case. These names will need to match the ones you send via your payload to APNS if you want the action buttons to be displayed. Each category can have up to three buttons which must be labeled yes, no and maybe (This is strict, it will not work if you label them anything other than this). In turn each of these buttons has four properties, callback the javascript function you want to call, title the label for the button, foreground whether or not to bring your app to the foreground and destructive which doesn’t actually do anything destructive, it just colors the button red as a warning to the user that the action may be destructive.

## Force Starting App

When you implement the actionable notifications, you might notice that if the user has force closed his application, then the background actions will not work untill user opens the app the next time (Note: If you have used 'foreground': true, which will restart the app, this is not the intended behaviour for many providers). In this situation, 'forceStart' comes in handy. This will start the app again BUT the application will not be brought to foreground, hence it will not disrupt any task that the user was performing. In order to take advantage of this feature, you will need to be using cordova-android 6.0.0 or higher. If you add force-start: 1 to the data payload the application will be restarted in background even if it was force closed.

Example:
```javascript
Push.send({
"from": 'push',
"title": "Test Notification for Force Start",
"text": "This will forcestart your app.",
"badge": 1,
"notId": 123456,
"query": {},
"apn": {
"sound": "www/application/app/testApp.wav"
},
"gcm": {
"sound": "testApp"
},
"forceStart": 1
});
```

Note: This is restricted to Android only. In IOS, once the user closes an app, you can not restart it forcefully unlike android.
16 changes: 12 additions & 4 deletions lib/common/notifications.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@

// This is the match pattern for tokens
_matchToken = Match.OneOf({ apn: String }, { gcm: String });

Expand All @@ -19,6 +20,7 @@ var _validateDocument = function(notification) {
sound: Match.Optional(String),
notId: Match.Optional(Match.Integer),
contentAvailable: Match.Optional(Match.Integer),
forceStart: Match.Optional(Match.Integer),
apn: Match.Optional({
from: Match.Optional(String),
title: Match.Optional(String),
Expand All @@ -38,8 +40,10 @@ var _validateDocument = function(notification) {
picture: Match.Optional(String),
badge: Match.Optional(Match.Integer),
sound: Match.Optional(String),
notId: Match.Optional(Match.Integer)
notId: Match.Optional(Match.Integer),
actions: Match.Optional([Match.Any])
}),
android_channel_id: Match.Optional(String),
query: Match.Optional(String),
token: Match.Optional(_matchToken),
tokens: Match.Optional([_matchToken]),
Expand Down Expand Up @@ -75,14 +79,14 @@ Push.send = function(options) {
}, _.pick(options, 'from', 'title', 'text'));

// Add extra
_.extend(notification, _.pick(options, 'payload', 'badge', 'sound', 'notId', 'delayUntil'));
_.extend(notification, _.pick(options, 'payload', 'badge', 'sound', 'notId', 'delayUntil', 'android_channel_id'));

if (Match.test(options.apn, Object)) {
notification.apn = _.pick(options.apn, 'from', 'title', 'text', 'badge', 'sound', 'notId', 'category');
}

if (Match.test(options.gcm, Object)) {
notification.gcm = _.pick(options.gcm, 'image', 'style', 'summaryText', 'picture', 'from', 'title', 'text', 'badge', 'sound', 'notId');
notification.gcm = _.pick(options.gcm, 'image', 'style', 'summaryText', 'picture', 'from', 'title', 'text', 'badge', 'sound', 'notId','actions', 'android_channel_id');
}

// Set one token selector, this can be token, array of tokens or query
Expand All @@ -100,6 +104,10 @@ Push.send = function(options) {
if (typeof options.contentAvailable !== 'undefined') {
notification.contentAvailable = options.contentAvailable;
}

if (typeof options.forceStart !== 'undefined') {
notification.forceStart = options.forceStart;
}

notification.sent = false;
notification.sending = 0;
Expand Down Expand Up @@ -135,4 +143,4 @@ Push.deny = function(rules) {
}
});
}
};
};
Loading