Skip to content
Merged
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
63 changes: 40 additions & 23 deletions messaging/messaging.go
Original file line number Diff line number Diff line change
Expand Up @@ -214,36 +214,53 @@ func (p *APNSPayload) MarshalJSON() ([]byte, error) {
// Alert may be specified as a string (via the AlertString field), or as a struct (via the Alert
// field).
type Aps struct {
AlertString string `json:"-"`
Alert *ApsAlert `json:"-"`
Badge *int `json:"badge,omitempty"`
Sound string `json:"sound,omitempty"`
ContentAvailable bool `json:"-"`
Category string `json:"category,omitempty"`
ThreadID string `json:"thread-id,omitempty"`
AlertString string
Alert *ApsAlert
Badge *int
Sound string
ContentAvailable bool
MutableContent bool
Category string
ThreadID string
CustomData map[string]interface{}
}

// MarshalJSON marshals an Aps into JSON (for internal use only).
func (a *Aps) MarshalJSON() ([]byte, error) {
type apsAlias Aps
s := &struct {
Alert interface{} `json:"alert,omitempty"`
ContentAvailable *int `json:"content-available,omitempty"`
*apsAlias
}{
apsAlias: (*apsAlias)(a),
}

// standardFields creates a map containing all the fields except the custom data.
func (a *Aps) standardFields() map[string]interface{} {
m := make(map[string]interface{})
if a.Alert != nil {
s.Alert = a.Alert
m["alert"] = a.Alert
} else if a.AlertString != "" {
s.Alert = a.AlertString
m["alert"] = a.AlertString
}
if a.ContentAvailable {
one := 1
s.ContentAvailable = &one
m["content-available"] = 1
}
return json.Marshal(s)
if a.MutableContent {
m["mutable-content"] = 1
}
if a.Badge != nil {
m["badge"] = *a.Badge
}
if a.Sound != "" {
m["sound"] = a.Sound
}
if a.Category != "" {
m["category"] = a.Category
}
if a.ThreadID != "" {
m["thread-id"] = a.ThreadID
}
return m
}

// MarshalJSON marshals an Aps into JSON (for internal use only).
func (a *Aps) MarshalJSON() ([]byte, error) {
m := a.standardFields()
for k, v := range a.CustomData {
m[k] = v
}
return json.Marshal(m)
}

// ApsAlert is the alert payload that can be included in an Aps.
Expand Down
22 changes: 22 additions & 0 deletions messaging/messaging_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,7 @@ var validMessages = []struct {
Sound: "s",
ThreadID: "t",
ContentAvailable: true,
MutableContent: true,
},
CustomData: map[string]interface{}{
"k1": "v1",
Expand All @@ -269,6 +270,7 @@ var validMessages = []struct {
"sound": "s",
"thread-id": "t",
"content-available": float64(1),
"mutable-content": float64(1),
},
"k1": "v1",
"k2": true,
Expand All @@ -288,6 +290,8 @@ var validMessages = []struct {
Sound: "s",
ThreadID: "t",
ContentAvailable: true,
MutableContent: true,
CustomData: map[string]interface{}{"k1": "v1", "k2": 1},
},
},
},
Expand All @@ -302,6 +306,9 @@ var validMessages = []struct {
"sound": "s",
"thread-id": "t",
"content-available": float64(1),
"mutable-content": float64(1),
"k1": "v1",
"k2": float64(1),
},
},
},
Expand Down Expand Up @@ -471,6 +478,21 @@ var invalidMessages = []struct {
},
want: "multiple alert specifications",
},
{
name: "APNSMultipleFieldSpecifications",
req: &Message{
APNS: &APNSConfig{
Payload: &APNSPayload{
Aps: &Aps{
Category: "category",
CustomData: map[string]interface{}{"category": "category"},
},
},
},
Topic: "topic",
},
want: `multiple specifications for the key "category"`,
},
{
name: "InvalidAPNSTitleLocArgs",
req: &Message{
Expand Down
6 changes: 6 additions & 0 deletions messaging/messaging_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,12 @@ func validateAps(aps *Aps) error {
if aps.Alert != nil && aps.AlertString != "" {
return fmt.Errorf("multiple alert specifications")
}
m := aps.standardFields()
for k := range aps.CustomData {
if _, contains := m[k]; contains {
return fmt.Errorf("multiple specifications for the key %q", k)
}
}
return validateApsAlert(aps.Alert)
}
return nil
Expand Down