Merge pull request #36 from appleboy/multiple
Fix #35 support multiple notifications.
This commit is contained in:
commit
91099ff74e
3
Makefile
3
Makefile
|
@ -17,5 +17,8 @@ docker_build: clean
|
|||
tar -zxvf bin.tar.gz
|
||||
-rm -rf bin.tar.gz build.tar.gz
|
||||
|
||||
test:
|
||||
cd gopush && go test -v -covermode=count -coverprofile=coverage.out
|
||||
|
||||
clean:
|
||||
rm -rf build.tar.gz bin.tar.gz bin/*
|
||||
|
|
|
@ -174,7 +174,7 @@ func typeForPlatForm(platform int) string {
|
|||
}
|
||||
}
|
||||
|
||||
func LogPush(status, token string, req RequestPushNotification, errPush error) {
|
||||
func LogPush(status, token string, req PushNotification, errPush error) {
|
||||
var plat, platColor, output string
|
||||
|
||||
platColor = colorForPlatForm(req.Platform)
|
||||
|
|
|
@ -41,7 +41,11 @@ type Alert struct {
|
|||
TitleLocKey string `json:"title-loc-key,omitempty"`
|
||||
}
|
||||
|
||||
type RequestPushNotification struct {
|
||||
type RequestPush struct {
|
||||
Notifications []PushNotification `json:"notifications" binding:"required"`
|
||||
}
|
||||
|
||||
type PushNotification struct {
|
||||
// Common
|
||||
Tokens []string `json:"tokens" binding:"required"`
|
||||
Platform int `json:"platform" binding:"required"`
|
||||
|
@ -114,26 +118,33 @@ func InitAPNSClient() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func pushNotification(notification RequestPushNotification) bool {
|
||||
switch notification.Platform {
|
||||
case PlatFormIos:
|
||||
if !PushConf.Ios.Enabled {
|
||||
return false
|
||||
func SendNotification(req RequestPush) int {
|
||||
var count int
|
||||
for _, notification := range req.Notifications {
|
||||
switch notification.Platform {
|
||||
case PlatFormIos:
|
||||
if !PushConf.Ios.Enabled {
|
||||
continue
|
||||
}
|
||||
|
||||
count += 1
|
||||
go PushToIOS(notification)
|
||||
case PlatFormAndroid:
|
||||
if !PushConf.Android.Enabled {
|
||||
continue
|
||||
}
|
||||
|
||||
count += 1
|
||||
go PushToAndroid(notification)
|
||||
}
|
||||
go PushToIOS(notification)
|
||||
case PlatFormAndroid:
|
||||
if !PushConf.Android.Enabled {
|
||||
return false
|
||||
}
|
||||
go PushToAndroid(notification)
|
||||
}
|
||||
|
||||
return true
|
||||
return count
|
||||
}
|
||||
|
||||
// The iOS Notification Payload
|
||||
// ref: https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/TheNotificationPayload.html
|
||||
func GetIOSNotification(req RequestPushNotification) *apns.Notification {
|
||||
func GetIOSNotification(req PushNotification) *apns.Notification {
|
||||
notification := &apns.Notification{}
|
||||
|
||||
if len(req.ApnsID) > 0 {
|
||||
|
@ -225,7 +236,7 @@ func GetIOSNotification(req RequestPushNotification) *apns.Notification {
|
|||
return notification
|
||||
}
|
||||
|
||||
func PushToIOS(req RequestPushNotification) bool {
|
||||
func PushToIOS(req PushNotification) bool {
|
||||
|
||||
notification := GetIOSNotification(req)
|
||||
|
||||
|
@ -260,7 +271,7 @@ func PushToIOS(req RequestPushNotification) bool {
|
|||
|
||||
// HTTP Connection Server Reference for Android
|
||||
// https://developers.google.com/cloud-messaging/http-server-ref
|
||||
func GetAndroidNotification(req RequestPushNotification) gcm.HttpMessage {
|
||||
func GetAndroidNotification(req PushNotification) gcm.HttpMessage {
|
||||
notification := gcm.HttpMessage{}
|
||||
|
||||
notification.RegistrationIds = req.Tokens
|
||||
|
@ -311,7 +322,7 @@ func GetAndroidNotification(req RequestPushNotification) gcm.HttpMessage {
|
|||
return notification
|
||||
}
|
||||
|
||||
func PushToAndroid(req RequestPushNotification) bool {
|
||||
func PushToAndroid(req PushNotification) bool {
|
||||
var apiKey string
|
||||
|
||||
notification := GetAndroidNotification(req)
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"encoding/json"
|
||||
"github.com/buger/jsonparser"
|
||||
"github.com/google/go-gcm"
|
||||
"github.com/sideshow/apns2"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"log"
|
||||
"os"
|
||||
|
@ -64,7 +65,7 @@ func TestIOSNotificationStructure(t *testing.T) {
|
|||
|
||||
test := "test"
|
||||
message := "Welcome notification Server"
|
||||
req := RequestPushNotification{
|
||||
req := PushNotification{
|
||||
ApnsID: test,
|
||||
Topic: test,
|
||||
Expiration: time.Now().Unix(),
|
||||
|
@ -126,7 +127,7 @@ func TestIOSAlertNotificationStructure(t *testing.T) {
|
|||
var dat map[string]interface{}
|
||||
|
||||
test := "test"
|
||||
req := RequestPushNotification{
|
||||
req := PushNotification{
|
||||
Alert: Alert{
|
||||
Action: test,
|
||||
ActionLocKey: test,
|
||||
|
@ -178,7 +179,7 @@ func TestIOSAlertNotificationStructure(t *testing.T) {
|
|||
func TestAndroidNotificationStructure(t *testing.T) {
|
||||
|
||||
test := "test"
|
||||
req := RequestPushNotification{
|
||||
req := PushNotification{
|
||||
Tokens: []string{"a", "b"},
|
||||
Message: "Welcome",
|
||||
To: test,
|
||||
|
@ -219,7 +220,7 @@ func TestPushToIOS(t *testing.T) {
|
|||
PushConf.Ios.PemKeyPath = "../certificate/certificate-valid.pem"
|
||||
InitAPNSClient()
|
||||
|
||||
req := RequestPushNotification{
|
||||
req := PushNotification{
|
||||
Tokens: []string{"11aa01229f15f0f0c52029d8cf8cd0aeaf2365fe4cebc4af26cd6d76b7919ef7"},
|
||||
Platform: 1,
|
||||
Message: "Welcome",
|
||||
|
@ -235,7 +236,7 @@ func TestPushToAndroidWrongAPIKey(t *testing.T) {
|
|||
PushConf.Android.Enabled = true
|
||||
PushConf.Android.ApiKey = os.Getenv("ANDROID_API_KEY") + "a"
|
||||
|
||||
req := RequestPushNotification{
|
||||
req := PushNotification{
|
||||
Tokens: []string{"aaaaaa", "bbbbb"},
|
||||
Platform: 2,
|
||||
Message: "Welcome",
|
||||
|
@ -251,7 +252,7 @@ func TestPushToAndroidWrongToken(t *testing.T) {
|
|||
PushConf.Android.Enabled = true
|
||||
PushConf.Android.ApiKey = os.Getenv("ANDROID_API_KEY")
|
||||
|
||||
req := RequestPushNotification{
|
||||
req := PushNotification{
|
||||
Tokens: []string{"aaaaaa", "bbbbb"},
|
||||
Platform: 2,
|
||||
Message: "Welcome",
|
||||
|
@ -271,7 +272,7 @@ func TestPushToAndroidRightTokenForJSONLog(t *testing.T) {
|
|||
|
||||
android_token := os.Getenv("ANDROID_TEST_TOKEN")
|
||||
|
||||
req := RequestPushNotification{
|
||||
req := PushNotification{
|
||||
Tokens: []string{android_token, "bbbbb"},
|
||||
Platform: 2,
|
||||
Message: "Welcome",
|
||||
|
@ -289,7 +290,7 @@ func TestPushToAndroidRightTokenForStringLog(t *testing.T) {
|
|||
|
||||
android_token := os.Getenv("ANDROID_TEST_TOKEN")
|
||||
|
||||
req := RequestPushNotification{
|
||||
req := PushNotification{
|
||||
Tokens: []string{android_token, "bbbbb"},
|
||||
Platform: 2,
|
||||
Message: "Welcome",
|
||||
|
@ -307,7 +308,7 @@ func TestOverwriteAndroidApiKey(t *testing.T) {
|
|||
|
||||
android_token := os.Getenv("ANDROID_TEST_TOKEN")
|
||||
|
||||
req := RequestPushNotification{
|
||||
req := PushNotification{
|
||||
Tokens: []string{android_token, "bbbbb"},
|
||||
Platform: 2,
|
||||
Message: "Welcome",
|
||||
|
@ -318,3 +319,133 @@ func TestOverwriteAndroidApiKey(t *testing.T) {
|
|||
success := PushToAndroid(req)
|
||||
assert.False(t, success)
|
||||
}
|
||||
|
||||
func TestSenMultipleNotifications(t *testing.T) {
|
||||
PushConf = BuildDefaultPushConf()
|
||||
|
||||
PushConf.Ios.Enabled = true
|
||||
PushConf.Ios.PemKeyPath = "../certificate/certificate-valid.pem"
|
||||
InitAPNSClient()
|
||||
|
||||
PushConf.Android.Enabled = true
|
||||
PushConf.Android.ApiKey = os.Getenv("ANDROID_API_KEY")
|
||||
|
||||
android_token := os.Getenv("ANDROID_TEST_TOKEN")
|
||||
|
||||
req := RequestPush{
|
||||
Notifications: []PushNotification{
|
||||
//ios
|
||||
PushNotification{
|
||||
Tokens: []string{"11aa01229f15f0f0c52029d8cf8cd0aeaf2365fe4cebc4af26cd6d76b7919ef7"},
|
||||
Platform: 1,
|
||||
Message: "Welcome",
|
||||
},
|
||||
// android
|
||||
PushNotification{
|
||||
Tokens: []string{android_token, "bbbbb"},
|
||||
Platform: 2,
|
||||
Message: "Welcome",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
count := SendNotification(req)
|
||||
assert.Equal(t, 2, count)
|
||||
}
|
||||
|
||||
func TestDisabledAndroidNotifications(t *testing.T) {
|
||||
PushConf = BuildDefaultPushConf()
|
||||
|
||||
PushConf.Ios.Enabled = true
|
||||
PushConf.Ios.PemKeyPath = "../certificate/certificate-valid.pem"
|
||||
InitAPNSClient()
|
||||
|
||||
PushConf.Android.Enabled = false
|
||||
PushConf.Android.ApiKey = os.Getenv("ANDROID_API_KEY")
|
||||
|
||||
android_token := os.Getenv("ANDROID_TEST_TOKEN")
|
||||
|
||||
req := RequestPush{
|
||||
Notifications: []PushNotification{
|
||||
//ios
|
||||
PushNotification{
|
||||
Tokens: []string{"11aa01229f15f0f0c52029d8cf8cd0aeaf2365fe4cebc4af26cd6d76b7919ef7"},
|
||||
Platform: 1,
|
||||
Message: "Welcome",
|
||||
},
|
||||
// android
|
||||
PushNotification{
|
||||
Tokens: []string{android_token, "bbbbb"},
|
||||
Platform: 2,
|
||||
Message: "Welcome",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
count := SendNotification(req)
|
||||
assert.Equal(t, 1, count)
|
||||
}
|
||||
|
||||
func TestDisabledIosNotifications(t *testing.T) {
|
||||
PushConf = BuildDefaultPushConf()
|
||||
|
||||
PushConf.Ios.Enabled = false
|
||||
PushConf.Ios.PemKeyPath = "../certificate/certificate-valid.pem"
|
||||
InitAPNSClient()
|
||||
|
||||
PushConf.Android.Enabled = true
|
||||
PushConf.Android.ApiKey = os.Getenv("ANDROID_API_KEY")
|
||||
|
||||
android_token := os.Getenv("ANDROID_TEST_TOKEN")
|
||||
|
||||
req := RequestPush{
|
||||
Notifications: []PushNotification{
|
||||
//ios
|
||||
PushNotification{
|
||||
Tokens: []string{"11aa01229f15f0f0c52029d8cf8cd0aeaf2365fe4cebc4af26cd6d76b7919ef7"},
|
||||
Platform: 1,
|
||||
Message: "Welcome",
|
||||
},
|
||||
// android
|
||||
PushNotification{
|
||||
Tokens: []string{android_token, "bbbbb"},
|
||||
Platform: 2,
|
||||
Message: "Welcome",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
count := SendNotification(req)
|
||||
assert.Equal(t, 1, count)
|
||||
}
|
||||
|
||||
func TestMissingIosCertificate(t *testing.T) {
|
||||
PushConf = BuildDefaultPushConf()
|
||||
|
||||
PushConf.Ios.Enabled = true
|
||||
PushConf.Ios.PemKeyPath = "test"
|
||||
err := InitAPNSClient()
|
||||
|
||||
assert.Error(t, err)
|
||||
}
|
||||
|
||||
func TestAPNSClientDevHost(t *testing.T) {
|
||||
PushConf = BuildDefaultPushConf()
|
||||
|
||||
PushConf.Ios.Enabled = true
|
||||
PushConf.Ios.PemKeyPath = "../certificate/certificate-valid.pem"
|
||||
InitAPNSClient()
|
||||
|
||||
assert.Equal(t, apns2.HostDevelopment, ApnsClient.Host)
|
||||
}
|
||||
|
||||
func TestAPNSClientProdHost(t *testing.T) {
|
||||
PushConf = BuildDefaultPushConf()
|
||||
|
||||
PushConf.Ios.Enabled = true
|
||||
PushConf.Ios.Production = true
|
||||
PushConf.Ios.PemKeyPath = "../certificate/certificate-valid.pem"
|
||||
InitAPNSClient()
|
||||
|
||||
assert.Equal(t, apns2.HostProduction, ApnsClient.Host)
|
||||
}
|
||||
|
|
|
@ -21,15 +21,20 @@ func rootHandler(c *gin.Context) {
|
|||
}
|
||||
|
||||
func pushHandler(c *gin.Context) {
|
||||
var form RequestPushNotification
|
||||
var form RequestPush
|
||||
|
||||
if err := c.BindJSON(&form); err != nil {
|
||||
AbortWithError(c, http.StatusBadRequest, "Bad input request, please refer to README guide.")
|
||||
AbortWithError(c, http.StatusBadRequest, "Missing nitifications field.")
|
||||
return
|
||||
}
|
||||
|
||||
if len(form.Notifications) == 0 {
|
||||
AbortWithError(c, http.StatusBadRequest, "Notification field is empty.")
|
||||
return
|
||||
}
|
||||
|
||||
// process notification.
|
||||
pushNotification(form)
|
||||
go SendNotification(form)
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"text": "Welcome to notification server.",
|
||||
|
|
|
@ -92,15 +92,28 @@ func TestAPIStatusHandler(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
func TestMissingParameterPushHandler(t *testing.T) {
|
||||
func TestMissingNotificationsParameter(t *testing.T) {
|
||||
initTest()
|
||||
|
||||
r := gofight.New()
|
||||
|
||||
// missing some parameter.
|
||||
// missing notifications parameter.
|
||||
r.POST("/api/push").
|
||||
Run(GetMainEngine(), func(r gofight.HTTPResponse, rq gofight.HTTPRequest) {
|
||||
|
||||
assert.Equal(t, http.StatusBadRequest, r.Code)
|
||||
})
|
||||
}
|
||||
|
||||
func TestEmptyNotifications(t *testing.T) {
|
||||
initTest()
|
||||
|
||||
r := gofight.New()
|
||||
|
||||
// notifications is empty.
|
||||
r.POST("/api/push").
|
||||
SetJSON(gofight.D{
|
||||
"platform": 1,
|
||||
"notifications": []PushNotification{},
|
||||
}).
|
||||
Run(GetMainEngine(), func(r gofight.HTTPResponse, rq gofight.HTTPRequest) {
|
||||
|
||||
|
@ -108,99 +121,7 @@ func TestMissingParameterPushHandler(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
func TestDisabledIosPushHandler(t *testing.T) {
|
||||
initTest()
|
||||
|
||||
PushConf.Ios.Enabled = false
|
||||
InitAPNSClient()
|
||||
|
||||
r := gofight.New()
|
||||
|
||||
r.POST("/api/push").
|
||||
SetJSON(gofight.D{
|
||||
"tokens": []string{"11aa01229f15f0f0c52029d8cf8cd0aeaf2365fe4cebc4af26cd6d76b7919ef7"},
|
||||
"platform": 1,
|
||||
"message": "Welcome",
|
||||
}).
|
||||
Run(GetMainEngine(), func(r gofight.HTTPResponse, rq gofight.HTTPRequest) {
|
||||
|
||||
assert.Equal(t, http.StatusOK, r.Code)
|
||||
})
|
||||
}
|
||||
|
||||
func TestMissingIosCertificate(t *testing.T) {
|
||||
initTest()
|
||||
|
||||
PushConf.Ios.Enabled = true
|
||||
PushConf.Ios.PemKeyPath = "test"
|
||||
err := InitAPNSClient()
|
||||
|
||||
assert.Error(t, err)
|
||||
}
|
||||
|
||||
func TestIosPushDevelopment(t *testing.T) {
|
||||
initTest()
|
||||
|
||||
PushConf.Ios.Enabled = true
|
||||
PushConf.Ios.PemKeyPath = "../certificate/certificate-valid.pem"
|
||||
InitAPNSClient()
|
||||
|
||||
r := gofight.New()
|
||||
|
||||
r.POST("/api/push").
|
||||
SetJSON(gofight.D{
|
||||
"tokens": []string{"11aa01229f15f0f0c52029d8cf8cd0aeaf2365fe4cebc4af26cd6d76b7919ef7"},
|
||||
"platform": 1,
|
||||
"message": "Welcome",
|
||||
}).
|
||||
Run(GetMainEngine(), func(r gofight.HTTPResponse, rq gofight.HTTPRequest) {
|
||||
|
||||
assert.Equal(t, http.StatusOK, r.Code)
|
||||
})
|
||||
}
|
||||
|
||||
func TestIosPushProduction(t *testing.T) {
|
||||
initTest()
|
||||
|
||||
PushConf.Ios.Enabled = true
|
||||
PushConf.Ios.Production = true
|
||||
PushConf.Ios.PemKeyPath = "../certificate/certificate-valid.pem"
|
||||
InitAPNSClient()
|
||||
|
||||
r := gofight.New()
|
||||
|
||||
r.POST("/api/push").
|
||||
SetJSON(gofight.D{
|
||||
"tokens": []string{"11aa01229f15f0f0c52029d8cf8cd0aeaf2365fe4cebc4af26cd6d76b7919ef7"},
|
||||
"platform": 1,
|
||||
"message": "Welcome",
|
||||
}).
|
||||
Run(GetMainEngine(), func(r gofight.HTTPResponse, rq gofight.HTTPRequest) {
|
||||
|
||||
assert.Equal(t, http.StatusOK, r.Code)
|
||||
})
|
||||
}
|
||||
|
||||
func TestDisabledAndroidPushHandler(t *testing.T) {
|
||||
initTest()
|
||||
|
||||
PushConf.Android.Enabled = false
|
||||
|
||||
r := gofight.New()
|
||||
|
||||
r.POST("/api/push").
|
||||
SetJSON(gofight.D{
|
||||
"tokens": []string{"aaaaaa", "bbbbb"},
|
||||
"platform": 2,
|
||||
"message": "Welcome",
|
||||
}).
|
||||
Run(GetMainEngine(), func(r gofight.HTTPResponse, rq gofight.HTTPRequest) {
|
||||
|
||||
assert.Equal(t, http.StatusOK, r.Code)
|
||||
})
|
||||
}
|
||||
|
||||
func TestHalfSuccessAndroidPushHandler(t *testing.T) {
|
||||
func TestSuccessPushHandler(t *testing.T) {
|
||||
initTest()
|
||||
|
||||
PushConf.Android.Enabled = true
|
||||
|
@ -212,31 +133,13 @@ func TestHalfSuccessAndroidPushHandler(t *testing.T) {
|
|||
|
||||
r.POST("/api/push").
|
||||
SetJSON(gofight.D{
|
||||
"tokens": []string{android_token, "bbbbb"},
|
||||
"platform": 2,
|
||||
"message": "Welcome",
|
||||
}).
|
||||
Run(GetMainEngine(), func(r gofight.HTTPResponse, rq gofight.HTTPRequest) {
|
||||
|
||||
assert.Equal(t, http.StatusOK, r.Code)
|
||||
})
|
||||
}
|
||||
|
||||
func TestAllSuccessAndroidPushHandler(t *testing.T) {
|
||||
initTest()
|
||||
|
||||
PushConf.Android.Enabled = true
|
||||
PushConf.Android.ApiKey = os.Getenv("ANDROID_API_KEY")
|
||||
|
||||
android_token := os.Getenv("ANDROID_TEST_TOKEN")
|
||||
|
||||
r := gofight.New()
|
||||
|
||||
r.POST("/api/push").
|
||||
SetJSON(gofight.D{
|
||||
"tokens": []string{android_token, android_token},
|
||||
"platform": 2,
|
||||
"message": "Welcome",
|
||||
"notifications": []gofight.D{
|
||||
gofight.D{
|
||||
"tokens": []string{android_token, "bbbbb"},
|
||||
"platform": 2,
|
||||
"message": "Welcome",
|
||||
},
|
||||
},
|
||||
}).
|
||||
Run(GetMainEngine(), func(r gofight.HTTPResponse, rq gofight.HTTPRequest) {
|
||||
|
||||
|
|
Loading…
Reference in New Issue