-
Notifications
You must be signed in to change notification settings - Fork 0
/
postmark.go
129 lines (113 loc) · 2.81 KB
/
postmark.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
package postmark
import (
"bufio"
"bytes"
"encoding/base64"
"io"
"mime"
"net/mail"
"os"
"path/filepath"
"strings"
"time"
)
// Message is an email message
type Message struct {
Subject string
HTMLBody string
TextBody string
To []*mail.Address
Attachments []*Attachment
}
// AddAttachment is a helper to add a file attachment to an email
func (m *Message) AddAttachment(name string, filename string) error {
a := &Attachment{}
a.Name = name
f, err := os.Open(filename)
if err != nil {
return err
}
a.File = f
m.Attachments = append(m.Attachments, a)
return nil
}
// NewMessage creates a new mail message
func NewMessage() *Message {
return &Message{}
}
// AddTo adds a new recipient to the message
func (m *Message) AddTo(address string) error {
addr, err := mail.ParseAddress(address)
if err != nil {
return err
}
m.To = append(m.To, addr)
return nil
}
// Attachment is a Message attachnment backed by a file
type Attachment struct {
Name string
File *os.File
}
func joinAddresses(addrs []*mail.Address) string {
var astr []string
for _, a := range addrs {
astr = append(astr, a.String())
}
return strings.Join(astr, ",")
}
func newPostmarkMessage(m *Message) (*postmarkMessage, error) {
pm := &postmarkMessage{}
pm.Subject = m.Subject
pm.To = joinAddresses(m.To)
pm.HTMLBody = m.HTMLBody
pm.TextBody = m.TextBody
for _, a := range m.Attachments {
pm.addAttachment(a)
}
return pm, nil
}
type postmarkMessage struct {
From string `json:",omitempty"`
To string `json:",omitempty"`
Cc string `json:",omitempty"`
Bcc string `json:",omitempty"`
Subject string `json:",omitempty"`
HTMLBody string `json:",omitempty"`
TextBody string `json:",omitempty"`
ReplyTo string `json:",omitempty"`
TrackOpens bool `json:",omitempty"`
Attachments []*postmarkAttachment `json:",omitempty"`
}
func (p *postmarkMessage) addAttachment(a *Attachment) (bool, error) {
pa := &postmarkAttachment{}
pa.Name = a.Name
st, err := a.File.Stat()
if err != nil {
return false, err
}
pa.ContentType = mime.TypeByExtension(filepath.Ext(st.Name()))
buf := &bytes.Buffer{}
enc := base64.NewEncoder(base64.StdEncoding, buf)
defer enc.Close()
b := bufio.NewReader(a.File)
if _, err = io.Copy(enc, b); err != nil {
return false, err
}
pa.Content = buf.String()
p.Attachments = append(p.Attachments, pa)
return true, nil
}
type postmarkAttachment struct {
Name string
Content string
ContentType string
}
// Response is recieved by postmark when an email is submitted for sending
type Response struct {
To string
SubmittedAt time.Time
MessageID string
ErrorCode int
Message string
}