mirror of
https://github.com/status-im/go-fcm.git
synced 2025-02-16 22:17:05 +00:00
code comments - godoc
This commit is contained in:
parent
079508a609
commit
1b3a6b7e10
102
fcm.go
102
fcm.go
@ -7,35 +7,41 @@ import (
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"time"
|
||||
// "github.com/jpillora/backoff"
|
||||
)
|
||||
|
||||
const (
|
||||
// fcm_server_url fcm server url
|
||||
fcm_server_url = "https://fcm.googleapis.com/fcm/send"
|
||||
// MAX_TTL the default ttl for a notification
|
||||
MAX_TTL = 2419200
|
||||
// Priority_HIGH notification priority
|
||||
Priority_HIGH = "high"
|
||||
// Priority_NORMAL notification priority
|
||||
Priority_NORMAL = "normal"
|
||||
// retry_after_header header name
|
||||
retry_after_header = "Retry-After"
|
||||
// error_key readable error caching !
|
||||
error_key = "error"
|
||||
)
|
||||
|
||||
var (
|
||||
// minBackoff = 1 * time.Second
|
||||
// maxBackoff = 10 * time.Second
|
||||
// retreyableErrors whether the error is a retryable
|
||||
retreyableErrors = map[string]bool{
|
||||
"Unavailable": true,
|
||||
"InternalServerError": true,
|
||||
}
|
||||
|
||||
// for testing purposes
|
||||
// fcmServerUrl for testing purposes
|
||||
fcmServerUrl = fcm_server_url
|
||||
)
|
||||
|
||||
// FcmClient stores the key and the Message (FcmMsg)
|
||||
type FcmClient struct {
|
||||
ApiKey string
|
||||
Message FcmMsg
|
||||
}
|
||||
|
||||
// FcmMsg represents fcm request message
|
||||
type FcmMsg struct {
|
||||
Data map[string]string `json:"data,omitempty"`
|
||||
To string `json:"to,omitempty"`
|
||||
@ -51,6 +57,7 @@ type FcmMsg struct {
|
||||
Condition string `json:"condition,omitempty"`
|
||||
}
|
||||
|
||||
// FcmMsg represents fcm response message - (tokens and topics)
|
||||
type FcmResponseStatus struct {
|
||||
Ok bool
|
||||
StatusCode int
|
||||
@ -64,6 +71,7 @@ type FcmResponseStatus struct {
|
||||
RetryAfter string
|
||||
}
|
||||
|
||||
// NotificationPayload notification message payload
|
||||
type NotificationPayload struct {
|
||||
Title string `json:"title,omitempty"`
|
||||
Body string `json:"body,omitempty"`
|
||||
@ -79,24 +87,8 @@ type NotificationPayload struct {
|
||||
TitleLocArgs string `json:"title_loc_args,omitempty"`
|
||||
}
|
||||
|
||||
type InstanceIdResult struct {
|
||||
Application string `json:"application,omitempty"`
|
||||
AuthorizedEntity string `json:"authorizedEntity,omitempty"`
|
||||
ApplicationVersion string `json:"applicationVersion,omitempty"`
|
||||
AppSigner string `json:"appSigner,omitempty"`
|
||||
AttestStatus string `json:"attestStatus,omitempty"`
|
||||
Platform string `json:"platform,omitempty"`
|
||||
connectionType string `json:"connectionType,omitempty"`
|
||||
connectDate string `json:"connectDate,omitempty"`
|
||||
rel map[string]InstanceIdRelTopics `json:"rel,omitempty"`
|
||||
}
|
||||
|
||||
type InstanceIdRelTopics struct {
|
||||
TopicName map[string]TopicDate
|
||||
}
|
||||
|
||||
type TopicDate map[string]string
|
||||
|
||||
// NewFcmClient init and create fcm client
|
||||
func NewFcmClient(apiKey string) *FcmClient {
|
||||
fcmc := new(FcmClient)
|
||||
fcmc.ApiKey = apiKey
|
||||
@ -104,6 +96,7 @@ func NewFcmClient(apiKey string) *FcmClient {
|
||||
return fcmc
|
||||
}
|
||||
|
||||
// NewFcmTopicMsg sets the targeted token/topic and the data payload
|
||||
func (this *FcmClient) NewFcmTopicMsg(to string, body map[string]string) *FcmClient {
|
||||
|
||||
this.NewFcmMsgTo(to, body)
|
||||
@ -111,6 +104,7 @@ func (this *FcmClient) NewFcmTopicMsg(to string, body map[string]string) *FcmCli
|
||||
return this
|
||||
}
|
||||
|
||||
// NewFcmMsgTo sets the targeted token/topic and the data payload
|
||||
func (this *FcmClient) NewFcmMsgTo(to string, body map[string]string) *FcmClient {
|
||||
this.Message.To = to
|
||||
this.Message.Data = body
|
||||
@ -118,6 +112,7 @@ func (this *FcmClient) NewFcmMsgTo(to string, body map[string]string) *FcmClient
|
||||
return this
|
||||
}
|
||||
|
||||
// SetMsgData sets data payload
|
||||
func (this *FcmClient) SetMsgData(body map[string]string) *FcmClient {
|
||||
|
||||
this.Message.Data = body
|
||||
@ -126,6 +121,7 @@ func (this *FcmClient) SetMsgData(body map[string]string) *FcmClient {
|
||||
|
||||
}
|
||||
|
||||
// NewFcmRegIdsMsg gets a list of devices with data payload
|
||||
func (this *FcmClient) NewFcmRegIdsMsg(list []string, body map[string]string) *FcmClient {
|
||||
this.newDevicesList(list)
|
||||
this.Message.Data = body
|
||||
@ -134,6 +130,7 @@ func (this *FcmClient) NewFcmRegIdsMsg(list []string, body map[string]string) *F
|
||||
|
||||
}
|
||||
|
||||
// newDevicesList init the devices list
|
||||
func (this *FcmClient) newDevicesList(list []string) *FcmClient {
|
||||
this.Message.RegistrationIds = make([]string, len(list))
|
||||
copy(this.Message.RegistrationIds, list)
|
||||
@ -142,6 +139,7 @@ func (this *FcmClient) newDevicesList(list []string) *FcmClient {
|
||||
|
||||
}
|
||||
|
||||
// AppendDevices adds more devices/tokens to the Fcm request
|
||||
func (this *FcmClient) AppendDevices(list []string) *FcmClient {
|
||||
|
||||
this.Message.RegistrationIds = append(this.Message.RegistrationIds, list...)
|
||||
@ -149,10 +147,12 @@ func (this *FcmClient) AppendDevices(list []string) *FcmClient {
|
||||
return this
|
||||
}
|
||||
|
||||
// apiKeyHeader generates the value of the Authorization key
|
||||
func (this *FcmClient) apiKeyHeader() string {
|
||||
return fmt.Sprintf("key=%v", this.ApiKey)
|
||||
}
|
||||
|
||||
// sendOnce send a single request to fcm
|
||||
func (this *FcmClient) sendOnce() (*FcmResponseStatus, error) {
|
||||
|
||||
fcmRespStatus := new(FcmResponseStatus)
|
||||
@ -208,16 +208,19 @@ func (this *FcmClient) sendOnce() (*FcmResponseStatus, error) {
|
||||
|
||||
}
|
||||
|
||||
// Send to fcm
|
||||
func (this *FcmClient) Send() (*FcmResponseStatus, error) {
|
||||
return this.sendOnce()
|
||||
|
||||
}
|
||||
|
||||
// toJsonByte converts FcmMsg to a json byte
|
||||
func (this *FcmMsg) toJsonByte() ([]byte, error) {
|
||||
|
||||
return json.Marshal(this)
|
||||
|
||||
}
|
||||
|
||||
// parseStatusBody parse FCM response body
|
||||
func (this *FcmResponseStatus) parseStatusBody(body []byte) error {
|
||||
|
||||
if err := json.Unmarshal([]byte(body), &this); err != nil {
|
||||
@ -227,6 +230,8 @@ func (this *FcmResponseStatus) parseStatusBody(body []byte) error {
|
||||
|
||||
}
|
||||
|
||||
// SetPriorety Sets the priority of the message.
|
||||
// Priority_HIGH or Priority_NORMAL
|
||||
func (this *FcmClient) SetPriorety(p string) {
|
||||
|
||||
if p == Priority_HIGH {
|
||||
@ -236,6 +241,11 @@ func (this *FcmClient) SetPriorety(p string) {
|
||||
}
|
||||
}
|
||||
|
||||
// SetCollapseKey This parameter identifies a group of messages
|
||||
// (e.g., with collapse_key: "Updates Available") that can be collapsed,
|
||||
// so that only the last message gets sent when delivery can be resumed.
|
||||
// This is intended to avoid sending too many of the same messages when the
|
||||
// device comes back online or becomes active (see delay_while_idle).
|
||||
func (this *FcmClient) SetCollapseKey(val string) *FcmClient {
|
||||
|
||||
this.Message.CollapseKey = val
|
||||
@ -243,6 +253,8 @@ func (this *FcmClient) SetCollapseKey(val string) *FcmClient {
|
||||
return this
|
||||
}
|
||||
|
||||
// SetNotificationPayload sets the notification payload based on the specs
|
||||
// https://firebase.google.com/docs/cloud-messaging/http-server-ref
|
||||
func (this *FcmClient) SetNotificationPayload(payload *NotificationPayload) *FcmClient {
|
||||
|
||||
this.Message.Notification = *payload
|
||||
@ -250,6 +262,10 @@ func (this *FcmClient) SetNotificationPayload(payload *NotificationPayload) *Fcm
|
||||
return this
|
||||
}
|
||||
|
||||
// SetContentAvailable On iOS, use this field to represent content-available
|
||||
// in the APNS payload. When a notification or message is sent and this is set
|
||||
// to true, an inactive client app is awoken. On Android, data messages wake
|
||||
// the app by default. On Chrome, currently not supported.
|
||||
func (this *FcmClient) SetContentAvailable(isContentAvailable bool) *FcmClient {
|
||||
|
||||
this.Message.ContentAvailable = isContentAvailable
|
||||
@ -257,12 +273,21 @@ func (this *FcmClient) SetContentAvailable(isContentAvailable bool) *FcmClient {
|
||||
return this
|
||||
}
|
||||
|
||||
// SetDelayWhileIdle When this parameter is set to true, it indicates that
|
||||
// the message should not be sent until the device becomes active.
|
||||
// The default value is false.
|
||||
func (this *FcmClient) SetDelayWhileIdle(isDelayWhileIdle bool) *FcmClient {
|
||||
|
||||
this.Message.DelayWhileIdle = isDelayWhileIdle
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
// SetTimeToLive This parameter specifies how long (in seconds) the message
|
||||
// should be kept in FCM storage if the device is offline. The maximum time
|
||||
// to live supported is 4 weeks, and the default value is 4 weeks.
|
||||
// For more information, see
|
||||
// https://firebase.google.com/docs/cloud-messaging/concept-options#ttl
|
||||
func (this *FcmClient) SetTimeToLive(ttl int) *FcmClient {
|
||||
|
||||
if ttl > MAX_TTL {
|
||||
@ -277,6 +302,9 @@ func (this *FcmClient) SetTimeToLive(ttl int) *FcmClient {
|
||||
return this
|
||||
}
|
||||
|
||||
// SetRestrictedPackageName This parameter specifies the package name of the
|
||||
// application where the registration tokens must match in order to
|
||||
// receive the message.
|
||||
func (this *FcmClient) SetRestrictedPackageName(pkg string) *FcmClient {
|
||||
|
||||
this.Message.RestrictedPackageName = pkg
|
||||
@ -284,6 +312,9 @@ func (this *FcmClient) SetRestrictedPackageName(pkg string) *FcmClient {
|
||||
return this
|
||||
}
|
||||
|
||||
// SetDryRun This parameter, when set to true, allows developers to test
|
||||
// a request without actually sending a message.
|
||||
// The default value is false
|
||||
func (this *FcmClient) SetDryRun(drun bool) *FcmClient {
|
||||
|
||||
this.Message.DryRun = drun
|
||||
@ -291,6 +322,7 @@ func (this *FcmClient) SetDryRun(drun bool) *FcmClient {
|
||||
return this
|
||||
}
|
||||
|
||||
// PrintResults prints the FcmResponseStatus results for fast using and debugging
|
||||
func (this *FcmResponseStatus) PrintResults() {
|
||||
fmt.Println("Status Code :", this.StatusCode)
|
||||
fmt.Println("Success :", this.Success)
|
||||
@ -306,6 +338,8 @@ func (this *FcmResponseStatus) PrintResults() {
|
||||
}
|
||||
}
|
||||
|
||||
// IsTimeout check whether the response timeout based on http response status
|
||||
// code and if any error is retryable
|
||||
func (this *FcmResponseStatus) IsTimeout() bool {
|
||||
if this.StatusCode > 500 {
|
||||
return true
|
||||
@ -322,33 +356,15 @@ func (this *FcmResponseStatus) IsTimeout() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
// GetRetryAfterTime converts the retrey after response header
|
||||
// to a time.Duration
|
||||
func (this *FcmResponseStatus) GetRetryAfterTime() (t time.Duration, e error) {
|
||||
t, e = time.ParseDuration(this.RetryAfter)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
// SetCondition to set a logical expression of conditions that determine the message target
|
||||
func (this *FcmClient) SetCondition(condition string) *FcmClient {
|
||||
this.Message.Condition = condition
|
||||
return this
|
||||
}
|
||||
|
||||
// func newBackoffHandler() *backoff.Backoff {
|
||||
// b := &backoff.Backoff{
|
||||
//
|
||||
// Min: minBackoff,
|
||||
// Max: maxBackoff,
|
||||
// Jitter: true,
|
||||
// }
|
||||
//
|
||||
// return b
|
||||
// }
|
||||
|
||||
// func setMinBackoff(m time.Duration) {
|
||||
// minBackoff = m
|
||||
// }
|
||||
//
|
||||
// func setMaxBackoff(m time.Duration) {
|
||||
// maxBackoff = m
|
||||
// }
|
||||
|
@ -11,23 +11,37 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
// instance_id_info_with_details_srv_url
|
||||
instance_id_info_with_details_srv_url = "https://iid.googleapis.com/iid/info/%s?details=true"
|
||||
|
||||
// instance_id_info_no_details_srv_url
|
||||
instance_id_info_no_details_srv_url = "https://iid.googleapis.com/iid/info/%s"
|
||||
|
||||
// subscribe_instanceid_to_topic_srv_url
|
||||
subscribe_instanceid_to_topic_srv_url = "https://iid.googleapis.com/iid/v1/%s/rel/topics/%s"
|
||||
|
||||
// batch_add_srv_url
|
||||
batch_add_srv_url = "https://iid.googleapis.com/iid/v1:batchAdd"
|
||||
|
||||
// batch_rem_srv_url
|
||||
batch_rem_srv_url = "https://iid.googleapis.com/iid/v1:batchRemove"
|
||||
|
||||
// apns_batch_import_srv_url
|
||||
apns_batch_import_srv_url = "https://iid.googleapis.com/iid/v1:batchImport"
|
||||
|
||||
// apns_token_key
|
||||
apns_token_key = "apns_token"
|
||||
// status_key
|
||||
status_key = "status"
|
||||
// reg_token_key
|
||||
reg_token_key = "registration_token"
|
||||
|
||||
// topics
|
||||
topics = "/topics/"
|
||||
)
|
||||
|
||||
var (
|
||||
// batchErrors response errors
|
||||
batchErrors = map[string]bool{
|
||||
"NOT_FOUND": true,
|
||||
"INVALID_ARGUMENT": true,
|
||||
@ -36,6 +50,7 @@ var (
|
||||
}
|
||||
)
|
||||
|
||||
// InstanceIdInfoResponse response for instance id info request
|
||||
type InstanceIdInfoResponse struct {
|
||||
Application string `json:"application,omitempty"`
|
||||
AuthorizedEntity string `json:"authorizedEntity,omitempty"`
|
||||
@ -49,17 +64,21 @@ type InstanceIdInfoResponse struct {
|
||||
Rel map[string]map[string]map[string]string `json:"rel,omitempty"`
|
||||
}
|
||||
|
||||
// SubscribeResponse response for single topic subscribtion
|
||||
type SubscribeResponse struct {
|
||||
Error string `json:"error,omitempty"`
|
||||
Status string
|
||||
StatusCode int
|
||||
}
|
||||
|
||||
|
||||
// BatchRequest add/remove request
|
||||
type BatchRequest struct {
|
||||
To string `json:"to,omitempty"`
|
||||
RegTokens []string `json:"registration_tokens,omitempty"`
|
||||
}
|
||||
|
||||
// BatchResponse add/remove response
|
||||
type BatchResponse struct {
|
||||
Error string `json:"error,omitempty"`
|
||||
Results []map[string]string `json:"results,omitempty"`
|
||||
@ -67,12 +86,16 @@ type BatchResponse struct {
|
||||
StatusCode int
|
||||
}
|
||||
|
||||
|
||||
// ApnsBatchRequest apns import request
|
||||
type ApnsBatchRequest struct {
|
||||
App string `json:"application,omitempty"`
|
||||
Sandbox bool `json:"sandbox,omitempty"`
|
||||
ApnsTokens []string `json:"apns_tokens,omitempty"`
|
||||
}
|
||||
|
||||
|
||||
// ApnsBatchResponse apns import response
|
||||
type ApnsBatchResponse struct {
|
||||
Results []map[string]string `json:"results,omitempty"`
|
||||
Error string `json:"error,omitempty"`
|
||||
@ -80,6 +103,8 @@ type ApnsBatchResponse struct {
|
||||
StatusCode int
|
||||
}
|
||||
|
||||
|
||||
// GetInfo gets the instance id info
|
||||
func (this *FcmClient) GetInfo(withDetails bool, instanceIdToken string) (*InstanceIdInfoResponse, error) {
|
||||
|
||||
var request_url string = generateGetInfoUrl(instance_id_info_no_details_srv_url, instanceIdToken)
|
||||
@ -117,6 +142,7 @@ func (this *FcmClient) GetInfo(withDetails bool, instanceIdToken string) (*Insta
|
||||
return infoResponse, nil
|
||||
}
|
||||
|
||||
// parseGetInfo parses response to InstanceIdInfoResponse
|
||||
func parseGetInfo(body []byte) (*InstanceIdInfoResponse, error) {
|
||||
|
||||
info := new(InstanceIdInfoResponse)
|
||||
@ -129,6 +155,7 @@ func parseGetInfo(body []byte) (*InstanceIdInfoResponse, error) {
|
||||
|
||||
}
|
||||
|
||||
// PrintResults prints InstanceIdInfoResponse, for faster debugging
|
||||
func (this *InstanceIdInfoResponse) PrintResults() {
|
||||
fmt.Println("Error : ", this.Error)
|
||||
fmt.Println("App : ", this.Application)
|
||||
@ -149,10 +176,12 @@ func (this *InstanceIdInfoResponse) PrintResults() {
|
||||
}
|
||||
}
|
||||
|
||||
// generateGetInfoUrl generate based on with details and the instance token
|
||||
func generateGetInfoUrl(srv string, instanceIdToken string) string {
|
||||
return fmt.Sprintf(srv, instanceIdToken)
|
||||
}
|
||||
|
||||
// SubscribeToTopic subscribes a single device/token to a topic
|
||||
func (this *FcmClient) SubscribeToTopic(instanceIdToken string, topic string) (*SubscribeResponse, error) {
|
||||
|
||||
request, err := http.NewRequest("POST", generateSubToTopicUrl(instanceIdToken, topic), nil)
|
||||
@ -184,6 +213,7 @@ func (this *FcmClient) SubscribeToTopic(instanceIdToken string, topic string) (*
|
||||
return subResponse, nil
|
||||
}
|
||||
|
||||
// parseSubscribeResponse converts a byte response to a SubscribeResponse
|
||||
func parseSubscribeResponse(body []byte, resp *http.Response) (*SubscribeResponse, error) {
|
||||
|
||||
subResp := new(SubscribeResponse)
|
||||
@ -197,6 +227,7 @@ func parseSubscribeResponse(body []byte, resp *http.Response) (*SubscribeRespons
|
||||
return subResp, nil
|
||||
}
|
||||
|
||||
// PrintResults prints SubscribeResponse, for faster debugging
|
||||
func (this *SubscribeResponse) PrintResults() {
|
||||
|
||||
fmt.Println("Response Status: ", this.Status)
|
||||
@ -207,6 +238,7 @@ func (this *SubscribeResponse) PrintResults() {
|
||||
|
||||
}
|
||||
|
||||
// generateSubToTopicUrl generates a url based on the instnace id and topic name
|
||||
func generateSubToTopicUrl(instaceId string, topic string) string {
|
||||
Tmptopic := strings.ToLower(topic)
|
||||
if strings.Contains(Tmptopic, "/topics/") {
|
||||
@ -216,6 +248,7 @@ func generateSubToTopicUrl(instaceId string, topic string) string {
|
||||
return fmt.Sprintf(subscribe_instanceid_to_topic_srv_url, instaceId, topic)
|
||||
}
|
||||
|
||||
// BatchSubscribeToTopic subscribes (many) devices/tokens to a given topic
|
||||
func (this *FcmClient) BatchSubscribeToTopic(tokens []string, topic string) (*BatchResponse, error) {
|
||||
|
||||
jsonByte, err := generateBatchRequest(tokens, topic)
|
||||
@ -256,6 +289,7 @@ func (this *FcmClient) BatchSubscribeToTopic(tokens []string, topic string) (*Ba
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// BatchUnsubscribeFromTopic unsubscribes (many) devices/tokens from a given topic
|
||||
func (this *FcmClient) BatchUnsubscribeFromTopic(tokens []string, topic string) (*BatchResponse, error) {
|
||||
|
||||
jsonByte, err := generateBatchRequest(tokens, topic)
|
||||
@ -297,6 +331,7 @@ func (this *FcmClient) BatchUnsubscribeFromTopic(tokens []string, topic string)
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// PrintResults prints BatchResponse, for faster debugging
|
||||
func (this *BatchResponse) PrintResults() {
|
||||
fmt.Println("Error : ", this.Error)
|
||||
fmt.Println("Status : ", this.Status)
|
||||
@ -308,6 +343,7 @@ func (this *BatchResponse) PrintResults() {
|
||||
}
|
||||
}
|
||||
|
||||
// generateBatchRequest based on tokens and topic
|
||||
func generateBatchRequest(tokens []string, topic string) ([]byte, error) {
|
||||
envelope := new(BatchRequest)
|
||||
envelope.To = topics + extractTopicName(topic)
|
||||
@ -318,6 +354,7 @@ func generateBatchRequest(tokens []string, topic string) ([]byte, error) {
|
||||
|
||||
}
|
||||
|
||||
// extractTopicName extract topic name for valid topic name input
|
||||
func extractTopicName(inTopic string) (result string) {
|
||||
Tmptopic := strings.ToLower(inTopic)
|
||||
if strings.Contains(Tmptopic, "/topics/") {
|
||||
@ -330,6 +367,7 @@ func extractTopicName(inTopic string) (result string) {
|
||||
return
|
||||
}
|
||||
|
||||
// generateBatchResponse converts a byte response to BatchResponse
|
||||
func generateBatchResponse(resp []byte) (*BatchResponse, error) {
|
||||
result := new(BatchResponse)
|
||||
|
||||
@ -341,6 +379,7 @@ func generateBatchResponse(resp []byte) (*BatchResponse, error) {
|
||||
|
||||
}
|
||||
|
||||
// ApnsBatchImportRequest apns import requst
|
||||
func (this *FcmClient) ApnsBatchImportRequest(apnsReq *ApnsBatchRequest) (*ApnsBatchResponse, error) {
|
||||
|
||||
jsonByte, err := apnsReq.ToByte()
|
||||
@ -384,6 +423,7 @@ func (this *FcmClient) ApnsBatchImportRequest(apnsReq *ApnsBatchRequest) (*ApnsB
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// ToByte converts ApnsBatchRequest to a byte
|
||||
func (this *ApnsBatchRequest) ToByte() ([]byte, error) {
|
||||
data, err := json.Marshal(this)
|
||||
if err != nil {
|
||||
@ -393,6 +433,7 @@ func (this *ApnsBatchRequest) ToByte() ([]byte, error) {
|
||||
return data, nil
|
||||
}
|
||||
|
||||
// parseApnsBatchResponse converts apns byte response to ApnsBatchResponse
|
||||
func parseApnsBatchResponse(resp []byte) (*ApnsBatchResponse, error) {
|
||||
|
||||
result := new(ApnsBatchResponse)
|
||||
@ -404,6 +445,7 @@ func parseApnsBatchResponse(resp []byte) (*ApnsBatchResponse, error) {
|
||||
|
||||
}
|
||||
|
||||
// PrintResults prints ApnsBatchResponse, for faster debugging
|
||||
func (this *ApnsBatchResponse) PrintResults() {
|
||||
fmt.Println("Status : ", this.Status)
|
||||
fmt.Println("StatusCode : ", this.StatusCode)
|
||||
|
Loading…
x
Reference in New Issue
Block a user