Repository: mailgun/mailgun-go
Pull request #248 (2021-02-21 02:58:29)

Update to suppport htmlonly option of trackingClicks
## Overview

This PR is for supporting `htmlonly` option of `o:tracking-clicks`.

According to [Messages Sending API](https://documentation.mailgun.com/en/latest/api-sending.html#sending)  `o:tracking-clicks` has 5 options `yes`, `no`, `true`, `false` or `htmlonly`.  But currently the type of `trackingClicks` is `bool` so we can't set `htmlonly` as an option. 

## Test

It worked fine as below email screenshot. (This PR passes option correctly)

### with htmlonly option

* text mail
    <img width="400" src=https://user-images.githubusercontent.com/3014624/108473723-c09a4880-72d1-11eb-8aaf-05688e839530.png />
* HTML mail (tracking link)
    <img width="400" src=https://user-images.githubusercontent.com/3014624/108473751-ca23b080-72d1-11eb-85a0-8ebb790b14fc.png />

### with yes option

* text mail (tracking link)
    <img width="400" src=https://user-images.githubusercontent.com/3014624/108473850-ea536f80-72d1-11eb-8104-304982d0932a.png />




Patch:
diff --git a/messages.go b/messages.go
index 9c92884..6850a20 100644
--- a/messages.go
+++ b/messages.go
@@ -33,7 +33,7 @@ type Message struct {
 	nativeSend         bool
 	testMode           bool
 	tracking           bool
-	trackingClicks     bool
+	trackingClicks     string
 	trackingOpens      bool
 	headers            map[string]string
 	variables          map[string]string
@@ -133,6 +133,13 @@ type sendMessageResponse struct {
 	Id      string `json:"id"`
 }
 
+// TrackingOptions contains fields relevant to trackings.
+type TrackingOptions struct {
+	Tracking       bool
+	TrackingClicks string
+	TrackingOpens  bool
+}
+
 // features abstracts the common characteristics between regular and MIME messages.
 // addCC, addBCC, recipientCount, setHtml and setAMPHtml are invoked via the package-global AddCC, AddBCC,
 // RecipientCount, SetHtml and SetAMPHtml calls, as these functions are ignored for MIME messages.
@@ -420,10 +427,22 @@ func (m *Message) SetTracking(tracking bool) {
 
 // SetTrackingClicks information is found in the Mailgun documentation.
 func (m *Message) SetTrackingClicks(trackingClicks bool) {
-	m.trackingClicks = trackingClicks
+	m.trackingClicks = yesNo(trackingClicks)
 	m.trackingClicksSet = true
 }
 
+// SetTrackingOptions sets the o:tracking, o:tracking-clicks and o:tracking-opens at once.
+func (m *Message) SetTrackingOptions(options *TrackingOptions) {
+	m.tracking = options.Tracking
+	m.trackingSet = true
+
+	m.trackingClicks = options.TrackingClicks
+	m.trackingClicksSet = true
+
+	m.trackingOpens = options.TrackingOpens
+	m.trackingOpensSet = true
+}
+
 // SetRequireTLS information is found in the Mailgun documentation.
 func (m *Message) SetRequireTLS(b bool) {
 	m.requireTLS = b
@@ -552,7 +571,7 @@ func (mg *MailgunImpl) Send(ctx context.Context, message *Message) (mes string,
 		payload.addValue("o:tracking", yesNo(message.tracking))
 	}
 	if message.trackingClicksSet {
-		payload.addValue("o:tracking-clicks", yesNo(message.trackingClicks))
+		payload.addValue("o:tracking-clicks", message.trackingClicks)
 	}
 	if message.trackingOpensSet {
 		payload.addValue("o:tracking-opens", yesNo(message.trackingOpens))


Test patch:
diff --git a/messages_test.go b/messages_test.go
index b5c50fd..ef2137b 100644
--- a/messages_test.go
+++ b/messages_test.go
@@ -17,7 +17,7 @@ import (
 const (
 	fromUser       = "=?utf-8?q?Katie_Brewer=2C_CFP=C2=AE?= <joe@example.com>"
 	exampleSubject = "Mailgun-go Example Subject"
-	exampleText    = "Testing some Mailgun awesomeness!"
+	exampleText    = "Testing some Mailgun awesomeness!\nhttps://www.mailgun.com/"
 	exampleHtml    = "<html><head /><body><p>Testing some <a href=\"http://google.com?q=abc&r=def&s=ghi\">Mailgun HTML awesomeness!</a> at www.kc5tja@yahoo.com</p></body></html>"
 	exampleAMPHtml = `<!doctype html><html ⚡4email><head><meta charset="utf-8"><script async src="https://cdn.ampproject.org/v0.js"></script><style amp4email-boilerplate>body{visibility:hidden}</style><style amp-custom>h1{margin: 1rem;}</style></head><body><h1>Hello, I am an AMP EMAIL!</h1></body></html>`
 	exampleMime    = `Content-Type: text/plain; charset="ascii"
@@ -148,6 +148,31 @@ func TestSendMGTracking(t *testing.T) {
 	})
 }
 
+func TestSendMGTrackingClicksHtmlOnly(t *testing.T) {
+	if reason := SkipNetworkTest(); reason != "" {
+		t.Skip(reason)
+	}
+
+	spendMoney(t, func() {
+		toUser := os.Getenv("MG_EMAIL_TO")
+		mg, err := NewMailgunFromEnv()
+		ensure.Nil(t, err)
+
+		ctx := context.Background()
+		m := mg.NewMessage(fromUser, exampleSubject, exampleText, toUser)
+		m.SetHtml(exampleHtml)
+		options := TrackingOptions{
+			Tracking:       true,
+			TrackingClicks: "htmlonly",
+			TrackingOpens:  true,
+		}
+		m.SetTrackingOptions(&options)
+		msg, id, err := mg.Send(ctx, m)
+		ensure.Nil(t, err)
+		t.Log("TestSendHtml:MSG(" + msg + "),ID(" + id + ")")
+	})
+}
+
 func TestSendMGTag(t *testing.T) {
 	if reason := SkipNetworkTest(); reason != "" {
 		t.Skip(reason)