all repos — navani @ master

forlater's primary mail processing service

mail/send.go (view raw)

  1package mail
  2
  3import (
  4	"fmt"
  5	"io"
  6	"log"
  7	"mime"
  8	"os"
  9
 10	"git.icyphox.sh/forlater/navani/reader"
 11	"git.icyphox.sh/rel2abs"
 12	"github.com/joho/godotenv"
 13	mail "github.com/xhit/go-simple-mail/v2"
 14)
 15
 16func init() {
 17	err := godotenv.Load()
 18	if err != nil {
 19		log.Fatal("error loading .env file")
 20	}
 21}
 22
 23func htmlMail(article *reader.Article) (*mail.Email, error) {
 24	htmlContent, err := RenderTemplate("html.tpl", article)
 25	if err != nil {
 26		return &mail.Email{}, err
 27	}
 28
 29	htmlAbs, err := rel2abs.Convert(htmlContent, article.URL.String())
 30	if err != nil {
 31		return &mail.Email{}, err
 32	}
 33
 34	plainContent, err := reader.MakePlaintext(htmlAbs)
 35	if err != nil {
 36		return &mail.Email{}, fmt.Errorf("making plaintext: %w\n", err)
 37	}
 38
 39	email := mail.NewMSG()
 40	email.SetBodyData(mail.TextPlain, plainContent)
 41	email.AddAlternative(mail.TextHTML, string(htmlContent))
 42
 43	return email, nil
 44}
 45
 46func plainMail(article *reader.Article) (*mail.Email, error) {
 47	email := mail.NewMSG()
 48	email.SetBodyData(mail.TextPlain, []byte(article.TextContent))
 49	return email, nil
 50}
 51
 52func SendArticle(article *reader.Article, mime string, to string, readable bool) error {
 53	var (
 54		EMAIL_FROM = os.Getenv("EMAIL_FROM")
 55		err        error
 56		email      *mail.Email
 57	)
 58
 59	switch mime {
 60	case "text/html":
 61		email, err = htmlMail(article)
 62		if err != nil {
 63			return err
 64		}
 65	case "html":
 66		// Exception for weird sites
 67		email, err = htmlMail(article)
 68		if err != nil {
 69			return err
 70		}
 71	case "text/plain":
 72		email, err = plainMail(article)
 73		if err != nil {
 74			return err
 75		}
 76	default:
 77		readable = false
 78	}
 79
 80	email.SetFrom(fmt.Sprintf("saved forlater <%s>", EMAIL_FROM))
 81	email.AddTo(to)
 82	if readable {
 83		if article.Title != "" {
 84			email.SetSubject(article.Title)
 85		} else {
 86			email.SetSubject(article.URL.String())
 87		}
 88	} else {
 89		email.SetSubject("[forlater.email] Unable to read your link")
 90		email.SetBody(mail.TextPlain, fmt.Sprintf(
 91			"We were unable to parse your link: %s",
 92			article.URL.String(),
 93		))
 94	}
 95
 96	c, err := mailClient()
 97	if err != nil {
 98		return fmt.Errorf("mail: %w\n", err)
 99	}
100	err = email.Send(c)
101	if err != nil {
102		return err
103	}
104	return nil
105}
106
107func SendAttachment(r reader.Response, to string, url string) error {
108	var EMAIL_FROM = os.Getenv("EMAIL_FROM")
109	email := mail.NewMSG()
110	email.SetFrom(fmt.Sprintf("saved forlater <%s>", EMAIL_FROM))
111	email.AddTo(to)
112
113	b, err := io.ReadAll(r.Body)
114	if err != nil {
115		return fmt.Errorf("read attachment: %w\n", err)
116	}
117	fmt.Println(len(b))
118
119	ext, _ := mime.ExtensionsByType(r.MIMEType)
120	var name string
121	if ext != nil {
122		name = "file" + ext[0]
123	} else {
124		name = "file"
125	}
126	email.SetSubject(url)
127	email.Attach(&mail.File{MimeType: r.MIMEType, Data: b, Name: name, Inline: true})
128	email.SetBody(mail.TextPlain, fmt.Sprintf(`That didn't look like a HTML page; we found %s.
129We've attached it to this email.`, r.MIMEType))
130
131	c, err := mailClient()
132	if err != nil {
133		return fmt.Errorf("mail: %w\n", err)
134	}
135	err = email.Send(c)
136	if err != nil {
137		return err
138	}
139	return nil
140}