Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 0 additions & 24 deletions gorush/const.go

This file was deleted.

96 changes: 96 additions & 0 deletions gorush/consts/const.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package consts

import (
"github.com/appleboy/gorush/gorush/structs"
"github.com/sideshow/apns2"
)

const (
// PlatFormIos constant is 1 for iOS
PlatFormIos structs.Platform = iota + 1
// PlatFormAndroid constant is 2 for Android
PlatFormAndroid
)

const (
// SucceededPush is log block
SucceededPush = "succeeded-push"
// FailedPush is log block
FailedPush = "failed-push"
)

// Stat variable for redis
const (
TotalCountKey = "gorush-total-count"
IosSuccessKey = "gorush-ios-success-count"
IosErrorKey = "gorush-ios-error-count"
AndroidSuccessKey = "gorush-android-success-count"
AndroidErrorKey = "gorush-android-error-count"
)

const (
// ApnsPriorityLow will tell APNs to send the push message at a time that takes
// into account power considerations for the device. Notifications with this
// priority might be grouped and delivered in bursts. They are throttled, and
// in some cases are not delivered.
ApnsPriorityLow = apns2.PriorityLow

// ApnsPriorityHigh will tell APNs to send the push message immediately.
// Notifications with this priority must trigger an alert, sound, or badge on
// the target device. It is an error to use this priority for a push
// notification that contains only the content-available key.
ApnsPriorityHigh = apns2.PriorityHigh
)

const (
// PriorityNormal sets push notification with normal priority
PriorityNormal structs.Priority = "normal"
// PriorityHigh sets push notification with high priority
PriorityHigh structs.Priority = "high"
)

const (
// PushTypeAlert is used for notifications that trigger a user interaction —
// for example, an alert, badge, or sound. If you set this push type, the
// apns-topic header field must use your app’s bundle ID as the topic. The
// alert push type is required on watchOS 6 and later. It is recommended on
// macOS, iOS, tvOS, and iPadOS.
PushTypeAlert = apns2.PushTypeAlert

// PushTypeBackground is used for notifications that deliver content in the
// background, and don’t trigger any user interactions. If you set this push
// type, the apns-topic header field must use your app’s bundle ID as the
// topic. The background push type is required on watchOS 6 and later. It is
// recommended on macOS, iOS, tvOS, and iPadOS.
PushTypeBackground = apns2.PushTypeBackground

// PushTypeVOIP is used for notifications that provide information about an
// incoming Voice-over-IP (VoIP) call. If you set this push type, the
// apns-topic header field must use your app’s bundle ID with .voip appended
// to the end. If you’re using certificate-based authentication, you must
// also register the certificate for VoIP services. The voip push type is
// not available on watchOS. It is recommended on macOS, iOS, tvOS, and
// iPadOS.
PushTypeVOIP = apns2.PushTypeVOIP

// PushTypeComplication is used for notifications that contain update
// information for a watchOS app’s complications. If you set this push type,
// the apns-topic header field must use your app’s bundle ID with
// .complication appended to the end. If you’re using certificate-based
// authentication, you must also register the certificate for WatchKit
// services. The complication push type is recommended for watchOS and iOS.
// It is not available on macOS, tvOS, and iPadOS.
PushTypeComplication = apns2.PushTypeComplication

// PushTypeFileProvider is used to signal changes to a File Provider
// extension. If you set this push type, the apns-topic header field must
// use your app’s bundle ID with .pushkit.fileprovider appended to the end.
// The fileprovider push type is not available on watchOS. It is recommended
// on macOS, iOS, tvOS, and iPadOS.
PushTypeFileProvider = apns2.PushTypeFileProvider

// PushTypeMDM is used for notifications that tell managed devices to
// contact the MDM server. If you set this push type, you must use the topic
// from the UID attribute in the subject of your MDM push certificate.
PushTypeMDM = apns2.PushTypeMDM
)
23 changes: 13 additions & 10 deletions gorush/log.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ import (
"os"
"strings"

"github.com/appleboy/gorush/gorush/consts"
"github.com/appleboy/gorush/gorush/structs"

"github.com/mattn/go-isatty"
"github.com/sirupsen/logrus"
)
Expand Down Expand Up @@ -116,22 +119,22 @@ func SetLogLevel(log *logrus.Logger, levelString string) error {
return nil
}

func colorForPlatForm(platform int) string {
func colorForPlatForm(platform structs.Platform) string {
switch platform {
case PlatFormIos:
case consts.PlatFormIos:
return blue
case PlatFormAndroid:
case consts.PlatFormAndroid:
return yellow
default:
return reset
}
}

func typeForPlatForm(platform int) string {
func typeForPlatForm(platform structs.Platform) string {
switch platform {
case PlatFormIos:
case consts.PlatFormIos:
return "ios"
case PlatFormAndroid:
case consts.PlatFormAndroid:
return "android"
default:
return ""
Expand Down Expand Up @@ -197,7 +200,7 @@ func LogPush(status, token string, req PushNotification, errPush error) {
} else {
var typeColor string
switch status {
case SucceededPush:
case consts.SucceededPush:
if isTerm {
typeColor = green
}
Expand All @@ -208,7 +211,7 @@ func LogPush(status, token string, req PushNotification, errPush error) {
log.Token,
log.Message,
)
case FailedPush:
case consts.FailedPush:
if isTerm {
typeColor = red
}
Expand All @@ -224,9 +227,9 @@ func LogPush(status, token string, req PushNotification, errPush error) {
}

switch status {
case SucceededPush:
case consts.SucceededPush:
LogAccess.Info(output)
case FailedPush:
case consts.FailedPush:
LogError.Error(output)
}
}
10 changes: 6 additions & 4 deletions gorush/log_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"testing"

"github.com/appleboy/gorush/config"
"github.com/appleboy/gorush/gorush/consts"

"github.com/sirupsen/logrus"
"github.com/stretchr/testify/assert"
)
Expand Down Expand Up @@ -79,14 +81,14 @@ func TestErrorLogPath(t *testing.T) {
}

func TestPlatFormType(t *testing.T) {
assert.Equal(t, "ios", typeForPlatForm(PlatFormIos))
assert.Equal(t, "android", typeForPlatForm(PlatFormAndroid))
assert.Equal(t, "ios", typeForPlatForm(consts.PlatFormIos))
assert.Equal(t, "android", typeForPlatForm(consts.PlatFormAndroid))
assert.Equal(t, "", typeForPlatForm(10000))
}

func TestPlatFormColor(t *testing.T) {
assert.Equal(t, blue, colorForPlatForm(PlatFormIos))
assert.Equal(t, yellow, colorForPlatForm(PlatFormAndroid))
assert.Equal(t, blue, colorForPlatForm(consts.PlatFormIos))
assert.Equal(t, yellow, colorForPlatForm(consts.PlatFormAndroid))
assert.Equal(t, reset, colorForPlatForm(1000000))
}

Expand Down
86 changes: 7 additions & 79 deletions gorush/notification.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,42 +8,10 @@ import (
"strings"
"sync"

"github.com/appleboy/go-fcm"
"github.com/appleboy/gorush/gorush/consts"
"github.com/appleboy/gorush/gorush/structs"
)

// D provide string array
type D map[string]interface{}

const (
// ApnsPriorityLow will tell APNs to send the push message at a time that takes
// into account power considerations for the device. Notifications with this
// priority might be grouped and delivered in bursts. They are throttled, and
// in some cases are not delivered.
ApnsPriorityLow = 5

// ApnsPriorityHigh will tell APNs to send the push message immediately.
// Notifications with this priority must trigger an alert, sound, or badge on
// the target device. It is an error to use this priority for a push
// notification that contains only the content-available key.
ApnsPriorityHigh = 10
)

// Alert is APNs payload
type Alert struct {
Action string `json:"action,omitempty"`
ActionLocKey string `json:"action-loc-key,omitempty"`
Body string `json:"body,omitempty"`
LaunchImage string `json:"launch-image,omitempty"`
LocArgs []string `json:"loc-args,omitempty"`
LocKey string `json:"loc-key,omitempty"`
Title string `json:"title,omitempty"`
Subtitle string `json:"subtitle,omitempty"`
TitleLocArgs []string `json:"title-loc-args,omitempty"`
TitleLocKey string `json:"title-loc-key,omitempty"`
SummaryArg string `json:"summary-arg,omitempty"`
SummaryArgCount int `json:"summary-arg-count,omitempty"`
}

// RequestPush support multiple notification request.
type RequestPush struct {
Notifications []PushNotification `json:"notifications" binding:"required"`
Expand All @@ -54,47 +22,7 @@ type PushNotification struct {
wg *sync.WaitGroup
log *[]LogPushEntry

// Common
ID string `json:"notif_id,omitempty"`
Tokens []string `json:"tokens" binding:"required"`
Platform int `json:"platform" binding:"required"`
Message string `json:"message,omitempty"`
Title string `json:"title,omitempty"`
Image string `json:"image,omitempty"`
Priority string `json:"priority,omitempty"`
ContentAvailable bool `json:"content_available,omitempty"`
MutableContent bool `json:"mutable_content,omitempty"`
Sound interface{} `json:"sound,omitempty"`
Data D `json:"data,omitempty"`
Retry int `json:"retry,omitempty"`

// Android
APIKey string `json:"api_key,omitempty"`
To string `json:"to,omitempty"`
CollapseKey string `json:"collapse_key,omitempty"`
DelayWhileIdle bool `json:"delay_while_idle,omitempty"`
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
Expiration *int64 `json:"expiration,omitempty"`
ApnsID string `json:"apns_id,omitempty"`
CollapseID string `json:"collapse_id,omitempty"`
Topic string `json:"topic,omitempty"`
PushType string `json:"push_type,omitempty"`
Badge *int `json:"badge,omitempty"`
Category string `json:"category,omitempty"`
ThreadID string `json:"thread-id,omitempty"`
URLArgs []string `json:"url-args,omitempty"`
Alert Alert `json:"alert,omitempty"`
Production bool `json:"production,omitempty"`
Development bool `json:"development,omitempty"`
SoundName string `json:"name,omitempty"`
SoundVolume float32 `json:"volume,omitempty"`
Apns D `json:"apns,omitempty"`
structs.PushNotification
}

// WaitDone decrements the WaitGroup counter.
Expand All @@ -121,7 +49,7 @@ 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/")) ||
return (p.Platform == consts.PlatFormAndroid && p.To != "" && strings.HasPrefix(p.To, "/topics/")) ||
p.Condition != ""
}

Expand All @@ -136,20 +64,20 @@ func CheckMessage(req PushNotification) error {
return errors.New(msg)
}

if len(req.Tokens) == PlatFormIos && len(req.Tokens[0]) == 0 {
if len(req.Tokens) == 1 && len(req.Tokens[0]) == 0 {
msg = "the token must not be empty"
LogAccess.Debug(msg)
return errors.New(msg)
}

if req.Platform == PlatFormAndroid && len(req.Tokens) > 1000 {
if req.Platform == consts.PlatFormAndroid && len(req.Tokens) > 1000 {
msg = "the message may specify at most 1000 registration IDs"
LogAccess.Debug(msg)
return errors.New(msg)
}

// ref: https://firebase.google.com/docs/cloud-messaging/http-server-ref
if req.Platform == PlatFormAndroid && req.TimeToLive != nil && (*req.TimeToLive < uint(0) || uint(2419200) < *req.TimeToLive) {
if req.Platform == consts.PlatFormAndroid && req.TimeToLive != nil && (*req.TimeToLive < uint(0) || uint(2419200) < *req.TimeToLive) {
msg = "the message's TimeToLive field must be an integer " +
"between 0 and 2419200 (4 weeks)"
LogAccess.Debug(msg)
Expand Down
14 changes: 8 additions & 6 deletions gorush/notification_apns.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import (
"sync"
"time"

"github.com/appleboy/gorush/gorush/consts"

"github.com/mitchellh/mapstructure"
"github.com/sideshow/apns2"
"github.com/sideshow/apns2/certificate"
Expand Down Expand Up @@ -273,9 +275,9 @@ func GetIOSNotification(req PushNotification) *apns2.Notification {
}

if len(req.Priority) > 0 {
if req.Priority == "normal" {
if req.Priority == consts.PriorityNormal {
notification.Priority = apns2.PriorityLow
} else if req.Priority == "high" {
} else if req.Priority == consts.PriorityHigh {
notification.Priority = apns2.PriorityHigh
}
}
Expand Down Expand Up @@ -399,17 +401,17 @@ Retry:
err = errors.New(res.Reason)
}
// apns server error
LogPush(FailedPush, token, req, err)
LogPush(consts.FailedPush, token, req, err)

if PushConf.Core.Sync {
req.AddLog(getLogPushEntry(FailedPush, token, req, err))
req.AddLog(getLogPushEntry(consts.FailedPush, token, req, err))
} else if PushConf.Core.FeedbackURL != "" {
go func(logger *logrus.Logger, log LogPushEntry, url string, timeout int64) {
err := DispatchFeedback(log, url, timeout)
if err != nil {
logger.Error(err)
}
}(LogError, getLogPushEntry(FailedPush, token, req, err), PushConf.Core.FeedbackURL, PushConf.Core.FeedbackTimeout)
}(LogError, getLogPushEntry(consts.FailedPush, token, req, err), PushConf.Core.FeedbackURL, PushConf.Core.FeedbackTimeout)
}

StatStorage.AddIosError(1)
Expand All @@ -422,7 +424,7 @@ Retry:
}

if res.Sent() && !isError {
LogPush(SucceededPush, token, req, nil)
LogPush(consts.SucceededPush, token, req, nil)
StatStorage.AddIosSuccess(1)
}
// free push slot
Expand Down
Loading