replace Extend with data field.

Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>
This commit is contained in:
Bo-Yi Wu 2016-04-13 11:15:24 +08:00
parent 08339e36d7
commit 9bc2df6baa
3 changed files with 91 additions and 90 deletions

View File

@ -193,11 +193,11 @@ Request body must has a notifications array. The following is a parameter table
|tokens|string array|device tokens|o|| |tokens|string array|device tokens|o||
|platform|int|platform(iOS,Android)|o|1=iOS, 2=Android| |platform|int|platform(iOS,Android)|o|1=iOS, 2=Android|
|message|string|message for notification|o|| |message|string|message for notification|o||
|priority|string|Sets the priority of the message.|-|| |title|string|notification title|-||
|priority|string|Sets the priority of the message.|-|`normal` or `high`|
|content_available|bool|data messages wake the app by default.|-|| |content_available|bool|data messages wake the app by default.|-||
|sound|string|sound type|-|| |sound|string|sound type|-||
|title|string|notification title|-|| |data|string array|extensible partition|-||
|extend|string array|extensible partition|-||
|api_key|string|Android api key|-|only Android| |api_key|string|Android api key|-|only Android|
|to|string|The value must be a registration token, notification key, or topic.|-|only Android| |to|string|The value must be a registration token, notification key, or topic.|-|only Android|
|collapse_key|string|a key for collapsing notifications|-|only Android| |collapse_key|string|a key for collapsing notifications|-|only Android|
@ -205,30 +205,29 @@ Request body must has a notifications array. The following is a parameter table
|time_to_live|int|expiration of message kept on GCM storage|-|only Android| |time_to_live|int|expiration of message kept on GCM storage|-|only Android|
|restricted_package_name|string|the package name of the application|-|only Android| |restricted_package_name|string|the package name of the application|-|only Android|
|dry_run|bool|allows developers to test a request without actually sending a message|-|only Android| |dry_run|bool|allows developers to test a request without actually sending a message|-|only Android|
|data|string array|data payload of a GCM message|-|only Android| |notification|string array|payload of a GCM message|-|only Android. See the [detail](#android-notification-payload)|
|notification|string array|payload of a GCM message|-|only Android. See the [detail]()|
|expiration|int|expiration for notification|-|only iOS| |expiration|int|expiration for notification|-|only iOS|
|apns_id|string|A canonical UUID that identifies the notification|-|only iOS| |apns_id|string|A canonical UUID that identifies the notification|-|only iOS|
|topic|string|topic of the remote notification|-|only iOS| |topic|string|topic of the remote notification|-|only iOS|
|badge|int|badge count|-|only iOS| |badge|int|badge count|-|only iOS|
|category|string|the UIMutableUserNotificationCategory object|-|only iOS| |category|string|the UIMutableUserNotificationCategory object|-|only iOS|
|alert|string array|payload of a iOS message|-|only iOS. See the [detail]()| |alert|string array|payload of a iOS message|-|only iOS. See the [detail](#ios-alert-payload)|
### iOS alert structure ### iOS alert payload
|name|type|description|required|note| |name|type|description|required|note|
|-------|-------|--------|--------|---------| |-------|-------|--------|--------|---------|
|action||||| |action|string|The label of the action button. This one is required for Safari Push Notifications.|-||
|action-loc-key||||| |action-loc-key|string|If a string is specified, the system displays an alert that includes the Close and View buttons.|-||
|launch-image||||| |launch-image|string|The filename of an image file in the app bundle, with or without the filename extension.|-||
|loc-args||||| |loc-args|array of strings|Variable string values to appear in place of the format specifiers in loc-key.|-||
|loc-key||||| |loc-key|string|A key to an alert-message string in a Localizable.strings file for the current localization.|-||
|title-loc-args||||| |title-loc-args|array of strings|Variable string values to appear in place of the format specifiers in title-loc-key.|-||
|title-loc-key||||| |title-loc-key|string|The key to a title string in the Localizable.strings file for the current localization.|-||
See more detail about [APNs Provider API](https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/APNsProviderAPI.html#//apple_ref/doc/uid/TP40008194-CH101-SW1). See more detail about [APNs Remote Notification Payload](https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/TheNotificationPayload.html#//apple_ref/doc/uid/TP40008194-CH107-SW1).
### Android notification structure ### Android notification payload
|name|type|description|required|note| |name|type|description|required|note|
|-------|-------|--------|--------|---------| |-------|-------|--------|--------|---------|
@ -243,6 +242,54 @@ See more detail about [APNs Provider API](https://developer.apple.com/library/io
See more detail about [GCM server reference](https://developers.google.com/cloud-messaging/http-server-ref#send-downstream). See more detail about [GCM server reference](https://developers.google.com/cloud-messaging/http-server-ref#send-downstream).
### iOS Example
Send normal notification.
```json
"notifications": [
{
"tokens": ["token_a", "token_b"],
"platform": 1,
"message": "Hello World iOS!",
"title": "You got message"
}
]
```
The app icon be badged with the number `9` and that a bundled alert sound be played when the notification is delivered.
```json
"notifications": [
{
"tokens": ["token_a", "token_b"],
"platform": 1,
"message": "Hello World iOS!",
"title": "You got message",
"badge": 9,
"sound": "bingbong.aiff"
}
]
```
Add other fields which user defined via `data` field.
```json
"notifications": [
{
"tokens": ["token_a", "token_b"],
"platform": 1,
"message": "Hello World iOS!",
"title": "You got message",
"data": {
"key1": "welcome",
"key2": 2
}
}
]
```
## License ## License
Copyright 2016 Bo-Yi Wu [@appleboy](https://twitter.com/appleboy). Copyright 2016 Bo-Yi Wu [@appleboy](https://twitter.com/appleboy).

View File

@ -10,10 +10,7 @@ import (
"time" "time"
) )
type ExtendJSON struct { type D map[string]interface{}
Key string `json:"key"`
Value string `json:"val"`
}
const ( const (
// PriorityLow will tell APNs to send the push message at a time that takes // PriorityLow will tell APNs to send the push message at a time that takes
@ -47,14 +44,14 @@ type RequestPush struct {
type PushNotification struct { type PushNotification struct {
// Common // Common
Tokens []string `json:"tokens" binding:"required"` Tokens []string `json:"tokens" binding:"required"`
Platform int `json:"platform" binding:"required"` Platform int `json:"platform" binding:"required"`
Message string `json:"message" binding:"required"` Message string `json:"message" binding:"required"`
Title string `json:"title,omitempty"` Title string `json:"title,omitempty"`
Priority string `json:"priority,omitempty"` Priority string `json:"priority,omitempty"`
ContentAvailable bool `json:"content_available,omitempty"` ContentAvailable bool `json:"content_available,omitempty"`
Sound string `json:"sound,omitempty"` Sound string `json:"sound,omitempty"`
Extend []ExtendJSON `json:"extend,omitempty"` Data D `json:"data,omitempty"`
// Android // Android
ApiKey string `json:"api_key,omitempty"` ApiKey string `json:"api_key,omitempty"`
@ -64,7 +61,6 @@ type PushNotification struct {
TimeToLive uint `json:"time_to_live,omitempty"` TimeToLive uint `json:"time_to_live,omitempty"`
RestrictedPackageName string `json:"restricted_package_name,omitempty"` RestrictedPackageName string `json:"restricted_package_name,omitempty"`
DryRun bool `json:"dry_run,omitempty"` DryRun bool `json:"dry_run,omitempty"`
Data gcm.Data `json:"data,omitempty"`
Notification gcm.Notification `json:"notification,omitempty"` Notification gcm.Notification `json:"notification,omitempty"`
// iOS // iOS
@ -178,9 +174,9 @@ func GetIOSNotification(req PushNotification) *apns.Notification {
payload.ContentAvailable() payload.ContentAvailable()
} }
if len(req.Extend) > 0 { if len(req.Data) > 0 {
for _, extend := range req.Extend { for k, v := range req.Data {
payload.Custom(extend.Key, extend.Value) payload.Custom(k, v)
} }
} }
@ -309,17 +305,12 @@ func GetAndroidNotification(req PushNotification) gcm.HttpMessage {
notification.DryRun = true notification.DryRun = true
} }
if len(req.Extend) > 0 { // Add another field
notification.Data = make(map[string]interface{})
for _, extend := range req.Extend {
notification.Data[extend.Key] = extend.Value
}
}
// overwrite Extend
if len(req.Data) > 0 { if len(req.Data) > 0 {
notification.Data = req.Data notification.Data = make(map[string]interface{})
for k, v := range req.Data {
notification.Data[k] = v
}
} }
notification.Notification = &req.Notification notification.Notification = &req.Notification

View File

@ -74,15 +74,9 @@ func TestIOSNotificationStructure(t *testing.T) {
Badge: 1, Badge: 1,
Sound: test, Sound: test,
ContentAvailable: true, ContentAvailable: true,
Extend: []ExtendJSON{ Data: D{
{ "key1": "test",
Key: "key1", "key2": 2,
Value: "1",
},
{
Key: "key2",
Value: "2",
},
}, },
Category: test, Category: test,
URLArgs: []string{"a", "b"}, URLArgs: []string{"a", "b"},
@ -103,8 +97,8 @@ func TestIOSNotificationStructure(t *testing.T) {
sound, _ := jsonparser.GetString(data, "aps", "sound") sound, _ := jsonparser.GetString(data, "aps", "sound")
contentAvailable, _ := jsonparser.GetInt(data, "aps", "content-available") contentAvailable, _ := jsonparser.GetInt(data, "aps", "content-available")
category, _ := jsonparser.GetString(data, "aps", "category") category, _ := jsonparser.GetString(data, "aps", "category")
key1 := dat["key1"].(string) key1 := dat["key1"].(interface{})
key2 := dat["key2"].(string) key2 := dat["key2"].(interface{})
aps := dat["aps"].(map[string]interface{}) aps := dat["aps"].(map[string]interface{})
urlArgs := aps["url-args"].([]interface{}) urlArgs := aps["url-args"].([]interface{})
@ -116,8 +110,8 @@ func TestIOSNotificationStructure(t *testing.T) {
assert.Equal(t, 1, int(badge)) assert.Equal(t, 1, int(badge))
assert.Equal(t, test, sound) assert.Equal(t, test, sound)
assert.Equal(t, 1, int(contentAvailable)) assert.Equal(t, 1, int(contentAvailable))
assert.Equal(t, "1", key1) assert.Equal(t, "test", key1)
assert.Equal(t, "2", key2) assert.Equal(t, 2, int(key2.(float64)))
assert.Equal(t, test, category) assert.Equal(t, test, category)
assert.Contains(t, urlArgs, "a") assert.Contains(t, urlArgs, "a")
assert.Contains(t, urlArgs, "b") assert.Contains(t, urlArgs, "b")
@ -193,15 +187,9 @@ func TestAndroidNotificationStructure(t *testing.T) {
DryRun: true, DryRun: true,
Title: test, Title: test,
Sound: test, Sound: test,
Extend: []ExtendJSON{ Data: D{
{ "a": "1",
Key: "key1", "b": 2,
Value: "1",
},
{
Key: "key2",
Value: "2",
},
}, },
Notification: gcm.Notification{ Notification: gcm.Notification{
Color: test, Color: test,
@ -224,33 +212,8 @@ func TestAndroidNotificationStructure(t *testing.T) {
assert.Equal(t, test, notification.Notification.Color) assert.Equal(t, test, notification.Notification.Color)
assert.Equal(t, test, notification.Notification.Tag) assert.Equal(t, test, notification.Notification.Tag)
assert.Equal(t, "Welcome", notification.Notification.Body) assert.Equal(t, "Welcome", notification.Notification.Body)
assert.Equal(t, "1", notification.Data["key1"])
// add data file to overwrite `Extend`
req = PushNotification{
Tokens: []string{"a", "b"},
Message: "Welcome",
To: test,
Data: map[string]interface{}{
"a": "1",
"b": "2",
},
Extend: []ExtendJSON{
{
Key: "key1",
Value: "1",
},
{
Key: "key2",
Value: "2",
},
},
}
notification = GetAndroidNotification(req)
assert.Equal(t, "1", notification.Data["a"]) assert.Equal(t, "1", notification.Data["a"])
assert.Equal(t, "2", notification.Data["b"]) assert.Equal(t, 2, notification.Data["b"])
} }
func TestPushToIOS(t *testing.T) { func TestPushToIOS(t *testing.T) {