aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--go.mod1
-rw-r--r--go.sum2
-rw-r--r--walrss/internal/rss/processor.go59
-rw-r--r--walrss/internal/state/state.go19
-rw-r--r--walrss/main.go5
5 files changed, 69 insertions, 17 deletions
diff --git a/go.mod b/go.mod
index 1a1c461..dded7d8 100644
--- a/go.mod
+++ b/go.mod
@@ -16,6 +16,7 @@ require (
github.com/huandu/xstrings v1.3.2 // indirect
github.com/imdario/mergo v0.3.12 // indirect
github.com/jaytaylor/html2text v0.0.0-20211105163654-bc68cce691ba // indirect
+ github.com/jordan-wright/email v4.0.1-0.20210109023952-943e75fe5223+incompatible // indirect
github.com/json-iterator/go v1.1.10 // indirect
github.com/kkyr/fig v0.3.0 // indirect
github.com/klauspost/compress v1.15.0 // indirect
diff --git a/go.sum b/go.sum
index 6d0c6bb..ca69f32 100644
--- a/go.sum
+++ b/go.sum
@@ -34,6 +34,8 @@ github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU=
github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
github.com/jaytaylor/html2text v0.0.0-20211105163654-bc68cce691ba h1:QFQpJdgbON7I0jr2hYW7Bs+XV0qjc3d5tZoDnRFnqTg=
github.com/jaytaylor/html2text v0.0.0-20211105163654-bc68cce691ba/go.mod h1:CVKlgaMiht+LXvHG173ujK6JUhZXKb2u/BQtjPDIvyk=
+github.com/jordan-wright/email v4.0.1-0.20210109023952-943e75fe5223+incompatible h1:jdpOPRN1zP63Td1hDQbZW73xKmzDvZHzVdNYxhnTMDA=
+github.com/jordan-wright/email v4.0.1-0.20210109023952-943e75fe5223+incompatible/go.mod h1:1c7szIrayyPPB/987hsnvNzLushdWf4o/79s3P08L8A=
github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68=
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/kkyr/fig v0.3.0 h1:5bd1amYKp/gsK2bGEUJYzcCrQPKOZp6HZD9K21v9Guo=
diff --git a/walrss/internal/rss/processor.go b/walrss/internal/rss/processor.go
index e220f0a..214aaf2 100644
--- a/walrss/internal/rss/processor.go
+++ b/walrss/internal/rss/processor.go
@@ -3,15 +3,17 @@ package rss
import (
"bytes"
"context"
+ "crypto/tls"
"fmt"
"github.com/carlmjohnson/requests"
"github.com/codemicro/walrss/walrss/internal/core"
"github.com/codemicro/walrss/walrss/internal/db"
"github.com/codemicro/walrss/walrss/internal/state"
+ "github.com/jordan-wright/email"
"github.com/matcornic/hermes"
"github.com/mmcdole/gofeed"
"github.com/patrickmn/go-cache"
- "io/ioutil"
+ "net/smtp"
"sort"
"strings"
"sync"
@@ -30,10 +32,11 @@ type processedFeed struct {
}
func ProcessFeeds(st *state.State, day db.SendDay, hour int) error {
- u, e := core.GetUsersBySchedule(st, day, hour)
+ u, err := core.GetUsersBySchedule(st, day, hour)
+ if err != nil {
+ return err
+ }
for _, ur := range u {
- fmt.Printf("%#v\n", ur)
-
userFeeds, err := core.GetFeedsForUser(st, ur.ID)
if err != nil {
return err
@@ -49,17 +52,26 @@ func ProcessFeeds(st *state.State, day db.SendDay, hour int) error {
if err != nil {
pf.Error = err
} else {
+ // TODO: this interval is wack
pf.Items = filterFeedContent(rawFeed, time.Date(2022, 04, 01, 0, 0, 0, 0, time.UTC))
}
processedFeeds = append(processedFeeds, pf)
}
- plainContent, htmlContent, err := generateEmail(processedFeeds)
+ plainContent, htmlContent, err := generateEmail(st, processedFeeds)
if err != nil {
return err
}
- // TODO: Send email
+ if err := sendEmail(
+ st,
+ plainContent,
+ htmlContent,
+ ur.Email,
+ "RSS digest for "+strings.ToUpper(time.Now().UTC().Format(dateFormat)),
+ ); err != nil {
+ return err
+ }
}
return nil
@@ -118,7 +130,7 @@ func filterFeedContent(feed *gofeed.Feed, earliestPublishTime time.Time) []*feed
return o
}
-func generateEmail(processedItems []*processedFeed) (plain, html []byte, err error) {
+func generateEmail(st *state.State, processedItems []*processedFeed) (plain, html []byte, err error) {
sort.Slice(processedItems, func(i, j int) bool {
pi, pj := processedItems[i], processedItems[j]
@@ -135,6 +147,13 @@ func generateEmail(processedItems []*processedFeed) (plain, html []byte, err err
var sb strings.Builder
+ sb.WriteString("Here are the updates to the feeds you're subscribed to that have been published since we " +
+ "last sent you a digest.\n\n")
+
+ if len(processedItems) == 0 {
+ sb.WriteString("*There's nothing to show here right now.*\n\n")
+ }
+
for _, processedItem := range processedItems {
if len(processedItem.Items) != 0 || processedItem.Error != nil {
@@ -165,11 +184,21 @@ func generateEmail(processedItems []*processedFeed) (plain, html []byte, err err
e := hermes.Email{
Body: hermes.Body{
+ Title: "Hi there!",
+ Signature: "Have a good one",
+ Outros: []string{
+ "You can edit the feeds that you're subscribed to and your delivery settings here: " + st.Config.Server.ExternalURL,
+ },
FreeMarkdown: hermes.Markdown(sb.String()),
},
}
renderer := hermes.Hermes{
+ Product: hermes.Product{
+ Name: "Walrss",
+ Link: st.Config.Server.ExternalURL,
+ Copyright: ":)",
+ },
Theme: new(hermes.Flat),
}
@@ -185,3 +214,19 @@ func generateEmail(processedItems []*processedFeed) (plain, html []byte, err err
return []byte(plainString), []byte(htmlString), nil
}
+
+func sendEmail(st *state.State, plain, html []byte, to, subject string) error {
+ return (&email.Email{
+ From: st.Config.Email.From,
+ To: []string{to},
+ Subject: subject,
+ Text: plain,
+ HTML: html,
+ }).SendWithStartTLS(
+ fmt.Sprintf("%s:%d", st.Config.Email.Host, st.Config.Email.Port),
+ smtp.PlainAuth("", st.Config.Email.Username, st.Config.Email.Password, st.Config.Email.Host),
+ &tls.Config{
+ ServerName: st.Config.Email.Host,
+ },
+ )
+}
diff --git a/walrss/internal/state/state.go b/walrss/internal/state/state.go
index 31cb59b..6fc714b 100644
--- a/walrss/internal/state/state.go
+++ b/walrss/internal/state/state.go
@@ -19,16 +19,17 @@ func New() *State {
}
type Config struct {
- //Email struct {
- // Host string `fig:"host" validate:"required"`
- // Username string `fig:"username" validate:"required"`
- // Password string `fig:"password" validate:"required"`
- // From string `fig:"from" validate:"required"`
- // Port int `fig:"port" validate:"required"`
- //}
+ Email struct {
+ Host string `fig:"host" validate:"required"`
+ Username string `fig:"username" validate:"required"`
+ Password string `fig:"password" validate:"required"`
+ From string `fig:"from" validate:"required"`
+ Port int `fig:"port" validate:"required"`
+ }
Server struct {
- Host string `fig:"host" default:"127.0.0.1"`
- Port int `fig:"port" default:"8080"`
+ Host string `fig:"host" default:"127.0.0.1"`
+ Port int `fig:"port" default:"8080"`
+ ExternalURL string `fig:"externalURL" validate:"required"`
}
DataDirectory string `fig:"dataDir" default:"./"`
Debug bool `fig:"debug"`
diff --git a/walrss/main.go b/walrss/main.go
index 9978bab..1c11913 100644
--- a/walrss/main.go
+++ b/walrss/main.go
@@ -39,7 +39,10 @@ func run() error {
return err
}
- rss.ProcessFeeds(st, db.SendOnSunday, 21)
+ err = rss.ProcessFeeds(st, db.SendOnSunday, 21)
+ if err != nil {
+ return err
+ }
return server.Run()
}