-
Notifications
You must be signed in to change notification settings - Fork 0
/
mailgun.go
155 lines (147 loc) · 4.35 KB
/
mailgun.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
package worker
import(
"net/http"
"net/url"
"strings"
// "rabbit"
"helpers"
"fmt"
"time"
"errors"
"config"
"encoding/json"
"io/ioutil"
"github.com/streadway/amqp"
)
var MailGunClient *http.Client
func InitMg(){
transport := &http.Transport{
MaxIdleConns: 200,
IdleConnTimeout: 60 * time.Second,
DisableCompression: false,
}
MailGunClient = &http.Client{Transport: transport}
}
func MGListener(packet amqp.Delivery){
// the channel and routing keys are for failures
// in which the request would be forwarded to another provider
// as you pass it here
fmt.Println("Mailgun recieved a packet", packet.RoutingKey, string(packet.Body))
parts := strings.Split(packet.RoutingKey, ".")
if parts[0] == "log" {
ProcessLog(packet, "mailgun", GetMgEmailVars, SendMgRequest)
} else {
ProcessMail(packet, "mailgun", GetMgEmailVars, SendMgRequest)
}
}
/*
Sends the request
@return
StatusCode int
Nack Packet bool
Error error
*/
func SendMgRequest(body *string) (int, bool, error) {
request, err := getMGRequestObject(body)
if err != nil {
// negative ack packet and requeue it
return -1, true, err
}
response, err := MailGunClient.Do(request)
if err != nil {
// todo: log error
fmt.Println(err)
// negative acknowledge packet and requeue the packet
return -1, true, err
}
fmt.Println(response.StatusCode)
data , _ := ioutil.ReadAll(response.Body)
fmt.Println(string(data))
return response.StatusCode, false, nil
}
/*
Returns a http.Request object for POST endpoint of Sendgrid
*/
func getMGRequestObject(data *string) (*http.Request, error) {
var url = config.Configuration.MailGun.Endpoint + "/" + config.Configuration.MailGun.Domain + "/messages"
request, err := http.NewRequest("POST", url, strings.NewReader(*data))
if err != nil {
// todo: log error
return nil, err
}
request.SetBasicAuth("api", config.Configuration.MailGun.Key)
request.Header.Add("Content-Type", "application/x-www-form-urlencoded")
return request, nil
}
/*
Creates a JSON body out of options passed to it
*/
func GetMgEmailVars(options map[string]string, custom_args map[string]string) (string, error) {
requestBody := url.Values{}
var toArray []string
// var ccArray []string
var isBulk = false
if options["isBulk"] == "true" {
isBulk = true
}
if options["to"] != "" && len(options["to"]) < 5 {
// cannot process entity, push error
return "", errors.New("Not a valid recievers list")
}
// split string
toArray = strings.Split(options["to"], ",")
// get the rc variable string
var rcVariableString = getMgRecipientVariables(toArray, isBulk, custom_args)
// from option
var from = options["name"] + "<" + options["from"] + ">"
requestBody.Add("from", from)
// add all the recipients
for _, email := range toArray {
to := "<" + email + ">"
requestBody.Add("to", to)
}
requestBody.Add("subject", options["subject"])
requestBody.Add("html", options["content"])
requestBody.Add("h:Reply-To", from)
if isBulk == true {
requestBody.Add("recipient-variables", rcVariableString)
}
// Add custom variables at the global level too
for key, value := range custom_args {
// convert underscore to hyphens
key = strings.Replace(key, "_", "-", -1)
requestBody.Add("v:" + key, value)
}
// Encode the request params
return requestBody.Encode(), nil
}
/*
Returns a Mailgun Recipient Variables Map array for email send request
@params:
toArray: An array of recipients
isBulk: If the request was for bulk email
custom_args: A list of custom args used for tracking in webhooks
@return:
The format of recipient-variables map is:
{
"email": {...custom vars...}
}
*/
func getMgRecipientVariables(toArray []string, isBulk bool, custom_args map[string]string) (string) {
// indivdual emails doesn't need rc-variables
if isBulk == false {
return ""
}
var rcVariables map[string]interface{} = make(map[string]interface{})
// loop over all the recipients
for _, email := range toArray {
// strip all the space characters from email
email = strings.Replace(email, " ", "", -1)
// check if it is a valid email
if helpers.IsEmail(email) == true {
rcVariables[email] = custom_args
} // if valid email
} // for loop
str, _ := json.Marshal(rcVariables)
return string(str)
}