Bläddra i källkod

Email package

Signed-off-by: Vishal Rana <vr@labstack.com>
Vishal Rana 9 år sedan
förälder
incheckning
4463cfa216
2 ändrade filer med 120 tillägg och 0 borttagningar
  1. 119 0
      email/email.go
  2. 1 0
      email/email_test.go

+ 119 - 0
email/email.go

@@ -0,0 +1,119 @@
+package email
+
+import (
+	"bytes"
+	"fmt"
+	"net/mail"
+	"net/smtp"
+
+	"github.com/labstack/gommon/random"
+)
+
+type (
+	Email struct {
+		Auth        smtp.Auth
+		smtpAddress string
+		// TextTemplates text.Template
+	}
+
+	Message struct {
+		From        string
+		To          string
+		CC          string
+		Subject     string
+		Text        string
+		HTML        string
+		Inlines     []*File
+		Attachments []*File
+		buffer      *bytes.Buffer
+		boundary    string
+	}
+
+	File struct {
+		Name    string `json:"name"`
+		Type    string `json:"type"`
+		Content string `json:"content"`
+	}
+)
+
+func New(smtpAddress string) *Email {
+	return &Email{
+		smtpAddress: smtpAddress,
+	}
+}
+
+func (m *Message) writeText(content string, contentType string) {
+	m.buffer.WriteString(fmt.Sprintf("--%s\r\n", m.boundary))
+	m.buffer.WriteString(fmt.Sprintf("Content-Type: %s; charset=UTF-8\r\n", contentType))
+	m.buffer.WriteString("Content-Transfer-Encoding: quoted-printable\r\n")
+	m.buffer.WriteString("\r\n")
+	m.buffer.WriteString(content + "\r\n")
+}
+
+func (m *Message) writeFile(f *File, disposition string) {
+	m.buffer.WriteString(fmt.Sprintf("--%s\r\n", m.boundary))
+	m.buffer.WriteString(fmt.Sprintf("Content-Type: %s; name=%s\r\n", f.Type, f.Name))
+	m.buffer.WriteString(fmt.Sprintf("Content-Disposition: %s; filename=%s\r\n", disposition, f.Name))
+	m.buffer.WriteString("Content-Transfer-Encoding: base64\r\n")
+	m.buffer.WriteString("\r\n")
+	m.buffer.WriteString(f.Content + "\r\n")
+}
+
+func (e *Email) Send(m *Message) error {
+	// Construct message
+	m.buffer = new(bytes.Buffer)
+	m.boundary = random.String(16)
+	m.buffer.WriteString("MIME-Version: 1.0\r\n")
+	m.buffer.WriteString(fmt.Sprintf("From: %s\r\n", m.From))
+	m.buffer.WriteString(fmt.Sprintf("To: %s\r\n", m.To))
+	m.buffer.WriteString(fmt.Sprintf("CC: %s\r\n", m.CC))
+	m.buffer.WriteString(fmt.Sprintf("Subject: %s\r\n", m.Subject))
+	m.buffer.WriteString(fmt.Sprintf("Content-Type: multipart/mixed; boundary=%s\r\n", m.boundary))
+	m.buffer.WriteString("\r\n")
+	m.writeText(m.Text, "text/plain")
+	m.writeText(m.HTML, "text/html")
+	for _, f := range m.Inlines {
+		m.writeFile(f, "inline")
+	}
+	for _, f := range m.Attachments {
+		m.writeFile(f, "disposition")
+	}
+	m.buffer.WriteString("\r\n")
+	m.buffer.WriteString("--" + m.boundary + "--")
+
+	// Send message
+	c, err := smtp.Dial(e.smtpAddress)
+	if e.Auth != nil {
+		// Authenticate
+		if err := c.Auth(e.Auth); err != nil {
+			return err
+		}
+	}
+	if err != nil {
+		return err
+	}
+	defer c.Close()
+	from, err := mail.ParseAddress(m.From)
+	if err != nil {
+		return err
+	}
+	if err = c.Mail(from.Address); err != nil {
+		return err
+	}
+	to, err := mail.ParseAddressList(m.To)
+	if err != nil {
+		return err
+	}
+	for _, a := range to {
+		if err = c.Rcpt(a.Address); err != nil {
+			return err
+		}
+	}
+	wc, err := c.Data()
+	if err != nil {
+		return err
+	}
+	defer wc.Close()
+	_, err = m.buffer.WriteTo(wc)
+	return err
+}

+ 1 - 0
email/email_test.go

@@ -0,0 +1 @@
+package email