Skip to content

Commit fb5faaa

Browse files
author
Lars van Erp
committed
Initial commit
0 parents  commit fb5faaa

File tree

5 files changed

+239
-0
lines changed

5 files changed

+239
-0
lines changed

go.mod

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module github.com/cmdotcom/email-sdk-golang
2+
3+
go 1.25.4

pkg/emailgateway/README.md

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# CM Email Gateway API Golang package
2+
Official API docs: https://developers.cm.com/messaging/docs/email-introduction
3+
4+
## How to use the `emailgateway` package?
5+
### Installation
6+
```shell
7+
go get github.com/cmdotcom/email-sdk-golang/pkg/emailgateway
8+
```
9+
10+
### Initialize client
11+
```go
12+
package main
13+
14+
import "os"
15+
import (
16+
os
17+
emailgateway [TODO: Define repo]
18+
)
19+
20+
func main() {
21+
client, err := emailgateway.NewClient(emailgateway.Config{
22+
ProductToken: os.Getenv("CM_EMAIL_GATEWAY_PRODUCT_TOKEN"),
23+
})
24+
if err != nil {
25+
panic(err)
26+
}
27+
}
28+
```
29+
30+
### Sending an email
31+
```go
32+
33+
// Client initialization code
34+
35+
email := emailgateway.Email{
36+
From: emailgateway.Address{
37+
Name: "CM.com",
38+
Email: "no-reply@cm.com",
39+
},
40+
To: []emailgateway.Address{
41+
{
42+
Name: "Example Receiver",
43+
Email: "email@example.com",
44+
},
45+
},
46+
Subject: "My first emailgateway email",
47+
HTMLBody: "<h1> Hello world! </h1>",
48+
TextBody: "email",
49+
}
50+
51+
response, err := client.SendTransactionalEmail(email)
52+
if err != nil {
53+
// Handle error
54+
}
55+
```

pkg/emailgateway/emailgateway.go

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
package emailgateway
2+
3+
import (
4+
"bytes"
5+
"encoding/json"
6+
"errors"
7+
"net/http"
8+
"time"
9+
)
10+
11+
type priority string
12+
13+
const (
14+
PriorityLow priority = "LOW"
15+
PriorityHigh priority = "HIGH"
16+
17+
baseURL = "https://api.cm.com/email/gateway/v1"
18+
defaultHttpTimeout = 30 * time.Second
19+
defaultTransactionalPriority = PriorityHigh
20+
)
21+
22+
var (
23+
ErrUnableToSendEmail = errors.New("unable to send email")
24+
)
25+
26+
type Client struct {
27+
baseClient *http.Client
28+
productToken string
29+
transactionalPriority priority
30+
}
31+
32+
type Config struct {
33+
ProductToken string
34+
CustomHttpClient *http.Client
35+
DefaultTransactionalPriority priority
36+
}
37+
38+
func NewClient(config Config) (*Client, error) {
39+
var client Client
40+
41+
if config.ProductToken == "" {
42+
return nil, errors.New("config.ProductToken must be set")
43+
}
44+
client.productToken = config.ProductToken
45+
46+
client.baseClient = &http.Client{Timeout: defaultHttpTimeout}
47+
if config.CustomHttpClient != nil {
48+
client.baseClient = config.CustomHttpClient
49+
}
50+
51+
client.transactionalPriority = defaultTransactionalPriority
52+
if config.DefaultTransactionalPriority != "" {
53+
client.transactionalPriority = config.DefaultTransactionalPriority
54+
}
55+
56+
return &client, nil
57+
}
58+
59+
type SendEmailResponse struct {
60+
Status int `json:"status"`
61+
Message string `json:"message"`
62+
Success bool `json:"success"`
63+
MessageID string `json:"messageId"`
64+
}
65+
66+
func (c *Client) SendTransactionalEmail(email Email) (*SendEmailResponse, error) {
67+
emailPriority := c.transactionalPriority
68+
if email.Priority != "" {
69+
emailPriority = email.Priority
70+
}
71+
72+
mailBody, err := json.Marshal(email)
73+
if err != nil {
74+
return nil, err
75+
}
76+
77+
req, err := http.NewRequest(http.MethodPost, baseURL+"/transactional?priority="+string(emailPriority), bytes.NewBuffer(mailBody))
78+
if err != nil {
79+
return nil, err
80+
}
81+
82+
req.Header.Set("Content-Type", "application/json")
83+
req.Header.Set("X-CM-PRODUCTTOKEN", c.productToken)
84+
85+
resp, err := c.baseClient.Do(req)
86+
if err != nil {
87+
return nil, err
88+
}
89+
defer resp.Body.Close()
90+
91+
var response SendEmailResponse
92+
_ = json.NewDecoder(resp.Body).Decode(&response)
93+
94+
if resp.StatusCode != http.StatusAccepted {
95+
return &response, ErrUnableToSendEmail
96+
}
97+
98+
return &response, nil
99+
}
100+
101+
func (c *Client) SendMarketingEmail(email Email) (*SendEmailResponse, error) {
102+
mailBody, err := json.Marshal(email)
103+
if err != nil {
104+
return nil, err
105+
}
106+
107+
req, err := http.NewRequest(http.MethodPost, baseURL+"/transactional", bytes.NewBuffer(mailBody))
108+
if err != nil {
109+
return nil, err
110+
}
111+
112+
req.Header.Set("Content-Type", "application/json")
113+
req.Header.Set("X-CM-PRODUCTTOKEN", c.productToken)
114+
115+
resp, err := c.baseClient.Do(req)
116+
if err != nil {
117+
return nil, err
118+
}
119+
defer resp.Body.Close()
120+
121+
var response SendEmailResponse
122+
_ = json.NewDecoder(resp.Body).Decode(&response)
123+
124+
if resp.StatusCode != http.StatusAccepted {
125+
return &response, ErrUnableToSendEmail
126+
}
127+
128+
return &response, nil
129+
}

pkg/emailgateway/mail.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package emailgateway
2+
3+
type ContentType string
4+
5+
const (
6+
ContentTypePNG ContentType = "image/png"
7+
ContentTypeJPG ContentType = "image/jpg"
8+
ContentTypeJPEG ContentType = "image/jpeg"
9+
ContentTypePDF ContentType = "application/pdf"
10+
ContentTypeDoc ContentType = "application/doc"
11+
ContentTypeDocx ContentType = "application/docx"
12+
ContentTypeText ContentType = "application/zip"
13+
)
14+
15+
type Address struct {
16+
Email string `json:"email"`
17+
Name string `json:"name"`
18+
}
19+
20+
type Attachment struct {
21+
Filename string `json:"fileName"`
22+
// Content is the base64 encoded content of the attachment
23+
Content string `json:"content"`
24+
ContentType ContentType `json:"contentType"`
25+
ContentID string `json:"contentId"`
26+
}
27+
28+
type Email struct {
29+
From Address `json:"from"`
30+
ReplyTo *Address `json:"replyTo,omitempty"`
31+
To []Address `json:"to"`
32+
Cc []Address `json:"cc,omitempty"`
33+
Bcc []Address `json:"bcc,omitempty"`
34+
Subject string `json:"subject"`
35+
HTMLBody string `json:"html"`
36+
TextBody string `json:"text"`
37+
Attachments []Attachment `json:"attachments,omitempty"`
38+
CustomerReference string `json:"customerReference,omitempty"`
39+
Priority priority `json:"-"`
40+
}

pkg/emailgateway/webhook.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package emailgateway
2+
3+
type WebhookEvent string
4+
5+
const (
6+
WebhookEventDelivered WebhookEvent = "Delivered"
7+
WebhookEventOpened WebhookEvent = "Opened"
8+
WebhookEventClicked WebhookEvent = "Clicked"
9+
WebhookEventBounced WebhookEvent = "Bounced"
10+
WebhookEventUnsubscribed WebhookEvent = "Unsubscribed"
11+
WebhookEventComplained WebhookEvent = "Complained"
12+
)

0 commit comments

Comments
 (0)