Repository: mailgun/mailgun-go
Pull request #302 (2023-04-13 10:40:51)

Allow setting preferred reply method to mailing lists
The Mailgun API offers the ability to set the preferred reply method to [mailing lists](https://documentation.mailgun.com/en/latest/api-mailinglists.html#mailing-lists), but this is [currently missing](https://pkg.go.dev/github.com/mailgun/mailgun-go#List) in the mailgun-go library.

This PR adds the missing parameter to the mailgun-go library. Specifically, the implementation is based on the existing `AccessLevel` parameter, that is, it adds a new field `ReplyPreference` to the `MailingList` struct, introduces a new `ReplyPreference` datatype, adds support for the parameter in `CreateMailingList` and `UpdateMailingList`, and includes the field in test and mocks.

teros0: LGTM

Patch:
diff --git a/mailing_lists.go b/mailing_lists.go
index e29e100..d461135 100644
--- a/mailing_lists.go
+++ b/mailing_lists.go
@@ -22,16 +22,28 @@ const (
 // Specify the access of a mailing list member
 type AccessLevel string
 
+// Replies to a mailing list should go to one of two preferred destinations.
+const (
+	// List specifies that replies should be sent to the mailing list address.
+	ReplyPreferenceList = "list"
+	// Sender specifies that replies should be sent to the sender (FROM) address.
+	ReplyPreferenceSender = "sender"
+)
+
+// Set where replies should go
+type ReplyPreference string
+
 // A List structure provides information for a mailing list.
 //
 // AccessLevel may be one of ReadOnly, Members, or Everyone.
 type MailingList struct {
-	Address      string      `json:"address,omitempty"`
-	Name         string      `json:"name,omitempty"`
-	Description  string      `json:"description,omitempty"`
-	AccessLevel  AccessLevel `json:"access_level,omitempty"`
-	CreatedAt    RFC2822Time `json:"created_at,omitempty"`
-	MembersCount int         `json:"members_count,omitempty"`
+	Address         string          `json:"address,omitempty"`
+	Name            string          `json:"name,omitempty"`
+	Description     string          `json:"description,omitempty"`
+	AccessLevel     AccessLevel     `json:"access_level,omitempty"`
+	ReplyPreference ReplyPreference `json:"reply_preference,omitempty"`
+	CreatedAt       RFC2822Time     `json:"created_at,omitempty"`
+	MembersCount    int             `json:"members_count,omitempty"`
 }
 
 type listsResponse struct {
@@ -161,9 +173,10 @@ func (li *ListsIterator) fetch(ctx context.Context, url string) error {
 
 // CreateMailingList creates a new mailing list under your Mailgun account.
 // You need specify only the Address and Name members of the prototype;
-// Description, and AccessLevel are optional.
+// Description, AccessLevel and ReplyPreference are optional.
 // If unspecified, Description remains blank,
-// while AccessLevel defaults to Everyone.
+// while AccessLevel defaults to Everyone
+// and ReplyPreference defaults to List.
 func (mg *MailgunImpl) CreateMailingList(ctx context.Context, prototype MailingList) (MailingList, error) {
 	r := newHTTPRequest(generatePublicApiUrl(mg, listsEndpoint))
 	r.setClient(mg.Client())
@@ -181,6 +194,9 @@ func (mg *MailgunImpl) CreateMailingList(ctx context.Context, prototype MailingL
 	if prototype.AccessLevel != "" {
 		p.addValue("access_level", string(prototype.AccessLevel))
 	}
+	if prototype.ReplyPreference != "" {
+		p.addValue("reply_preference", string(prototype.ReplyPreference))
+	}
 	response, err := makePostRequest(ctx, r, p)
 	if err != nil {
 		return MailingList{}, err
@@ -217,7 +233,7 @@ func (mg *MailgunImpl) GetMailingList(ctx context.Context, addr string) (Mailing
 }
 
 // UpdateMailingList allows you to change various attributes of a list.
-// Address, Name, Description, and AccessLevel are all optional;
+// Address, Name, Description, AccessLevel and ReplyPreference are all optional;
 // only those fields which are set in the prototype will change.
 //
 // Be careful!  If changing the address of a mailing list,
@@ -240,6 +256,9 @@ func (mg *MailgunImpl) UpdateMailingList(ctx context.Context, addr string, proto
 	if prototype.AccessLevel != "" {
 		p.addValue("access_level", string(prototype.AccessLevel))
 	}
+	if prototype.ReplyPreference != "" {
+		p.addValue("reply_preference", string(prototype.ReplyPreference))
+	}
 	var l MailingList
 	response, err := makePutRequest(ctx, r, p)
 	if err != nil {
diff --git a/mock_mailing_list.go b/mock_mailing_list.go
index ad23d3e..58ce34c 100644
--- a/mock_mailing_list.go
+++ b/mock_mailing_list.go
@@ -30,12 +30,13 @@ func (ms *mockServer) addMailingListRoutes(r *mux.Router) {
 
 	ms.mailingList = append(ms.mailingList, MailingListContainer{
 		MailingList: MailingList{
-			AccessLevel:  "everyone",
-			Address:      "foo@mailgun.test",
-			CreatedAt:    RFC2822Time(time.Now().UTC()),
-			Description:  "Mailgun developers list",
-			MembersCount: 1,
-			Name:         "",
+			ReplyPreference: "list",
+			AccessLevel:     "everyone",
+			Address:         "foo@mailgun.test",
+			CreatedAt:       RFC2822Time(time.Now().UTC()),
+			Description:     "Mailgun developers list",
+			MembersCount:    1,
+			Name:            "",
 		},
 		Members: []Member{
 			{
@@ -146,6 +147,9 @@ func (ms *mockServer) updateMailingList(w http.ResponseWriter, r *http.Request)
 			if r.FormValue("access_level") != "" {
 				ms.mailingList[i].MailingList.AccessLevel = AccessLevel(r.FormValue("access_level"))
 			}
+			if r.FormValue("reply_preference") != "" {
+				ms.mailingList[i].MailingList.ReplyPreference = ReplyPreference(r.FormValue("reply_preference"))
+			}
 			toJSON(w, okResp{Message: "Mailing list member has been updated"})
 			return
 		}
@@ -160,11 +164,12 @@ func (ms *mockServer) createMailingList(w http.ResponseWriter, r *http.Request)
 
 	ms.mailingList = append(ms.mailingList, MailingListContainer{
 		MailingList: MailingList{
-			CreatedAt:   RFC2822Time(time.Now().UTC()),
-			Name:        r.FormValue("name"),
-			Address:     r.FormValue("address"),
-			Description: r.FormValue("description"),
-			AccessLevel: AccessLevel(r.FormValue("access_level")),
+			CreatedAt:       RFC2822Time(time.Now().UTC()),
+			Name:            r.FormValue("name"),
+			Address:         r.FormValue("address"),
+			Description:     r.FormValue("description"),
+			AccessLevel:     AccessLevel(r.FormValue("access_level")),
+			ReplyPreference: ReplyPreference(r.FormValue("reply_preference")),
 		},
 	})
 	toJSON(w, okResp{Message: "Mailing list has been created"})


Test patch:
diff --git a/mailing_lists_test.go b/mailing_lists_test.go
index 81da250..0dd4dc4 100644
--- a/mailing_lists_test.go
+++ b/mailing_lists_test.go
@@ -100,10 +100,11 @@ func TestMailingLists(t *testing.T) {
 
 	address := randomEmail("list", testDomain)
 	protoList := mailgun.MailingList{
-		Address:     address,
-		Name:        "List1",
-		Description: "A list created by an acceptance test.",
-		AccessLevel: mailgun.AccessLevelMembers,
+		Address:         address,
+		Name:            "List1",
+		Description:     "A list created by an acceptance test.",
+		AccessLevel:     mailgun.AccessLevelMembers,
+		ReplyPreference: mailgun.ReplyPreferenceSender,
 	}
 
 	var countLists = func() int {