github.com/mailgun/mailgun-go/v3@v3.6.4/parse.go (about)

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