Skip to content

Commit

Permalink
Send messages to topics for android (#296)
Browse files Browse the repository at this point in the history
Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>
  • Loading branch information
appleboy authored Oct 24, 2017
1 parent 4df2420 commit 115ee18
Show file tree
Hide file tree
Showing 9 changed files with 194 additions and 25 deletions.
12 changes: 11 additions & 1 deletion gorush/notification.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"net/http"
"net/url"
"os"
"strings"
"sync"

"github.com/appleboy/go-fcm"
Expand Down Expand Up @@ -69,6 +70,7 @@ type PushNotification struct {
TimeToLive *uint `json:"time_to_live,omitempty"`
RestrictedPackageName string `json:"restricted_package_name,omitempty"`
DryRun bool `json:"dry_run,omitempty"`
Condition string `json:"condition,omitempty"`
Notification fcm.Notification `json:"notification,omitempty"`

// iOS
Expand Down Expand Up @@ -103,11 +105,19 @@ func (p *PushNotification) AddLog(log LogPushEntry) {
}
}

// IsTopic check if message format is topic for FCM
// ref: https://firebase.google.com/docs/cloud-messaging/send-message#topic-http-post-request
func (p *PushNotification) IsTopic() bool {
return (p.Platform == PlatFormAndroid && p.To != "" && strings.HasPrefix(p.To, "/topics/")) ||
p.Condition != ""
}

// CheckMessage for check request message
func CheckMessage(req PushNotification) error {
var msg string

if len(req.Tokens) == 0 {
// ignore send topic mesaage from FCM
if !req.IsTopic() && len(req.Tokens) == 0 {
msg = "the message must specify at least one registration ID"
LogAccess.Debug(msg)
return errors.New(msg)
Expand Down
29 changes: 28 additions & 1 deletion gorush/notification_fcm.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ func InitFCMClient(key string) (*fcm.Client, error) {
func GetAndroidNotification(req PushNotification) *fcm.Message {
notification := &fcm.Message{
To: req.To,
Condition: req.Condition,
CollapseKey: req.CollapseKey,
ContentAvailable: req.ContentAvailable,
DelayWhileIdle: req.DelayWhileIdle,
Expand Down Expand Up @@ -122,11 +123,15 @@ Retry:
return false
}

LogAccess.Debug(fmt.Sprintf("Android Success count: %d, Failure count: %d", res.Success, res.Failure))
if !req.IsTopic() {
LogAccess.Debug(fmt.Sprintf("Android Success count: %d, Failure count: %d", res.Success, res.Failure))
}

StatStorage.AddAndroidSuccess(int64(res.Success))
StatStorage.AddAndroidError(int64(res.Failure))

var newTokens []string
// result from Send messages to specific devices
for k, result := range res.Results {
if result.Error != nil {
isError = true
Expand All @@ -141,6 +146,28 @@ Retry:
LogPush(SucceededPush, req.Tokens[k], req, nil)
}

// result from Send messages to topics
if req.IsTopic() {
to := ""
if req.To != "" {
to = req.To
} else {
to = req.Condition
}
LogAccess.Debug("Send Topic Message: ", to)
// Success
if res.MessageID != 0 {
LogPush(SucceededPush, to, req, nil)
} else {
isError = true
// failure
LogPush(FailedPush, to, req, res.Error)
if PushConf.Core.Sync {
req.AddLog(getLogPushEntry(FailedPush, to, req, res.Error))
}
}
}

if isError && retryCount < maxRetry {
retryCount++

Expand Down
20 changes: 20 additions & 0 deletions gorush/notification_fcm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,26 @@ func TestFCMMessage(t *testing.T) {
err = CheckMessage(req)
assert.Error(t, err)

// ignore check token length if send topic message
req = PushNotification{
Message: "Test",
Platform: PlatFormAndroid,
To: "/topics/foo-bar",
}

err = CheckMessage(req)
assert.NoError(t, err)

// "condition": "'dogs' in topics || 'cats' in topics",
req = PushNotification{
Message: "Test",
Platform: PlatFormAndroid,
Condition: "'dogs' in topics || 'cats' in topics",
}

err = CheckMessage(req)
assert.NoError(t, err)

// the message may specify at most 1000 registration IDs
req = PushNotification{
Message: "Test",
Expand Down
42 changes: 42 additions & 0 deletions gorush/notification_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,48 @@ func TestSyncModeForNotifications(t *testing.T) {
assert.Equal(t, 2, len(logs))
}

func TestSyncModeForTopicNotification(t *testing.T) {
PushConf, _ = config.LoadConf("")

PushConf.Android.Enabled = true
PushConf.Android.APIKey = os.Getenv("ANDROID_API_KEY")
PushConf.Log.HideToken = false

// enable sync mode
PushConf.Core.Sync = true

req := RequestPush{
Notifications: []PushNotification{
// android
{
// error:InvalidParameters
// Check that the provided parameters have the right name and type.
To: "/topics/foo-bar@@@##",
Platform: PlatFormAndroid,
Message: "This is a Firebase Cloud Messaging Topic Message!",
},
// android
{
// success
To: "/topics/foo-bar",
Platform: PlatFormAndroid,
Message: "This is a Firebase Cloud Messaging Topic Message!",
},
// android
{
// success
Condition: "'dogs' in topics || 'cats' in topics",
Platform: PlatFormAndroid,
Message: "This is a Firebase Cloud Messaging Topic Message!",
},
},
}

count, logs := queueNotification(req)
assert.Equal(t, 2, count)
assert.Equal(t, 1, len(logs))
}

func TestSetProxyURL(t *testing.T) {

err := SetProxy("87.236.233.92:8080")
Expand Down
4 changes: 4 additions & 0 deletions gorush/worker.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ func queueNotification(req RequestPush) (int, []LogPushEntry) {
}
QueueNotification <- notification
count += len(notification.Tokens)
// Count topic message
if notification.To != "" {
count++
}
}

if PushConf.Core.Sync {
Expand Down
20 changes: 17 additions & 3 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,12 +130,21 @@ func main() {
if opts.Android.Enabled {
gorush.PushConf.Android.Enabled = opts.Android.Enabled
req := gorush.PushNotification{
Tokens: []string{token},
Platform: gorush.PlatFormAndroid,
Message: message,
Title: title,
}

// send message to single device
if token != "" {
req.Tokens = []string{token}
}

// send topic message
if topic != "" {
req.To = topic
}

err := gorush.CheckMessage(req)

if err != nil {
Expand All @@ -159,12 +168,17 @@ func main() {

gorush.PushConf.Ios.Enabled = opts.Ios.Enabled
req := gorush.PushNotification{
Tokens: []string{token},
Platform: gorush.PlatFormIos,
Message: message,
Title: title,
}

// send message to single device
if token != "" {
req.Tokens = []string{token}
}

// send topic message
if topic != "" {
req.Topic = topic
}
Expand Down Expand Up @@ -259,13 +273,13 @@ Server Options:
iOS Options:
-i, --key <file> certificate key file path
-P, --password <password> certificate key password
--topic <topic> iOS topic
--ios enabled iOS (default: false)
--production iOS production mode (default: false)
Android Options:
-k, --apikey <api_key> Android API Key
--android enabled android (default: false)
Common Options:
--topic <topic> iOS or Android topic message
-h, --help Show this message
-v, --version Show version
`
Expand Down
41 changes: 24 additions & 17 deletions vendor/github.com/appleboy/go-fcm/README.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

45 changes: 45 additions & 0 deletions vendor/github.com/appleboy/go-fcm/response.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions vendor/vendor.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
"ignore": "test",
"package": [
{
"checksumSHA1": "DuVew6znkXuUG1wjGQF+pUyXrHU=",
"checksumSHA1": "TVTjsXflagrWbTXmbxPJdCtTFRo=",
"path": "github.com/appleboy/go-fcm",
"revision": "5f2cb2866531e4e37c7a9ff5fb7a1536e1ffc566",
"revisionTime": "2017-06-01T07:42:50Z"
"revision": "c12f9e2e95b14802da2b4d3807dd12ef0dd80a42",
"revisionTime": "2017-10-24T08:00:40Z"
},
{
"checksumSHA1": "Ab7MUtqX0iq2PUzzBxWpgzPSydw=",
Expand Down

0 comments on commit 115ee18

Please sign in to comment.