2016-03-24 16:46:37 +00:00
|
|
|
package main
|
|
|
|
|
2016-03-24 16:53:45 +00:00
|
|
|
import (
|
2016-03-25 08:41:47 +00:00
|
|
|
"github.com/google/go-gcm"
|
2016-03-24 16:46:37 +00:00
|
|
|
apns "github.com/sideshow/apns2"
|
2016-03-24 16:53:45 +00:00
|
|
|
"github.com/sideshow/apns2/payload"
|
2016-03-24 16:46:37 +00:00
|
|
|
"log"
|
|
|
|
)
|
|
|
|
|
|
|
|
type ExtendJSON struct {
|
|
|
|
Key string `json:"key"`
|
|
|
|
Value string `json:"val"`
|
|
|
|
}
|
|
|
|
|
2016-03-25 02:39:59 +00:00
|
|
|
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"`
|
|
|
|
TitleLocArgs []string `json:"title-loc-args,omitempty"`
|
|
|
|
TitleLocKey string `json:"title-loc-key,omitempty"`
|
|
|
|
}
|
|
|
|
|
2016-03-24 16:46:37 +00:00
|
|
|
type RequestPushNotification struct {
|
|
|
|
// Common
|
2016-03-25 02:40:29 +00:00
|
|
|
Tokens []string `json:"tokens" binding:"required"`
|
|
|
|
Platform int `json:"platform" binding:"required"`
|
|
|
|
Message string `json:"message" binding:"required"`
|
|
|
|
Priority string `json:"priority,omitempty"`
|
|
|
|
ContentAvailable bool `json:"content_available,omitempty"`
|
2016-03-25 01:34:22 +00:00
|
|
|
|
2016-03-24 16:46:37 +00:00
|
|
|
// Android
|
2016-03-25 09:56:09 +00:00
|
|
|
To string `json:"to,omitempty"`
|
2016-03-25 08:41:47 +00:00
|
|
|
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"`
|
|
|
|
Data gcm.Data `json:"data,omitempty"`
|
|
|
|
Notification gcm.Notification `json:"notification,omitempty"`
|
2016-03-25 01:34:22 +00:00
|
|
|
|
2016-03-24 16:46:37 +00:00
|
|
|
// iOS
|
2016-03-25 02:40:29 +00:00
|
|
|
ApnsID string `json:"apns_id,omitempty"`
|
|
|
|
Topic string `json:"topic,omitempty"`
|
|
|
|
Badge int `json:"badge,omitempty"`
|
|
|
|
Sound string `json:"sound,omitempty"`
|
|
|
|
Expiry int `json:"expiry,omitempty"`
|
|
|
|
Retry int `json:"retry,omitempty"`
|
|
|
|
Category string `json:"category,omitempty"`
|
|
|
|
URLArgs []string `json:"url-args,omitempty"`
|
|
|
|
Extend []ExtendJSON `json:"extend,omitempty"`
|
|
|
|
Alert alert `json:"alert,omitempty"`
|
2016-03-25 09:56:09 +00:00
|
|
|
|
2016-03-24 16:46:37 +00:00
|
|
|
// meta
|
|
|
|
IDs []uint64 `json:"seq_id,omitempty"`
|
|
|
|
}
|
|
|
|
|
|
|
|
func pushNotification(notification RequestPushNotification) bool {
|
|
|
|
var (
|
2016-03-24 16:53:45 +00:00
|
|
|
success bool
|
2016-03-24 16:46:37 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
switch notification.Platform {
|
|
|
|
case PlatFormIos:
|
2016-03-26 15:42:22 +00:00
|
|
|
success = pushNotificationIos(notification)
|
2016-03-24 16:46:37 +00:00
|
|
|
case PlatFormAndroid:
|
|
|
|
success = pushNotificationAndroid(notification)
|
|
|
|
}
|
|
|
|
|
|
|
|
return success
|
|
|
|
}
|
|
|
|
|
2016-03-26 15:42:22 +00:00
|
|
|
func pushNotificationIos(req RequestPushNotification) bool {
|
2016-03-24 16:46:37 +00:00
|
|
|
|
|
|
|
for _, token := range req.Tokens {
|
|
|
|
notification := &apns.Notification{}
|
|
|
|
notification.DeviceToken = token
|
|
|
|
|
|
|
|
if len(req.ApnsID) > 0 {
|
|
|
|
notification.ApnsID = req.ApnsID
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(req.Topic) > 0 {
|
|
|
|
notification.Topic = req.Topic
|
|
|
|
}
|
|
|
|
|
2016-03-25 02:39:59 +00:00
|
|
|
if len(req.Priority) > 0 && req.Priority == "normal" {
|
2016-03-24 16:46:37 +00:00
|
|
|
notification.Priority = apns.PriorityLow
|
|
|
|
}
|
|
|
|
|
|
|
|
payload := payload.NewPayload().Alert(req.Message)
|
|
|
|
|
|
|
|
if req.Badge > 0 {
|
|
|
|
payload.Badge(req.Badge)
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(req.Sound) > 0 {
|
|
|
|
payload.Sound(req.Sound)
|
|
|
|
}
|
|
|
|
|
2016-03-25 01:34:22 +00:00
|
|
|
if req.ContentAvailable {
|
|
|
|
payload.ContentAvailable()
|
|
|
|
}
|
|
|
|
|
2016-03-24 16:46:37 +00:00
|
|
|
if len(req.Extend) > 0 {
|
|
|
|
for _, extend := range req.Extend {
|
|
|
|
payload.Custom(extend.Key, extend.Value)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-03-25 02:39:59 +00:00
|
|
|
// Alert dictionary
|
|
|
|
|
|
|
|
if len(req.Alert.Title) > 0 {
|
|
|
|
payload.AlertTitle(req.Alert.Title)
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(req.Alert.TitleLocKey) > 0 {
|
|
|
|
payload.AlertTitleLocKey(req.Alert.TitleLocKey)
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(req.Alert.LocArgs) > 0 {
|
|
|
|
payload.AlertTitleLocArgs(req.Alert.LocArgs)
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(req.Alert.Body) > 0 {
|
|
|
|
payload.AlertBody(req.Alert.Body)
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(req.Alert.LaunchImage) > 0 {
|
|
|
|
payload.AlertLaunchImage(req.Alert.LaunchImage)
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(req.Alert.LocKey) > 0 {
|
|
|
|
payload.AlertLocKey(req.Alert.LocKey)
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(req.Alert.Action) > 0 {
|
|
|
|
payload.AlertAction(req.Alert.Action)
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(req.Alert.ActionLocKey) > 0 {
|
|
|
|
payload.AlertActionLocKey(req.Alert.ActionLocKey)
|
|
|
|
}
|
|
|
|
|
|
|
|
// General
|
|
|
|
|
|
|
|
if len(req.Category) > 0 {
|
|
|
|
payload.Category(req.Category)
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(req.URLArgs) > 0 {
|
|
|
|
payload.URLArgs(req.URLArgs)
|
|
|
|
}
|
|
|
|
|
2016-03-24 16:46:37 +00:00
|
|
|
notification.Payload = payload
|
|
|
|
|
|
|
|
// send ios notification
|
2016-03-26 15:42:22 +00:00
|
|
|
res, err := ApnsClient.Push(notification)
|
2016-03-24 16:46:37 +00:00
|
|
|
|
|
|
|
if err != nil {
|
2016-03-24 16:53:45 +00:00
|
|
|
log.Println("There was an error", err)
|
|
|
|
return false
|
2016-03-24 16:46:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if res.Sent() {
|
2016-03-24 16:53:45 +00:00
|
|
|
log.Println("APNs ID:", res.ApnsID)
|
2016-03-26 15:42:22 +00:00
|
|
|
return true
|
2016-03-24 16:46:37 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
func pushNotificationAndroid(req RequestPushNotification) bool {
|
|
|
|
|
2016-03-25 08:41:47 +00:00
|
|
|
// HTTP Connection Server Reference for Android
|
|
|
|
// https://developers.google.com/cloud-messaging/http-server-ref
|
|
|
|
notification := gcm.HttpMessage{}
|
|
|
|
|
|
|
|
notification.RegistrationIds = req.Tokens
|
|
|
|
|
2016-03-25 09:56:09 +00:00
|
|
|
if len(req.To) > 0 {
|
|
|
|
notification.To = req.To
|
2016-03-25 08:41:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if len(req.Priority) > 0 && req.Priority == "high" {
|
|
|
|
notification.Priority = "high"
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(req.CollapseKey) > 0 {
|
|
|
|
notification.CollapseKey = req.CollapseKey
|
|
|
|
}
|
|
|
|
|
|
|
|
if req.ContentAvailable {
|
|
|
|
notification.ContentAvailable = true
|
|
|
|
}
|
|
|
|
|
|
|
|
if req.DelayWhileIdle {
|
|
|
|
notification.DelayWhileIdle = true
|
|
|
|
}
|
|
|
|
|
|
|
|
if req.TimeToLive > 0 {
|
|
|
|
notification.TimeToLive = req.TimeToLive
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(req.RestrictedPackageName) > 0 {
|
|
|
|
notification.RestrictedPackageName = req.RestrictedPackageName
|
|
|
|
}
|
|
|
|
|
|
|
|
if req.DryRun {
|
|
|
|
notification.DryRun = true
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(req.Data) > 0 {
|
|
|
|
notification.Data = req.Data
|
|
|
|
}
|
|
|
|
|
|
|
|
notification.Notification = &req.Notification
|
|
|
|
|
2016-03-25 15:50:32 +00:00
|
|
|
// Set request message if body is empty
|
|
|
|
if len(notification.Notification.Body) == 0 {
|
|
|
|
notification.Notification.Body = req.Message
|
|
|
|
}
|
2016-03-25 08:41:47 +00:00
|
|
|
|
2016-03-26 05:59:56 +00:00
|
|
|
res, err := gcm.SendHttp(PushConf.Android.ApiKey, notification)
|
2016-03-25 08:41:47 +00:00
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
log.Println(err)
|
|
|
|
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
if res.Error != "" {
|
|
|
|
log.Println("GCM Error Message: " + res.Error)
|
|
|
|
}
|
|
|
|
|
|
|
|
if res.Success > 0 {
|
|
|
|
log.Printf("Success count: %d, Failure count: %d", res.Success, res.Failure)
|
|
|
|
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
2016-03-24 16:46:37 +00:00
|
|
|
return true
|
|
|
|
}
|