Commit 0a997c5

Eric Bower  ·  2025-08-30 08:22:02 -0400 EDT
parent d80b355
chore(feeds): better formatting for smtp emails
1 files changed,  +23, -11
+23, -11
......@@ -132,11 +132,14 @@ type Fetcher struct {
132132 db db.DB
133133 auth sasl.Client
134134 gron *gronx.Gronx
135+ host string
135136 }
136137
137138 func NewFetcher(dbpool db.DB, cfg *shared.ConfigSite) *Fetcher {
139+ host := os.Getenv("PICO_SMTP_HOST")
138140 smtPass := os.Getenv("PICO_SMTP_PASS")
139141 emailLogin := os.Getenv("PICO_SMTP_USER")
142+
140143 auth := sasl.NewPlainClient("", emailLogin, smtPass)
141144 gron := gronx.New()
142145 return &Fetcher{
......@@ -144,6 +147,7 @@ func NewFetcher(dbpool db.DB, cfg *shared.ConfigSite) *Fetcher {
144147 cfg: cfg,
145148 auth: auth,
146149 gron: gron,
150+ host: host,
147151 }
148152 }
149153
......@@ -253,7 +257,8 @@ func (f *Fetcher) RunPost(logger *slog.Logger, user *db.User, post *db.Post, ski
253257 return err
254258 }
255259
256- subject := fmt.Sprintf("%s feed digest", post.Title)
260+ subject := fmt.Sprintf("%s feed digest", post.Filename)
261+ unsubURL := getUnsubURL(post)
257262
258263 msgBody, err := f.FetchAll(logger, urls, parsed.InlineContent, user.Name, post)
259264 if err != nil {
......@@ -277,9 +282,11 @@ Also, we have centralized logs in our pico.sh TUI that will display realtime fee
277282
278283 %s`, post.Data.Attempts, maxAttempts, errForUser.Error(), post.Text)
279284 err = f.SendEmail(
280- logger, user.Name,
285+ logger,
286+ user.Name,
281287 parsed.Email,
282288 subject,
289+ unsubURL,
283290 &MsgBody{Html: strings.ReplaceAll(errBody, "\n", "<br />"), Text: errBody},
284291 )
285292 if err != nil {
......@@ -307,7 +314,7 @@ Also, we have centralized logs in our pico.sh TUI that will display realtime fee
307314 }
308315
309316 if msgBody != nil {
310- err = f.SendEmail(logger, user.Name, parsed.Email, subject, msgBody)
317+ err = f.SendEmail(logger, user.Name, parsed.Email, subject, unsubURL, msgBody)
311318 if err != nil {
312319 return err
313320 }
......@@ -460,6 +467,10 @@ type MsgBody struct {
460467 Text string
461468 }
462469
470+func getUnsubURL(post *db.Post) string {
471+ return fmt.Sprintf("https://feeds.pico.sh/unsub/%s", post.ID)
472+}
473+
463474 func (f *Fetcher) FetchAll(logger *slog.Logger, urls []string, inlineContent bool, username string, post *db.Post) (*MsgBody, error) {
464475 logger.Info("fetching feeds", "inlineContent", inlineContent)
465476 fp := gofeed.NewParser()
......@@ -475,7 +486,7 @@ func (f *Fetcher) FetchAll(logger *slog.Logger, urls []string, inlineContent boo
475486 }
476487 feeds := &DigestFeed{
477488 KeepAliveURL: fmt.Sprintf("https://feeds.pico.sh/keep-alive/%s", post.ID),
478- UnsubURL: fmt.Sprintf("https://feeds.pico.sh/unsub/%s", post.ID),
489+ UnsubURL: getUnsubURL(post),
479490 DaysLeft: daysLeft,
480491 ShowBanner: showBanner,
481492 Options: DigestOptions{InlineContent: inlineContent},
......@@ -564,19 +575,20 @@ func (f *Fetcher) FetchAll(logger *slog.Logger, urls []string, inlineContent boo
564575 }, nil
565576 }
566577
567-func (f *Fetcher) SendEmail(logger *slog.Logger, username, email, subject string, msg *MsgBody) error {
578+func (f *Fetcher) SendEmail(logger *slog.Logger, username, email, subject, unsubURL string, msg *MsgBody) error {
568579 if email == "" {
569580 return fmt.Errorf("(%s) does not have an email associated with their feed post", username)
570581 }
571- smtpAddr := "smtp.fastmail.com:587"
582+ smtpAddr := f.host
572583 fromEmail := "hello@pico.sh"
573584 to := []string{email}
574585 headers := map[string]string{
575- "From": fromEmail,
576- "To": email,
577- "Subject": subject,
578- "MIME-Version": "1.0",
579- "Content-Type": `multipart/alternative; boundary="boundary123"`,
586+ "From": fromEmail,
587+ "Subject": subject,
588+ "To": email,
589+ "MIME-Version": "1.0",
590+ "Content-Type": `multipart/alternative; boundary="boundary123"`,
591+ "List-Unsubscribe": "<" + unsubURL + ">",
580592 }
581593 var content strings.Builder
582594 for k, v := range headers {