Send messages to topics for android (#296)
Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>
This commit is contained in:
@@ -5,6 +5,7 @@ import (
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/appleboy/go-fcm"
|
||||
@@ -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
|
||||
@@ -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)
|
||||
|
||||
@@ -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,
|
||||
@@ -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
|
||||
@@ -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++
|
||||
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user