support multiple notification request.
Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>
This commit is contained in:
		
							parent
							
								
									8298bb4405
								
							
						
					
					
						commit
						bbfc058d05
					
				
							
								
								
									
										3
									
								
								Makefile
								
								
								
								
							
							
						
						
									
										3
									
								
								Makefile
								
								
								
								
							|  | @ -17,5 +17,8 @@ docker_build: clean | ||||||
| 	tar -zxvf bin.tar.gz | 	tar -zxvf bin.tar.gz | ||||||
| 	-rm -rf bin.tar.gz build.tar.gz | 	-rm -rf bin.tar.gz build.tar.gz | ||||||
| 
 | 
 | ||||||
|  | test: | ||||||
|  | 	cd gopush && go test -v -covermode=count -coverprofile=coverage.out | ||||||
|  | 
 | ||||||
| clean: | clean: | ||||||
| 	rm -rf build.tar.gz bin.tar.gz bin/* | 	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 | 	var plat, platColor, output string | ||||||
| 
 | 
 | ||||||
| 	platColor = colorForPlatForm(req.Platform) | 	platColor = colorForPlatForm(req.Platform) | ||||||
|  |  | ||||||
|  | @ -41,7 +41,11 @@ type Alert struct { | ||||||
| 	TitleLocKey  string   `json:"title-loc-key,omitempty"` | 	TitleLocKey  string   `json:"title-loc-key,omitempty"` | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| type RequestPushNotification struct { | type RequestPush struct { | ||||||
|  | 	Notifications []PushNotification `json:"notifications"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | type PushNotification struct { | ||||||
| 	// Common
 | 	// Common
 | ||||||
| 	Tokens           []string `json:"tokens" binding:"required"` | 	Tokens           []string `json:"tokens" binding:"required"` | ||||||
| 	Platform         int      `json:"platform" binding:"required"` | 	Platform         int      `json:"platform" binding:"required"` | ||||||
|  | @ -114,26 +118,33 @@ func InitAPNSClient() error { | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func pushNotification(notification RequestPushNotification) bool { | func SendNotification(req RequestPush) int { | ||||||
|  | 	var count int | ||||||
|  | 	for _, notification := range req.Notifications { | ||||||
| 		switch notification.Platform { | 		switch notification.Platform { | ||||||
| 		case PlatFormIos: | 		case PlatFormIos: | ||||||
| 			if !PushConf.Ios.Enabled { | 			if !PushConf.Ios.Enabled { | ||||||
| 			return false | 				continue | ||||||
| 			} | 			} | ||||||
|  | 
 | ||||||
|  | 			count += 1 | ||||||
| 			go PushToIOS(notification) | 			go PushToIOS(notification) | ||||||
| 		case PlatFormAndroid: | 		case PlatFormAndroid: | ||||||
| 			if !PushConf.Android.Enabled { | 			if !PushConf.Android.Enabled { | ||||||
| 			return false | 				continue | ||||||
| 		} |  | ||||||
| 		go PushToAndroid(notification) |  | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 	return true | 			count += 1 | ||||||
|  | 			go PushToAndroid(notification) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return count | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // The iOS Notification Payload
 | // The iOS Notification Payload
 | ||||||
| // ref: https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/TheNotificationPayload.html
 | // 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{} | 	notification := &apns.Notification{} | ||||||
| 
 | 
 | ||||||
| 	if len(req.ApnsID) > 0 { | 	if len(req.ApnsID) > 0 { | ||||||
|  | @ -225,7 +236,7 @@ func GetIOSNotification(req RequestPushNotification) *apns.Notification { | ||||||
| 	return notification | 	return notification | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func PushToIOS(req RequestPushNotification) bool { | func PushToIOS(req PushNotification) bool { | ||||||
| 
 | 
 | ||||||
| 	notification := GetIOSNotification(req) | 	notification := GetIOSNotification(req) | ||||||
| 
 | 
 | ||||||
|  | @ -260,7 +271,7 @@ func PushToIOS(req RequestPushNotification) bool { | ||||||
| 
 | 
 | ||||||
| // HTTP Connection Server Reference for Android
 | // HTTP Connection Server Reference for Android
 | ||||||
| // https://developers.google.com/cloud-messaging/http-server-ref
 | // 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 := gcm.HttpMessage{} | ||||||
| 
 | 
 | ||||||
| 	notification.RegistrationIds = req.Tokens | 	notification.RegistrationIds = req.Tokens | ||||||
|  | @ -311,7 +322,7 @@ func GetAndroidNotification(req RequestPushNotification) gcm.HttpMessage { | ||||||
| 	return notification | 	return notification | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func PushToAndroid(req RequestPushNotification) bool { | func PushToAndroid(req PushNotification) bool { | ||||||
| 	var apiKey string | 	var apiKey string | ||||||
| 
 | 
 | ||||||
| 	notification := GetAndroidNotification(req) | 	notification := GetAndroidNotification(req) | ||||||
|  |  | ||||||
|  | @ -5,6 +5,7 @@ import ( | ||||||
| 	"github.com/buger/jsonparser" | 	"github.com/buger/jsonparser" | ||||||
| 	"github.com/google/go-gcm" | 	"github.com/google/go-gcm" | ||||||
| 	"github.com/stretchr/testify/assert" | 	"github.com/stretchr/testify/assert" | ||||||
|  | 	"github.com/sideshow/apns2" | ||||||
| 	"log" | 	"log" | ||||||
| 	"os" | 	"os" | ||||||
| 	"testing" | 	"testing" | ||||||
|  | @ -64,7 +65,7 @@ func TestIOSNotificationStructure(t *testing.T) { | ||||||
| 
 | 
 | ||||||
| 	test := "test" | 	test := "test" | ||||||
| 	message := "Welcome notification Server" | 	message := "Welcome notification Server" | ||||||
| 	req := RequestPushNotification{ | 	req := PushNotification{ | ||||||
| 		ApnsID:           test, | 		ApnsID:           test, | ||||||
| 		Topic:            test, | 		Topic:            test, | ||||||
| 		Expiration:       time.Now().Unix(), | 		Expiration:       time.Now().Unix(), | ||||||
|  | @ -126,7 +127,7 @@ func TestIOSAlertNotificationStructure(t *testing.T) { | ||||||
| 	var dat map[string]interface{} | 	var dat map[string]interface{} | ||||||
| 
 | 
 | ||||||
| 	test := "test" | 	test := "test" | ||||||
| 	req := RequestPushNotification{ | 	req := PushNotification{ | ||||||
| 		Alert: Alert{ | 		Alert: Alert{ | ||||||
| 			Action:       test, | 			Action:       test, | ||||||
| 			ActionLocKey: test, | 			ActionLocKey: test, | ||||||
|  | @ -178,7 +179,7 @@ func TestIOSAlertNotificationStructure(t *testing.T) { | ||||||
| func TestAndroidNotificationStructure(t *testing.T) { | func TestAndroidNotificationStructure(t *testing.T) { | ||||||
| 
 | 
 | ||||||
| 	test := "test" | 	test := "test" | ||||||
| 	req := RequestPushNotification{ | 	req := PushNotification{ | ||||||
| 		Tokens:                []string{"a", "b"}, | 		Tokens:                []string{"a", "b"}, | ||||||
| 		Message:               "Welcome", | 		Message:               "Welcome", | ||||||
| 		To:                    test, | 		To:                    test, | ||||||
|  | @ -219,7 +220,7 @@ func TestPushToIOS(t *testing.T) { | ||||||
| 	PushConf.Ios.PemKeyPath = "../certificate/certificate-valid.pem" | 	PushConf.Ios.PemKeyPath = "../certificate/certificate-valid.pem" | ||||||
| 	InitAPNSClient() | 	InitAPNSClient() | ||||||
| 
 | 
 | ||||||
| 	req := RequestPushNotification{ | 	req := PushNotification{ | ||||||
| 		Tokens:   []string{"11aa01229f15f0f0c52029d8cf8cd0aeaf2365fe4cebc4af26cd6d76b7919ef7"}, | 		Tokens:   []string{"11aa01229f15f0f0c52029d8cf8cd0aeaf2365fe4cebc4af26cd6d76b7919ef7"}, | ||||||
| 		Platform: 1, | 		Platform: 1, | ||||||
| 		Message:  "Welcome", | 		Message:  "Welcome", | ||||||
|  | @ -235,7 +236,7 @@ func TestPushToAndroidWrongAPIKey(t *testing.T) { | ||||||
| 	PushConf.Android.Enabled = true | 	PushConf.Android.Enabled = true | ||||||
| 	PushConf.Android.ApiKey = os.Getenv("ANDROID_API_KEY") + "a" | 	PushConf.Android.ApiKey = os.Getenv("ANDROID_API_KEY") + "a" | ||||||
| 
 | 
 | ||||||
| 	req := RequestPushNotification{ | 	req := PushNotification{ | ||||||
| 		Tokens:   []string{"aaaaaa", "bbbbb"}, | 		Tokens:   []string{"aaaaaa", "bbbbb"}, | ||||||
| 		Platform: 2, | 		Platform: 2, | ||||||
| 		Message:  "Welcome", | 		Message:  "Welcome", | ||||||
|  | @ -251,7 +252,7 @@ func TestPushToAndroidWrongToken(t *testing.T) { | ||||||
| 	PushConf.Android.Enabled = true | 	PushConf.Android.Enabled = true | ||||||
| 	PushConf.Android.ApiKey = os.Getenv("ANDROID_API_KEY") | 	PushConf.Android.ApiKey = os.Getenv("ANDROID_API_KEY") | ||||||
| 
 | 
 | ||||||
| 	req := RequestPushNotification{ | 	req := PushNotification{ | ||||||
| 		Tokens:   []string{"aaaaaa", "bbbbb"}, | 		Tokens:   []string{"aaaaaa", "bbbbb"}, | ||||||
| 		Platform: 2, | 		Platform: 2, | ||||||
| 		Message:  "Welcome", | 		Message:  "Welcome", | ||||||
|  | @ -271,7 +272,7 @@ func TestPushToAndroidRightTokenForJSONLog(t *testing.T) { | ||||||
| 
 | 
 | ||||||
| 	android_token := os.Getenv("ANDROID_TEST_TOKEN") | 	android_token := os.Getenv("ANDROID_TEST_TOKEN") | ||||||
| 
 | 
 | ||||||
| 	req := RequestPushNotification{ | 	req := PushNotification{ | ||||||
| 		Tokens:   []string{android_token, "bbbbb"}, | 		Tokens:   []string{android_token, "bbbbb"}, | ||||||
| 		Platform: 2, | 		Platform: 2, | ||||||
| 		Message:  "Welcome", | 		Message:  "Welcome", | ||||||
|  | @ -289,7 +290,7 @@ func TestPushToAndroidRightTokenForStringLog(t *testing.T) { | ||||||
| 
 | 
 | ||||||
| 	android_token := os.Getenv("ANDROID_TEST_TOKEN") | 	android_token := os.Getenv("ANDROID_TEST_TOKEN") | ||||||
| 
 | 
 | ||||||
| 	req := RequestPushNotification{ | 	req := PushNotification{ | ||||||
| 		Tokens:   []string{android_token, "bbbbb"}, | 		Tokens:   []string{android_token, "bbbbb"}, | ||||||
| 		Platform: 2, | 		Platform: 2, | ||||||
| 		Message:  "Welcome", | 		Message:  "Welcome", | ||||||
|  | @ -307,7 +308,7 @@ func TestOverwriteAndroidApiKey(t *testing.T) { | ||||||
| 
 | 
 | ||||||
| 	android_token := os.Getenv("ANDROID_TEST_TOKEN") | 	android_token := os.Getenv("ANDROID_TEST_TOKEN") | ||||||
| 
 | 
 | ||||||
| 	req := RequestPushNotification{ | 	req := PushNotification{ | ||||||
| 		Tokens:   []string{android_token, "bbbbb"}, | 		Tokens:   []string{android_token, "bbbbb"}, | ||||||
| 		Platform: 2, | 		Platform: 2, | ||||||
| 		Message:  "Welcome", | 		Message:  "Welcome", | ||||||
|  | @ -318,3 +319,133 @@ func TestOverwriteAndroidApiKey(t *testing.T) { | ||||||
| 	success := PushToAndroid(req) | 	success := PushToAndroid(req) | ||||||
| 	assert.False(t, success) | 	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) | ||||||
|  | } | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue