feeds-send-email.diff

· erock's pastes · raw

expires: 2025-10-23

  1diff --git a/go.mod b/go.mod
  2index e39be9b..a31db19 100644
  3--- a/go.mod
  4+++ b/go.mod
  5@@ -30,6 +30,8 @@ require (
  6 	github.com/darkweak/souin v1.7.6
  7 	github.com/darkweak/souin/plugins/souin/storages v1.7.6
  8 	github.com/darkweak/storages/core v0.0.14
  9+	github.com/emersion/go-sasl v0.0.0-20241020182733-b788ff22d5a6
 10+	github.com/emersion/go-smtp v0.23.0
 11 	github.com/gkampitakis/go-snaps v0.5.7
 12 	github.com/google/go-cmp v0.7.0
 13 	github.com/google/renameio/v2 v2.0.0
 14@@ -51,7 +53,6 @@ require (
 15 	github.com/pkg/sftp v1.13.9
 16 	github.com/prometheus/client_golang v1.21.1
 17 	github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06
 18-	github.com/sendgrid/sendgrid-go v3.16.0+incompatible
 19 	github.com/simplesurance/go-ip-anonymizer v0.0.0-20200429124537-35a880f8e87d
 20 	github.com/x-way/crawlerdetect v0.2.28
 21 	github.com/yuin/goldmark v1.7.8
 22@@ -232,7 +233,6 @@ require (
 23 	github.com/safchain/ethtool v0.5.10 // indirect
 24 	github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 // indirect
 25 	github.com/secure-io/sio-go v0.3.1 // indirect
 26-	github.com/sendgrid/rest v2.6.9+incompatible // indirect
 27 	github.com/shirou/gopsutil/v3 v3.24.5 // indirect
 28 	github.com/shoenig/go-m1cpu v0.1.6 // indirect
 29 	github.com/shopspring/decimal v1.4.0 // indirect
 30diff --git a/go.sum b/go.sum
 31index 56ac59e..a51aa52 100644
 32--- a/go.sum
 33+++ b/go.sum
 34@@ -262,6 +262,10 @@ github.com/dsoprea/go-utility/v2 v2.0.0-20200717064901-2fccff4aa15e/go.mod h1:uA
 35 github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
 36 github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
 37 github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
 38+github.com/emersion/go-sasl v0.0.0-20241020182733-b788ff22d5a6 h1:oP4q0fw+fOSWn3DfFi4EXdT+B+gTtzx8GC9xsc26Znk=
 39+github.com/emersion/go-sasl v0.0.0-20241020182733-b788ff22d5a6/go.mod h1:iL2twTeMvZnrg54ZoPDNfJaJaqy0xIQFuBdrLsmspwQ=
 40+github.com/emersion/go-smtp v0.23.0 h1:ZiriTOTK7sKep7jbWqgB5kPsiBp5wnE5auEMnwRMnGc=
 41+github.com/emersion/go-smtp v0.23.0/go.mod h1:ZtRRkbTyp2XTHCA+BmyTFTrj8xY4I+b4McvHxCU2gsQ=
 42 github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
 43 github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
 44 github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
 45@@ -731,10 +735,6 @@ github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUt
 46 github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
 47 github.com/secure-io/sio-go v0.3.1 h1:dNvY9awjabXTYGsTF1PiCySl9Ltofk9GA3VdWlo7rRc=
 48 github.com/secure-io/sio-go v0.3.1/go.mod h1:+xbkjDzPjwh4Axd07pRKSNriS9SCiYksWnZqdnfpQxs=
 49-github.com/sendgrid/rest v2.6.9+incompatible h1:1EyIcsNdn9KIisLW50MKwmSRSK+ekueiEMJ7NEoxJo0=
 50-github.com/sendgrid/rest v2.6.9+incompatible/go.mod h1:kXX7q3jZtJXK5c5qK83bSGMdV6tsOE70KbHoqJls4lE=
 51-github.com/sendgrid/sendgrid-go v3.16.0+incompatible h1:i8eE6IMkiCy7vusSdacHHSBUpXyTcTXy/Rl9N9aZ/Qw=
 52-github.com/sendgrid/sendgrid-go v3.16.0+incompatible/go.mod h1:QRQt+LX/NmgVEvmdRw0VT/QgUn499+iza2FnDca9fg8=
 53 github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
 54 github.com/shirou/gopsutil/v3 v3.24.5 h1:i0t8kL+kQTvpAYToeuiVk3TgDeKOFioZO3Ztz/iZ9pI=
 55 github.com/shirou/gopsutil/v3 v3.24.5/go.mod h1:bsoOS1aStSs9ErQ1WWfxllSeS1K5D+U30r2NfcubMVk=
 56diff --git a/pkg/apps/feeds/cron.go b/pkg/apps/feeds/cron.go
 57index 22731e8..965d3ec 100644
 58--- a/pkg/apps/feeds/cron.go
 59+++ b/pkg/apps/feeds/cron.go
 60@@ -10,15 +10,16 @@ import (
 61 	"math"
 62 	"net/http"
 63 	"net/url"
 64+	"os"
 65 	"strings"
 66 	"text/template"
 67 	"time"
 68 
 69+	"github.com/emersion/go-sasl"
 70+	"github.com/emersion/go-smtp"
 71 	"github.com/mmcdole/gofeed"
 72 	"github.com/picosh/pico/pkg/db"
 73 	"github.com/picosh/pico/pkg/shared"
 74-	"github.com/sendgrid/sendgrid-go"
 75-	"github.com/sendgrid/sendgrid-go/helpers/mail"
 76 )
 77 
 78 var ErrNoRecentArticles = errors.New("no recent articles")
 79@@ -125,14 +126,19 @@ func isValidItem(logger *slog.Logger, item *gofeed.Item, feedItems []*db.FeedIte
 80 }
 81 
 82 type Fetcher struct {
 83-	cfg *shared.ConfigSite
 84-	db  db.DB
 85+	cfg  *shared.ConfigSite
 86+	db   db.DB
 87+	auth sasl.Client
 88 }
 89 
 90 func NewFetcher(dbpool db.DB, cfg *shared.ConfigSite) *Fetcher {
 91+	smtPass := os.Getenv("PICO_SMTP_PASS")
 92+	emailLogin := "me@erock.io"
 93+	email := sasl.NewPlainClient("", emailLogin, smtPass)
 94 	return &Fetcher{
 95-		db:  dbpool,
 96-		cfg: cfg,
 97+		db:   dbpool,
 98+		cfg:  cfg,
 99+		auth: email,
100 	}
101 }
102 
103@@ -516,41 +522,28 @@ func (f *Fetcher) FetchAll(logger *slog.Logger, urls []string, inlineContent boo
104 	}, nil
105 }
106 
107-func (f *Fetcher) SendEmail(logger *slog.Logger, username, email string, subject string, msg *MsgBody) error {
108+func (f *Fetcher) SendEmail(logger *slog.Logger, username, email, subject string, msg *MsgBody) error {
109 	if email == "" {
110 		return fmt.Errorf("(%s) does not have an email associated with their feed post", username)
111 	}
112-
113-	from := mail.NewEmail("team pico", shared.DefaultEmail)
114-	to := mail.NewEmail(username, email)
115-
116-	// f.logger.Infof("message body (%s)", plainTextContent)
117-
118-	message := mail.NewSingleEmail(from, subject, to, msg.Text, msg.Html)
119-	client := sendgrid.NewSendClient(f.cfg.SendgridKey)
120-
121+	smtpAddr := "smtp.fastmail.com:587"
122+	fromEmail := "hello@pico.sh"
123+	to := []string{email}
124+	content := fmt.Sprintf("From: %s\r\n", fromEmail) +
125+		fmt.Sprintf("To: %s\r\n", email) +
126+		fmt.Sprintf("Subject: %s\r\n", subject) +
127+		"\r\n" +
128+		fmt.Sprintf("%s\r\n", msg.Text)
129+	reader := strings.NewReader(content)
130 	logger.Info("sending email digest")
131-	response, err := client.Send(message)
132-	if err != nil {
133-		return err
134-	}
135-
136-	// f.logger.Infof("(%s) email digest response: %v", username, response)
137-
138-	if len(response.Headers["X-Message-Id"]) > 0 {
139-		logger.Info(
140-			"successfully sent email digest",
141-			"email", email,
142-			"x-message-id", response.Headers["X-Message-Id"][0],
143-		)
144-	} else {
145-		logger.Error(
146-			"could not find x-message-id, which means sending an email failed",
147-			"email", email,
148-		)
149-	}
150-
151-	return nil
152+	err := smtp.SendMail(
153+		smtpAddr,
154+		f.auth,
155+		fromEmail,
156+		to,
157+		reader,
158+	)
159+	return err
160 }
161 
162 func (f *Fetcher) Run(logger *slog.Logger) error {