Skip to content
This repository has been archived by the owner on Aug 21, 2024. It is now read-only.

Commit

Permalink
Merge pull request #5 from SirUela/master
Browse files Browse the repository at this point in the history
Added ability to see attachments
  • Loading branch information
paganotoni authored Sep 28, 2021
2 parents 03f9356 + 61884a4 commit ed8cc78
Show file tree
Hide file tree
Showing 7 changed files with 113 additions and 7 deletions.
68 changes: 61 additions & 7 deletions mailopen.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
package mailopen

import (
"bytes"
"errors"
"fmt"
"html"
"html/template"
"io/ioutil"
"mime"
"os"
"path"
"regexp"
Expand All @@ -28,6 +31,9 @@ const (
<p style="margin-bottom: 0;"><span style="font-weight: bold;">Cc:</span> %v </p>
<p style="margin-bottom: 0;"><span style="font-weight: bold;">Bcc:</span> %v </p>
<p style="margin-bottom: 0;"><span style="font-weight: bold;">Subject:</span> %v</p>
{{range .}}
<p style="margin-bottom: 0;"><span style="font-weight: bold;">Attachment-{{.Name}}:</span><a href="{{.Path}}" download="{{.Name}}">{{.Name}}</a></p>
{{end}}
</div>
`
plainHeaderTmpl = `
Expand All @@ -47,6 +53,11 @@ type FileSender struct {
TempDir string
}

type AttFile struct {
Path string
Name string
}

//Send sends an email to Sendgrid for delivery, it assumes
//bodies[0] is HTML body and bodies[1] is text.
func (ps FileSender) Send(m mail.Message) error {
Expand All @@ -55,13 +66,13 @@ func (ps FileSender) Send(m mail.Message) error {
}

htmlContent := ps.addHTMLHeader(m.Bodies[0].Content, m)
htmlPath, err := ps.saveEmailBody(htmlContent, m.Subject, "html")
htmlPath, err := ps.saveEmailBody(htmlContent, "html", m)
if err != nil {
return err
}

plainContent := ps.addPlainHeader(fmt.Sprintf("<html><head></head><body><pre>%v</pre></body></html>", m.Bodies[1].Content), m)
plainPath, err := ps.saveEmailBody(plainContent, m.Subject, "txt")
plainPath, err := ps.saveEmailBody(plainContent, "txt", m)

if err != nil {
return err
Expand Down Expand Up @@ -94,22 +105,65 @@ func (ps FileSender) addPlainHeader(content string, m mail.Message) string {
return re.ReplaceAllString(content, fmt.Sprintf(`$1%v$2$3`, header))
}

func (ps FileSender) saveEmailBody(content, subject, ctype string) (string, error) {
func (ps FileSender) saveEmailBody(content, ctype string, m mail.Message) (string, error) {
id, err := uuid.NewV4()
if err != nil {
return "", err
}

filePath := fmt.Sprintf("%s_%s_%s.html", flect.Underscore(subject), ctype, id)
if Testing {
filePath = fmt.Sprintf("%s_%s.html", flect.Underscore(subject), ctype)
afs, err := ps.saveAttachmentFiles(m.Attachments)
if err != nil {
return "", err
}

tmpl := template.Must(template.New("mail").Parse(content))

var tpl bytes.Buffer
err = tmpl.Execute(&tpl, afs)
if err != nil {
return "", err
}

filePath := fmt.Sprintf("%s_%s_%s.html", flect.Underscore(m.Subject), ctype, id)
if Testing {
filePath = fmt.Sprintf("%s_%s.html", flect.Underscore(m.Subject), ctype)
}
path := path.Join(ps.TempDir, filePath)
err = ioutil.WriteFile(path, []byte(content), 0644)
err = ioutil.WriteFile(path, tpl.Bytes(), 0644)

return path, err
}

func (ps FileSender) saveAttachmentFiles(Attachments []mail.Attachment) ([]AttFile, error) {
var afs []AttFile
var af AttFile
for _, a := range Attachments {
exts, err := mime.ExtensionsByType(a.ContentType)
if err != nil {
return nil, err
}

filePath := path.Join(ps.TempDir, fmt.Sprintf("%s_%s%s", uuid.Must(uuid.NewV4()), a.Name, exts[0]))

af.Path = filePath
af.Name = a.Name

b, err := ioutil.ReadAll(a.Reader)
if err != nil {
return nil, err
}

err = ioutil.WriteFile(filePath, b, 0777)
if err != nil {
return nil, err
}

afs = append(afs, af)
}

return afs, nil
}

// New creates a sender that writes emails into disk
func New() FileSender {
return FileSender{
Expand Down
42 changes: 42 additions & 0 deletions mailopen_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,13 @@ func init() {
mailopen.Testing = true
}

func openFile(name string, r *require.Assertions) *os.File {
f, err := os.Open(name)
r.NoError(err)

return f
}

//TODO: options open only
func Test_Send(t *testing.T) {
r := require.New(t)
Expand All @@ -34,6 +41,12 @@ func Test_Send(t *testing.T) {
{ContentType: "text/html", Content: "<html><head></head><body><div>Some Message</div></body></html>"},
{ContentType: "text/plain", Content: "Same message"},
}
m.Attachments = []mail.Attachment{
{Name: "csv_test", Reader: openFile("test_files/csv_sample.csv", r), ContentType: "text/csv", Embedded: false},
{Name: "img_test", Reader: openFile("test_files/img_sample.jpeg", r), ContentType: "image/jpeg", Embedded: false},
{Name: "pdf_test", Reader: openFile("test_files/pdf_sample.pdf", r), ContentType: "application/pdf", Embedded: false},
{Name: "zip_test", Reader: openFile("test_files/zip_sample.zip", r), ContentType: "application/zip", Embedded: false},
}

r.NoError(sender.Send(m))
htmlFile := path.Join(sender.TempDir, fmt.Sprintf("%s_%s.html", flect.Underscore(m.Subject), "html"))
Expand All @@ -51,6 +64,10 @@ func Test_Send(t *testing.T) {
r.Contains(string(dat), m.Bcc[0])
r.Contains(string(dat), m.Subject)

for _, a := range m.Attachments {
r.Contains(string(dat), a.Name)
}

dat, err = ioutil.ReadFile(txtFile)
r.NoError(err)

Expand Down Expand Up @@ -79,6 +96,31 @@ func Test_SendWithOneBody(t *testing.T) {
r.Error(sender.Send(m))
}

func Test_SendWithoutAttachments(t *testing.T) {
r := require.New(t)
sender := mailopen.New()
sender.Open = false

m := mail.NewMessage()
m.From = "testing@testing.com"
m.To = []string{"testing@other.com"}
m.CC = []string{"aa@other.com"}
m.Bcc = []string{"aax@other.com"}
m.Subject = "something"
m.Bodies = []mail.Body{
{ContentType: "text/html", Content: "<html><head></head><body><div>Some Message</div></body></html>"},
{ContentType: "text/plain", Content: "Same message"},
}

r.NoError(sender.Send(m))

htmlFile := path.Join(sender.TempDir, fmt.Sprintf("%s_%s.html", flect.Underscore(m.Subject), "html"))

dat, err := ioutil.ReadFile(htmlFile)
r.NoError(err)
r.NotContains(string(dat), "Attachment:")
}

func Test_Wrap(t *testing.T) {
r := require.New(t)

Expand Down
Binary file added test_files/.DS_Store
Binary file not shown.
10 changes: 10 additions & 0 deletions test_files/csv_sample.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
1,"Eldon Base for stackable storage shelf, platinum",Muhammed MacIntyre,3,-213.25,38.94,35,Nunavut,Storage & Organization,0.8
2,"1.7 Cubic Foot Compact ""Cube"" Office Refrigerators",Barry French,293,457.81,208.16,68.02,Nunavut,Appliances,0.58
3,"Cardinal Slant-D Ring Binder, Heavy Gauge Vinyl",Barry French,293,46.71,8.69,2.99,Nunavut,Binders and Binder Accessories,0.39
4,R380,Clay Rozendal,483,1198.97,195.99,3.99,Nunavut,Telephones and Communication,0.58
5,Holmes HEPA Air Purifier,Carlos Soltero,515,30.94,21.78,5.94,Nunavut,Appliances,0.5
6,G.E. Longer-Life Indoor Recessed Floodlight Bulbs,Carlos Soltero,515,4.43,6.64,4.95,Nunavut,Office Furnishings,0.37
7,"Angle-D Binders with Locking Rings, Label Holders",Carl Jackson,613,-54.04,7.3,7.72,Nunavut,Binders and Binder Accessories,0.38
8,"SAFCO Mobile Desk Side File, Wire Frame",Carl Jackson,613,127.70,42.76,6.22,Nunavut,Storage & Organization,
9,"SAFCO Commercial Wire Shelving, Black",Monica Federle,643,-695.26,138.14,35,Nunavut,Storage & Organization,
10,Xerox 198,Dorothy Badders,678,-226.36,4.98,8.33,Nunavut,Paper,0.38
Binary file added test_files/img_sample.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added test_files/pdf_sample.pdf
Binary file not shown.
Binary file added test_files/zip_sample.zip
Binary file not shown.

0 comments on commit ed8cc78

Please sign in to comment.