154 lines
3.3 KiB
Go
154 lines
3.3 KiB
Go
package gorush
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
|
|
"github.com/appleboy/go-fcm"
|
|
)
|
|
|
|
// InitFCMClient use for initialize FCM Client.
|
|
func InitFCMClient(key string) (*fcm.Client, error) {
|
|
var err error
|
|
|
|
if key == "" {
|
|
return nil, errors.New("Missing Android API Key")
|
|
}
|
|
|
|
if key != PushConf.Android.APIKey {
|
|
return fcm.NewClient(key)
|
|
}
|
|
|
|
if FCMClient == nil {
|
|
FCMClient, err = fcm.NewClient(key)
|
|
return FCMClient, err
|
|
}
|
|
|
|
return FCMClient, nil
|
|
}
|
|
|
|
// GetAndroidNotification use for define Android notification.
|
|
// HTTP Connection Server Reference for Android
|
|
// https://firebase.google.com/docs/cloud-messaging/http-server-ref
|
|
func GetAndroidNotification(req PushNotification) *fcm.Message {
|
|
notification := &fcm.Message{
|
|
To: req.To,
|
|
CollapseKey: req.CollapseKey,
|
|
ContentAvailable: req.ContentAvailable,
|
|
DelayWhileIdle: req.DelayWhileIdle,
|
|
TimeToLive: req.TimeToLive,
|
|
RestrictedPackageName: req.RestrictedPackageName,
|
|
DryRun: req.DryRun,
|
|
}
|
|
|
|
notification.RegistrationIDs = req.Tokens
|
|
|
|
if len(req.Priority) > 0 && req.Priority == "high" {
|
|
notification.Priority = "high"
|
|
}
|
|
|
|
// Add another field
|
|
if len(req.Data) > 0 {
|
|
notification.Data = make(map[string]interface{})
|
|
for k, v := range req.Data {
|
|
notification.Data[k] = v
|
|
}
|
|
}
|
|
|
|
notification.Notification = &req.Notification
|
|
|
|
// Set request message if body is empty
|
|
if len(req.Message) > 0 {
|
|
notification.Notification.Body = req.Message
|
|
}
|
|
|
|
if len(req.Title) > 0 {
|
|
notification.Notification.Title = req.Title
|
|
}
|
|
|
|
if len(req.Sound) > 0 {
|
|
notification.Notification.Sound = req.Sound
|
|
}
|
|
|
|
return notification
|
|
}
|
|
|
|
// PushToAndroid provide send notification to Android server.
|
|
func PushToAndroid(req PushNotification) bool {
|
|
LogAccess.Debug("Start push notification for Android")
|
|
if PushConf.Core.Sync {
|
|
defer req.WaitDone()
|
|
}
|
|
|
|
var (
|
|
client *fcm.Client
|
|
retryCount = 0
|
|
maxRetry = PushConf.Android.MaxRetry
|
|
)
|
|
|
|
if req.Retry > 0 && req.Retry < maxRetry {
|
|
maxRetry = req.Retry
|
|
}
|
|
|
|
// check message
|
|
err := CheckMessage(req)
|
|
|
|
if err != nil {
|
|
LogError.Error("request error: " + err.Error())
|
|
return false
|
|
}
|
|
|
|
Retry:
|
|
var isError = false
|
|
|
|
notification := GetAndroidNotification(req)
|
|
|
|
if req.APIKey != "" {
|
|
client, err = InitFCMClient(req.APIKey)
|
|
} else {
|
|
client, err = InitFCMClient(PushConf.Android.APIKey)
|
|
}
|
|
|
|
if err != nil {
|
|
// FCM server error
|
|
LogError.Error("FCM server error: " + err.Error())
|
|
return false
|
|
}
|
|
|
|
res, err := client.Send(notification)
|
|
if err != nil {
|
|
// Send Message error
|
|
LogError.Error("FCM server send message error: " + err.Error())
|
|
return false
|
|
}
|
|
|
|
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
|
|
for k, result := range res.Results {
|
|
if result.Error != nil {
|
|
isError = true
|
|
newTokens = append(newTokens, req.Tokens[k])
|
|
LogPush(FailedPush, req.Tokens[k], req, result.Error)
|
|
if PushConf.Core.Sync {
|
|
req.AddLog(getLogPushEntry(FailedPush, req.Tokens[k], req, result.Error))
|
|
}
|
|
continue
|
|
}
|
|
|
|
LogPush(SucceededPush, req.Tokens[k], req, nil)
|
|
}
|
|
|
|
if isError && retryCount < maxRetry {
|
|
retryCount++
|
|
|
|
// resend fail token
|
|
req.Tokens = newTokens
|
|
goto Retry
|
|
}
|
|
|
|
return isError
|
|
}
|