This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
package mail
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"plumber/internal/events"
|
||||
"plumber/internal/store"
|
||||
)
|
||||
|
||||
// Subscribe sends reply emails from PostCreated events. Nop or nil is a no-op.
|
||||
func Subscribe(bus *events.Bus, st store.Store, n Notifier) {
|
||||
if bus == nil || st == nil || n == nil {
|
||||
return
|
||||
}
|
||||
if _, disabled := n.(Nop); disabled {
|
||||
return
|
||||
}
|
||||
s := subscriber{store: st, mail: n}
|
||||
bus.Subscribe(s.handle)
|
||||
}
|
||||
|
||||
type subscriber struct {
|
||||
store store.Store
|
||||
mail Notifier
|
||||
}
|
||||
|
||||
func (s subscriber) handle(_ context.Context, ev any) {
|
||||
created, ok := ev.(events.PostCreated)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
if strings.TrimSpace(created.ParentID) == "" {
|
||||
return
|
||||
}
|
||||
go s.notifyReply(created.PostEvent)
|
||||
}
|
||||
|
||||
func (s subscriber) notifyReply(ev events.PostEvent) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
defer cancel()
|
||||
|
||||
parent, err := s.store.GetPost(ctx, ev.ParentID)
|
||||
if err != nil {
|
||||
log.Printf("notify reply %s: load parent: %v", ev.PostID, err)
|
||||
return
|
||||
}
|
||||
root, err := s.store.GetPost(ctx, ev.RootID)
|
||||
if err != nil {
|
||||
log.Printf("notify reply %s: load root: %v", ev.PostID, err)
|
||||
return
|
||||
}
|
||||
author, err := s.store.UserByID(ctx, ev.AuthorID)
|
||||
if err != nil {
|
||||
log.Printf("notify reply %s: load author: %v", ev.PostID, err)
|
||||
return
|
||||
}
|
||||
recipientID := parent.AuthorID
|
||||
if author.Admin() {
|
||||
recipientID = root.AuthorID
|
||||
}
|
||||
if recipientID == author.ID {
|
||||
return
|
||||
}
|
||||
msg := PostReply{
|
||||
RootID: root.ID,
|
||||
RootTitle: root.Title,
|
||||
ReplyID: ev.PostID,
|
||||
ReplyBody: ev.Body,
|
||||
ReplyAuthorName: author.Name,
|
||||
}
|
||||
recipient, err := s.store.UserByID(ctx, recipientID)
|
||||
if err != nil {
|
||||
log.Printf("notify reply %s: load recipient: %v", msg.ReplyID, err)
|
||||
return
|
||||
}
|
||||
if recipient == nil || strings.TrimSpace(recipient.Email) == "" {
|
||||
return
|
||||
}
|
||||
msg.ToEmail = recipient.Email
|
||||
msg.ToName = recipient.Name
|
||||
if err := s.mail.NotifyPostReply(ctx, msg); err != nil {
|
||||
log.Printf("notify reply %s: %v", msg.ReplyID, err)
|
||||
return
|
||||
}
|
||||
log.Printf("notify reply %s: accepted", msg.ReplyID)
|
||||
}
|
||||
Reference in New Issue
Block a user