newsbox/mill/mill.go
Adriano Caloiaro 8ae801ae5f
Initial commit
2023-02-15 08:57:48 -08:00

131 lines
2.8 KiB
Go

package mill
import (
"database/sql"
"encoding/json"
"log"
"newsbox/internal"
"newsbox/mailers"
"newsbox/models"
"time"
"github.com/btubbs/pgq"
)
type Handler interface {
Perform(payload []byte) (err error)
}
type IncomingEmailHandler struct {
Handler
Worker *pgq.Worker
Db *sql.DB
}
type OutgoingEmailHandler struct {
Handler
Worker *pgq.Worker
Db *sql.DB
}
type WelcomeEmailHandler struct {
Handler
Worker *pgq.Worker
Db *sql.DB
}
type EmailChangedEmailHandler struct {
Handler
Worker *pgq.Worker
Db *sql.DB
}
type WelcomeEmailJob struct {
Recipient string
VerificationURL string
}
type EmailAddressChangeEmailJob struct {
Recipient string
VerificationURL string
}
// Process processes incoming models.Message payloads
func (h *IncomingEmailHandler) Process(payload []byte) (err error) {
var msg models.Message
err = json.Unmarshal(payload, &msg)
if err != nil {
return
}
var owner models.User
err = models.DB.Eager().Find(&owner, msg.OwnerID)
if err != nil {
return
}
// Re-address the email to the user's email address
msg.To = owner.Email.Interface().(string)
// Determine time to deliver
tzOffset := owner.Preferences.TimeZoneUtcOffset
t := internal.TimeInZone(tzOffset)
et := time.Date(t.Year(), t.Month(), t.Day(), owner.Preferences.EmailHourOfDay, 0, 0, 0, t.Location())
diff := et.Sub(t)
// The message should be delivered later today
if diff > 0 {
et = t.Add(diff)
} else { // The message should be delivered tomorrow
et = time.Date(t.Year(), t.Month(), t.Day()+1, owner.Preferences.EmailHourOfDay, 0, 0, 0, t.Location())
}
log.Println("Queueing for:", et)
log.Println("Assumed location:", t.Location())
job, _ := json.MarshalIndent(&msg, "", "\t")
_, err = h.Worker.EnqueueJob("outgoing_email", job, pgq.After(et))
return
}
// Process processes outgoing models.Message payloads
func (w *OutgoingEmailHandler) Process(payload []byte) (err error) {
var msg models.Message
err = json.Unmarshal(payload, &msg)
if err != nil {
return
}
var owner models.User
err = models.DB.Find(&owner, msg.OwnerID)
if err != nil {
return
}
err = mailers.ForwardMessage(owner.Email.Interface().(string), &msg)
return
}
// Process processes new welcome email jobs
func (h *WelcomeEmailHandler) Process(payload []byte) (err error) {
var job WelcomeEmailJob
err = json.Unmarshal(payload, &job)
if err != nil {
return
}
err = mailers.SendWelcomeEmail(job.Recipient, job.VerificationURL)
return
}
// Process processes changes to user account email addresses
func (h *EmailChangedEmailHandler) Process(payload []byte) (err error) {
var job EmailAddressChangeEmailJob
err = json.Unmarshal(payload, &job)
if err != nil {
return
}
err = mailers.SendEmailAddressChangedEmail(job.Recipient, job.VerificationURL)
return
}