diff --git a/Readme.md b/Readme.md index b9c5c7b..633fa08 100644 --- a/Readme.md +++ b/Readme.md @@ -173,7 +173,7 @@ func main() { } ``` -### Create a subscriber +### Create/Upsert a subscriber ```go package main @@ -192,14 +192,14 @@ func main() { ctx := context.TODO() - subscriber := &mailerlite.Subscriber{ + subscriber := &mailerlite.UpsertSubscriber{ Email: "example@example.com", Fields: map[string]interface{}{ "city": "Vilnius", }, } - newSubscriber, _, err := client.Subscriber.Create(ctx, subscriber) + newSubscriber, _, err := client.Subscriber.Upsert(ctx, subscriber) if err != nil { log.Fatal(err) } @@ -227,14 +227,15 @@ func main() { ctx := context.TODO() - subscriber := &mailerlite.Subscriber{ + subscriber := &mailerlite.UpdateSubscriber{ + ID: "1", Email: "example@example.com", Fields: map[string]interface{}{ "company": "MailerLite", }, } - newSubscriber, _, err := client.Subscriber.Create(ctx, subscriber) + newSubscriber, _, err := client.Subscriber.Update(ctx, subscriber) if err != nil { log.Fatal(err) } diff --git a/subscribers.go b/subscribers.go index 95d5581..42c8082 100644 --- a/subscribers.go +++ b/subscribers.go @@ -13,8 +13,9 @@ type SubscriberService interface { List(ctx context.Context, options *ListSubscriberOptions) (*RootSubscribers, *Response, error) Count(ctx context.Context) (*Count, *Response, error) Get(ctx context.Context, options *GetSubscriberOptions) (*RootSubscriber, *Response, error) - Create(ctx context.Context, subscriber *SubscriberToCreate) (*RootSubscriber, *Response, error) - Update(ctx context.Context, subscriber *Subscriber) (*RootSubscriber, *Response, error) + Create(ctx context.Context, subscriber *Subscriber) (*RootSubscriber, *Response, error) + Upsert(ctx context.Context, subscriber *UpsertSubscriber) (*RootSubscriber, *Response, error) + Update(ctx context.Context, subscriber *UpdateSubscriber) (*RootSubscriber, *Response, error) Delete(ctx context.Context, subscriberID string) (*Response, error) Forget(ctx context.Context, subscriberID string) (*RootSubscriber, *Response, error) } @@ -61,7 +62,10 @@ type Subscriber struct { OptinIP string `json:"optin_ip,omitempty"` } -type SubscriberToCreate struct { +type UpdateSubscriber UpsertSubscriber + +type UpsertSubscriber struct { + ID string `json:"id,omitempty"` Email string `json:"email,omitempty"` Status string `json:"status,omitempty"` IPAddress interface{} `json:"ip_address,omitempty"` @@ -139,7 +143,8 @@ func (s *subscriberService) Get(ctx context.Context, options *GetSubscriberOptio return root, res, nil } -func (s *subscriberService) Create(ctx context.Context, subscriber *SubscriberToCreate) (*RootSubscriber, *Response, error) { +// Deprecated: use Upsert instead +func (s *subscriberService) Create(ctx context.Context, subscriber *Subscriber) (*RootSubscriber, *Response, error) { req, err := s.client.newRequest(http.MethodPost, subscriberEndpoint, subscriber) if err != nil { return nil, nil, err @@ -154,11 +159,22 @@ func (s *subscriberService) Create(ctx context.Context, subscriber *SubscriberTo return root, res, nil } -func (s *subscriberService) Upsert(ctx context.Context, subscriber *SubscriberToCreate) (*RootSubscriber, *Response, error) { - return s.Create(ctx, subscriber) +func (s *subscriberService) Upsert(ctx context.Context, subscriber *UpsertSubscriber) (*RootSubscriber, *Response, error) { + req, err := s.client.newRequest(http.MethodPost, subscriberEndpoint, subscriber) + if err != nil { + return nil, nil, err + } + + root := new(RootSubscriber) + res, err := s.client.do(ctx, req, root) + if err != nil { + return nil, res, err + } + + return root, res, nil } -func (s *subscriberService) Update(ctx context.Context, subscriber *Subscriber) (*RootSubscriber, *Response, error) { +func (s *subscriberService) Update(ctx context.Context, subscriber *UpdateSubscriber) (*RootSubscriber, *Response, error) { path := fmt.Sprintf("%s/%s", subscriberEndpoint, subscriber.ID) req, err := s.client.newRequest(http.MethodPut, path, subscriber) diff --git a/subscribers_test.go b/subscribers_test.go index 2b24600..740ec67 100644 --- a/subscribers_test.go +++ b/subscribers_test.go @@ -168,7 +168,7 @@ func TestCanForgetSubscrber(t *testing.T) { assert.Equal(t, res.StatusCode, http.StatusOK) } -func TestCanCreateSubscrberWithGroup(t *testing.T) { +func TestCanCreateSubscrberWithGroupDeprecated(t *testing.T) { client := mailerlite.NewClient(testKey) testClient := NewTestClient(func(req *http.Request) *http.Response { @@ -198,3 +198,66 @@ func TestCanCreateSubscrberWithGroup(t *testing.T) { assert.Equal(t, res.StatusCode, http.StatusOK) } + +func TestCanUpsertSubscrberWithGroup(t *testing.T) { + client := mailerlite.NewClient(testKey) + + testClient := NewTestClient(func(req *http.Request) *http.Response { + assert.Equal(t, req.Method, http.MethodPost) + assert.Equal(t, req.URL.String(), "https://connect.mailerlite.com/api/subscribers") + b, _ := io.ReadAll(req.Body) + assert.Equal(t, strings.TrimRight(string(b), "\r\n"), `{"email":"test@test.com","groups":["1234"]}`) + return &http.Response{ + StatusCode: http.StatusOK, + Body: io.NopCloser(bytes.NewBufferString(`OK`)), + } + }) + + ctx := context.TODO() + + client.SetHttpClient(testClient) + + options := &mailerlite.UpsertSubscriber{ + Email: "test@test.com", + Groups: []string{"1234"}, + } + + _, res, err := client.Subscriber.Upsert(ctx, options) + if err != nil { + return + } + + assert.Equal(t, res.StatusCode, http.StatusOK) +} + +func TestCanUpdateSubscrberWithGroup(t *testing.T) { + client := mailerlite.NewClient(testKey) + + testClient := NewTestClient(func(req *http.Request) *http.Response { + assert.Equal(t, req.Method, http.MethodPut) + assert.Equal(t, req.URL.String(), "https://connect.mailerlite.com/api/subscribers/1") + b, _ := io.ReadAll(req.Body) + assert.Equal(t, strings.TrimRight(string(b), "\r\n"), `{"id":"1","email":"test@test.com","groups":["1234"]}`) + return &http.Response{ + StatusCode: http.StatusOK, + Body: io.NopCloser(bytes.NewBufferString(`OK`)), + } + }) + + ctx := context.TODO() + + client.SetHttpClient(testClient) + + options := &mailerlite.UpdateSubscriber{ + ID: "1", + Email: "test@test.com", + Groups: []string{"1234"}, + } + + _, res, err := client.Subscriber.Update(ctx, options) + if err != nil { + return + } + + assert.Equal(t, res.StatusCode, http.StatusOK) +}