-
Notifications
You must be signed in to change notification settings - Fork 143
/
parse.go
97 lines (85 loc) · 2.76 KB
/
parse.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
package mailgun
import (
"fmt"
"reflect"
"time"
jsoniter "github.com/json-iterator/go"
"github.com/mailgun/mailgun-go/v4/events"
)
// All events returned by the EventIterator conform to this interface
type Event interface {
GetName() string
SetName(name string)
GetTimestamp() time.Time
SetTimestamp(time.Time)
GetID() string
SetID(id string)
}
// A list of all JSON event types returned by the /events API
var EventNames = map[string]func() Event{
"accepted": new_(events.Accepted{}),
"clicked": new_(events.Clicked{}),
"complained": new_(events.Complained{}),
"delivered": new_(events.Delivered{}),
"failed": new_(events.Failed{}),
"opened": new_(events.Opened{}),
"rejected": new_(events.Rejected{}),
"stored": new_(events.Stored{}),
"unsubscribed": new_(events.Unsubscribed{}),
"list_member_uploaded": new_(events.ListMemberUploaded{}),
"list_member_upload_error": new_(events.ListMemberUploadError{}),
"list_uploaded": new_(events.ListUploaded{}),
}
// new_ is a universal event "constructor".
func new_(e interface{}) func() Event {
typ := reflect.TypeOf(e)
return func() Event {
return reflect.New(typ).Interface().(Event)
}
}
func parseResponse(raw []byte) ([]Event, error) {
var resp events.Response
if err := jsoniter.Unmarshal(raw, &resp); err != nil {
return nil, fmt.Errorf("failed to un-marshall event.Response: %s", err)
}
var result []Event
for _, value := range resp.Items {
event, err := ParseEvent(value)
if err != nil {
return nil, fmt.Errorf("while parsing event: %s", err)
}
result = append(result, event)
}
return result, nil
}
// Given a slice of events.RawJSON events return a slice of Event for each parsed event
func ParseEvents(raw []events.RawJSON) ([]Event, error) {
var result []Event
for _, value := range raw {
event, err := ParseEvent(value)
if err != nil {
return nil, fmt.Errorf("while parsing event: %s", err)
}
result = append(result, event)
}
return result, nil
}
// Parse converts raw bytes data into an event struct. Can accept events.RawJSON as input
func ParseEvent(raw []byte) (Event, error) {
// Try to recognize the event first.
var e events.EventName
if err := jsoniter.Unmarshal(raw, &e); err != nil {
return nil, fmt.Errorf("failed to recognize event: %v", err)
}
// Get the event "constructor" from the map.
newEvent, ok := EventNames[e.GetName()]
if !ok {
return nil, fmt.Errorf("unsupported event: '%s'", e.GetName())
}
event := newEvent()
// Parse the known event.
if err := jsoniter.Unmarshal(raw, event); err != nil {
return nil, fmt.Errorf("failed to parse event '%s': %v", e.GetName(), err)
}
return event, nil
}