You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

137 lines
2.9 KiB

package nwmail
import (
"bytes"
"encoding/hex"
"fmt"
"io"
"math/rand"
"strings"
"time"
)
const (
HTMLUTF8 = "text/html; charset=utf-8"
PlainTextUTF8 = "text/plain; charset=utf-8"
dateFmtRFC2822 = "Mon, 02 Jan 2006 15:04:05 -0700 (MST)"
)
type Mail struct {
sender string
recipients []string
headers map[string]string
body *bytes.Buffer
}
func NewMail(sender Address) *Mail {
m := &Mail{
sender: sender.Address,
headers: map[string]string{},
body: new(bytes.Buffer),
}
m.headers["Message-ID"] = m.generateMessageId()
m.headers["From"] = sender.String()
m.headers["MIME-Version"] = "1.0"
m.headers["Date"] = time.Now().Format(dateFmtRFC2822) //default, may be overridden
m.headers["Content-Type"] = PlainTextUTF8 //default, may be overridden
return m
}
func (m *Mail) AddRecipient(recipient Address) {
m.recipients = append(m.recipients, recipient.Address)
if len(m.headers["To"]) != 0 {
m.headers["To"] += ","
}
m.headers["To"] += recipient.String()
}
func (m *Mail) AddCC(recipient Address) {
m.recipients = append(m.recipients, recipient.Address)
if len(m.headers["Cc"]) != 0 {
m.headers["Cc"] += ","
}
m.headers["Cc"] += recipient.String()
}
func (m *Mail) AddBCC(recipient Address) {
m.recipients = append(m.recipients, recipient.Address)
if len(m.headers["Bcc"]) != 0 {
m.headers["Bcc"] += ","
}
m.headers["Bcc"] += recipient.String()
}
func (m *Mail) SetDate(dateTime time.Time) {
m.headers["Date"] = dateTime.Format(dateFmtRFC2822)
}
func (m *Mail) SetSubject(subject string) {
m.headers["Subject"] = subject
}
func (m *Mail) SetContentType(contentType string) {
m.headers["Content-Type"] = contentType
}
func (m *Mail) SetPriority(priority Priority) {
m.headers["Priority"] = priority.String()
}
func (m *Mail) SetImportant() {
m.headers["Importance"] = "high"
}
func (m *Mail) SetSensitivity(sensitivity Sensitivity) {
m.headers["Sensitivity"] = sensitivity.String()
}
func (m *Mail) SetReplyTo(replyTo Address) {
m.headers["Reply-To"] = replyTo.String()
}
func (m *Mail) SetReadConfirmation(to Address) {
m.headers["Disposition-Notification-To"] = to.String()
}
func (m *Mail) SetReceivedConfirmation(to Address) {
m.headers["Return-Receipt-To"] = to.String()
}
func (m *Mail) Write(p []byte) (n int, err error) {
return m.body.Write(p)
}
func (m *Mail) WriteString(s string) (int, error) {
return m.body.WriteString(s)
}
func (m Mail) Buffer() *bytes.Buffer {
mailBuf := new(bytes.Buffer)
for key, value := range m.headers {
mailBuf.WriteString(fmt.Sprintf("%s: %s\n", key, value))
}
mailBuf.WriteString("\n")
io.Copy(mailBuf, m.body)
return mailBuf
}
func (m Mail) String() string {
return m.Buffer().String()
}
func (m Mail) generateMessageId() string {
uniqueId := make([]byte, 8)
rand.Seed(time.Now().UnixNano())
rand.Read(uniqueId)
host := m.sender[strings.Index(m.sender, "@")+1:]
return fmt.Sprintf("<%s@%s>", hex.EncodeToString(uniqueId), host)
}