瀏覽代碼

Refactor bounces package to remove db/queries dependency.

Instead of passing a DB/SQL statement references, instead pass a
callback that inserts a bounce into the DB via the `core` package.
Kailash Nadh 3 年之前
父節點
當前提交
aa19771307
共有 5 個文件被更改,包括 37 次插入25 次删除
  1. 2 2
      cmd/init.go
  2. 2 0
      cmd/main.go
  3. 6 23
      internal/bounce/bounce.go
  4. 25 0
      internal/core/bounces.go
  5. 2 0
      internal/core/core.go

+ 2 - 2
cmd/init.go

@@ -603,12 +603,12 @@ func initNotifTemplates(path string, fs stuffbin.FileSystem, i *i18n.I18n, cs *c
 // for incoming bounce events.
 func initBounceManager(app *App) *bounce.Manager {
 	opt := bounce.Opt{
-		BounceCount:     ko.MustInt("bounce.count"),
-		BounceAction:    ko.MustString("bounce.action"),
 		WebhooksEnabled: ko.Bool("bounce.webhooks_enabled"),
 		SESEnabled:      ko.Bool("bounce.ses_enabled"),
 		SendgridEnabled: ko.Bool("bounce.sendgrid_enabled"),
 		SendgridKey:     ko.String("bounce.sendgrid_key"),
+
+		RecordBounceCB: app.core.RecordBounce,
 	}
 
 	// For now, only one mailbox is supported.

+ 2 - 0
cmd/main.go

@@ -174,6 +174,8 @@ func main() {
 	app.core = core.New(&core.Opt{
 		Constants: core.Constants{
 			SendOptinConfirmation: app.constants.SendOptinConfirmation,
+			MaxBounceCount:        ko.MustInt("bounce.count"),
+			BounceAction:          ko.MustString("bounce.action"),
 		},
 		Queries: queries,
 		DB:      db,

+ 6 - 23
internal/bounce/bounce.go

@@ -9,7 +9,6 @@ import (
 	"github.com/knadh/listmonk/internal/bounce/mailbox"
 	"github.com/knadh/listmonk/internal/bounce/webhooks"
 	"github.com/knadh/listmonk/models"
-	"github.com/lib/pq"
 )
 
 const (
@@ -27,9 +26,6 @@ type Mailbox interface {
 
 // Opt represents bounce processing options.
 type Opt struct {
-	BounceCount  int    `json:"count"`
-	BounceAction string `json:"action"`
-
 	MailboxEnabled  bool        `json:"mailbox_enabled"`
 	MailboxType     string      `json:"mailbox_type"`
 	Mailbox         mailbox.Opt `json:"mailbox"`
@@ -37,6 +33,8 @@ type Opt struct {
 	SESEnabled      bool        `json:"ses_enabled"`
 	SendgridEnabled bool        `json:"sendgrid_enabled"`
 	SendgridKey     string      `json:"sendgrid_key"`
+
+	RecordBounceCB func(models.Bounce) error
 }
 
 // Manager handles e-mail bounces.
@@ -106,27 +104,12 @@ func (m *Manager) Run() {
 				return
 			}
 
-			date := b.CreatedAt
-			if date.IsZero() {
-				date = time.Now()
+			if b.CreatedAt.IsZero() {
+				b.CreatedAt = time.Now()
 			}
 
-			_, err := m.queries.RecordQuery.Exec(b.SubscriberUUID,
-				b.Email,
-				b.CampaignUUID,
-				b.Type,
-				b.Source,
-				b.Meta,
-				date,
-				m.opt.BounceCount,
-				m.opt.BounceAction)
-			if err != nil {
-				// Ignore the error if it complained of no subscriber.
-				if pqErr, ok := err.(*pq.Error); ok && pqErr.Column == "subscriber_id" {
-					m.log.Printf("bounced subscriber (%s / %s) not found", b.SubscriberUUID, b.Email)
-					continue
-				}
-				m.log.Printf("error recording bounce: %v", err)
+			if err := m.opt.RecordBounceCB(b); err != nil {
+				continue
 			}
 		}
 	}

+ 25 - 0
internal/core/bounces.go

@@ -50,6 +50,31 @@ func (c *Core) GetBounce(id int) (models.Bounce, error) {
 	return out[0], nil
 }
 
+// RecordBounce records a new bounce.
+func (c *Core) RecordBounce(b models.Bounce) error {
+	_, err := c.q.RecordBounce.Exec(b.SubscriberUUID,
+		b.Email,
+		b.CampaignUUID,
+		b.Type,
+		b.Source,
+		b.Meta,
+		b.CreatedAt,
+		c.constants.MaxBounceCount,
+		c.constants.BounceAction)
+
+	if err != nil {
+		// Ignore the error if it complained of no subscriber.
+		if pqErr, ok := err.(*pq.Error); ok && pqErr.Column == "subscriber_id" {
+			c.log.Printf("bounced subscriber (%s / %s) not found", b.SubscriberUUID, b.Email)
+			return nil
+		}
+
+		c.log.Printf("error recording bounce: %v", err)
+	}
+
+	return err
+}
+
 // DeleteBounce deletes a list.
 func (c *Core) DeleteBounce(id int) error {
 	return c.DeleteBounces([]int{id})

+ 2 - 0
internal/core/core.go

@@ -36,6 +36,8 @@ type Core struct {
 // Constants represents constant config.
 type Constants struct {
 	SendOptinConfirmation bool
+	MaxBounceCount        int
+	BounceAction          string
 }
 
 // Hooks contains external function hooks that are required by the core package.