100 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			100 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package mailgun
 | |
| 
 | |
| import (
 | |
| 	"fmt"
 | |
| 	"reflect"
 | |
| 	"time"
 | |
| 
 | |
| 	"github.com/mailgun/mailgun-go/v3/events"
 | |
| 	"github.com/mailru/easyjson"
 | |
| )
 | |
| 
 | |
| // All events returned by the EventIterator conform to this interface
 | |
| type Event interface {
 | |
| 	easyjson.Unmarshaler
 | |
| 	easyjson.Marshaler
 | |
| 	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 := easyjson.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 := easyjson.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.Name]
 | |
| 	if !ok {
 | |
| 		return nil, fmt.Errorf("unsupported event: '%s'", e.Name)
 | |
| 	}
 | |
| 	event := newEvent()
 | |
| 
 | |
| 	// Parse the known event.
 | |
| 	if err := easyjson.Unmarshal(raw, event); err != nil {
 | |
| 		return nil, fmt.Errorf("failed to parse event '%s': %v", e.Name, err)
 | |
| 	}
 | |
| 
 | |
| 	return event, nil
 | |
| }
 |