Skip to content

Commit

Permalink
Merge pull request #348 from Fasal-Tech/master
Browse files Browse the repository at this point in the history
feat: actionable notifications
  • Loading branch information
Morten N.O. Nørgaard Henriksen authored Oct 2, 2018
2 parents 464d824 + 96251e8 commit edb7fe8
Show file tree
Hide file tree
Showing 3 changed files with 121 additions and 2 deletions.
113 changes: 113 additions & 0 deletions docs/ADVANCED.md
Original file line number Diff line number Diff line change
Expand Up @@ -323,3 +323,116 @@ 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.
5 changes: 3 additions & 2 deletions lib/common/notifications.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ 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])
}),
query: Match.Optional(String),
token: Match.Optional(_matchToken),
Expand Down Expand Up @@ -82,7 +83,7 @@ Push.send = function(options) {
}

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');
}

// Set one token selector, this can be token, array of tokens or query
Expand Down
5 changes: 5 additions & 0 deletions lib/server/push.api.js
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,11 @@ Push.Configure = function(options) {
data.picture = notification.picture;
}

//Action Buttons
if(typeof notification.actions !== 'undefined') {
data.actions = notification.actions;
}

//var message = new gcm.Message();
var message = new gcm.Message({
collapseKey: notification.from,
Expand Down

0 comments on commit edb7fe8

Please # to comment.