Skip to content

Commit

Permalink
Merge pull request #47 from morus12/suppresions-api
Browse files Browse the repository at this point in the history
suppressions create and delete APIs
  • Loading branch information
mrz1836 authored Feb 7, 2024
2 parents 0eca06c + e871e5c commit 30a7426
Show file tree
Hide file tree
Showing 2 changed files with 136 additions and 2 deletions.
65 changes: 64 additions & 1 deletion suppressions.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ type SuppressionReasonType string
// OriginType - The reason type of origin
type OriginType string

// SuppressionUpdateStatus - The status of suppression update
type SuppressionUpdateStatus string

const (
// HardBounceReason means an email sent to the address returned a hard bounce.
HardBounceReason SuppressionReasonType = "HardBounce"
Expand All @@ -36,6 +39,15 @@ const (
// AdminOrigin means the email was added to the suppression list as
// the result of action by Postmark staff.
AdminOrigin OriginType = "Admin"

// SuppressionUpdateStatusSuppressed means the server successfully suppressed the email address.
SuppressionUpdateStatusSuppressed SuppressionUpdateStatus = "Suppressed"

// SuppressionUpdateStatusDeleted means the server successfully deleted the suppression.
SuppressionUpdateStatusDeleted SuppressionUpdateStatus = "Deleted"

// SuppressionUpdateStatusFailed means the server failed to update the suppression.
SuppressionUpdateStatusFailed SuppressionUpdateStatus = "Failed"
)

// Suppression contains a suppressed email address for a particular message stream.
Expand All @@ -55,12 +67,31 @@ type Suppression struct {
CreatedAt time.Time
}

// SuppressionResponse contains a status of suppression creation or deletion.
type SuppressionResponse struct {
// EmailAddress is the address that is suppressed (can't be emailed any more)
EmailAddress string

// Status of suppression creation or deletion.
Status SuppressionUpdateStatus

// If address cannot be suppressed or deleted (Status: Failed), the cause for failure is listed.
// Otherwise, this field is null.
Message string
}

// suppressionsResponse - A message received from the Postmark server
type suppressionsResponse struct {
// Suppressions - The slice of suppression email address.
Suppressions []Suppression
}

// updateSuppressionsResponse
type updateSuppressionsResponse struct {
// Suppressions - The slice of suppression email address.
Suppressions []SuppressionResponse
}

// GetSuppressions fetches email addresses in the list of suppression dump on the server
// It returns a Suppressions slice, and any error that occurred
// https://postmarkapp.com/developer/api/suppressions-api#suppression-dump
Expand All @@ -69,7 +100,6 @@ func (client *Client) GetSuppressions(
streamID string,
options map[string]interface{},
) ([]Suppression, error) {

values := &url.Values{}
for k, v := range options {
values.Add(k, fmt.Sprintf("%v", v))
Expand All @@ -88,3 +118,36 @@ func (client *Client) GetSuppressions(
}, &res)
return res.Suppressions, err
}

// CreateSuppressions creates email addresses in the suppression list on the server.
func (client *Client) CreateSuppressions(
ctx context.Context,
streamID string,
suppressions []Suppression,
) ([]SuppressionResponse, error) {
res := updateSuppressionsResponse{}
err := client.doRequest(ctx, parameters{
Method: http.MethodPost,
Path: fmt.Sprintf("message-streams/%s/suppressions", streamID),
Payload: suppressions,
TokenType: serverToken,
}, &res)
return res.Suppressions, err
}

// DeleteSuppressions deletes email addresses from the suppression list on the server.
// SpamComplaint suppressions cannot be deleted.
func (client *Client) DeleteSuppressions(
ctx context.Context,
streamID string,
suppressions []Suppression,
) ([]SuppressionResponse, error) {
res := updateSuppressionsResponse{}
err := client.doRequest(ctx, parameters{
Method: http.MethodPost,
Path: fmt.Sprintf("message-streams/%s/suppressions/delete", streamID),
Payload: suppressions,
TokenType: serverToken,
}, &res)
return res.Suppressions, err
}
73 changes: 72 additions & 1 deletion suppressions_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ func TestGetSuppressions(t *testing.T) {
})

res, err := client.GetSuppressions(context.Background(), "outbound", nil)

if err != nil {
t.Fatalf("GetSuppressions: %s", err.Error())
}
Expand Down Expand Up @@ -84,3 +83,75 @@ func TestGetSuppressions(t *testing.T) {
t.Fatalf("GetSuppressions: wrong suppression email address: %s", res[0].EmailAddress)
}
}

func TestCreateSuppressions(t *testing.T) {
responseJSON := `{
"Suppressions":[
{
"EmailAddress":"good.address@wildbit.com",
"Status":"Suppressed",
"Message": null
},
{
"EmailAddress":"spammy.address@wildbit.com",
"Status":"Failed",
"Message": "You do not have the required authority to change this suppression."
},
{
"EmailAddress":"invalid-email-address",
"Status":"Failed",
"Message": "An invalid email address was provided."
}
]
}`

tMux.HandleFunc(pat.Post("/message-streams/:StreamID/suppressions"), func(w http.ResponseWriter, req *http.Request) {
_, _ = w.Write([]byte(responseJSON))
})

res, err := client.CreateSuppressions(context.Background(), "outbound", []Suppression{})
if err != nil {
t.Fatalf(err.Error())
}

if len(res) != 3 {
t.Fatalf("CreateSuppressions: wrong number of suppression (%d)", len(res))
}

if res[0].EmailAddress != "good.address@wildbit.com" {
t.Fatalf("CreateSuppressions: wrong suppression email address: %s", res[0].EmailAddress)
}
}

func TestDeleteSuppressions(t *testing.T) {
responseJSON := `{
"Suppressions":[
{
"EmailAddress":"good.address@wildbit.com"
},
{
"EmailAddress":"not.suppressed@wildbit.com"
},
{
"EmailAddress":"spammy.address@wildbit.com"
}
]
}`

tMux.HandleFunc(pat.Post("/message-streams/:StreamID/suppressions/delete"), func(w http.ResponseWriter, req *http.Request) {
_, _ = w.Write([]byte(responseJSON))
})

res, err := client.DeleteSuppressions(context.Background(), "outbound", []Suppression{})
if err != nil {
t.Fatalf(err.Error())
}

if len(res) != 3 {
t.Fatalf("CreateSuppressions: wrong number of suppression (%d)", len(res))
}

if res[0].EmailAddress != "good.address@wildbit.com" {
t.Fatalf("CreateSuppressions: wrong suppression email address: %s", res[0].EmailAddress)
}
}

0 comments on commit 30a7426

Please sign in to comment.