Send mailing list emails
Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
This commit is contained in:
@@ -31,6 +31,9 @@ type (
|
||||
ID gid.GID `db:"id"`
|
||||
RecipientEmail string `db:"recipient_email"`
|
||||
RecipientName string `db:"recipient_name"`
|
||||
ReplyTo *mail.Addr `db:"reply_to"`
|
||||
UnsubscribeURL *string `db:"unsubscribe_url"`
|
||||
MailingListUpdateID *gid.GID `db:"mailing_list_update_id"`
|
||||
Subject string `db:"subject"`
|
||||
TextBody string `db:"text_body"`
|
||||
HtmlBody *string `db:"html_body"`
|
||||
@@ -44,6 +47,14 @@ type (
|
||||
UpdatedAt time.Time `db:"updated_at"`
|
||||
SentAt *time.Time `db:"sent_at"`
|
||||
}
|
||||
|
||||
Emails []*Email
|
||||
|
||||
EmailOptions struct {
|
||||
ReplyTo *mail.Addr
|
||||
UnsubscribeURL *string
|
||||
MailingListUpdateID *gid.GID
|
||||
}
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -62,9 +73,10 @@ func NewEmail(
|
||||
subject string,
|
||||
textBody string,
|
||||
htmlBody *string,
|
||||
opts *EmailOptions,
|
||||
) *Email {
|
||||
now := time.Now()
|
||||
return &Email{
|
||||
e := &Email{
|
||||
ID: gid.New(gid.NilTenant, EmailEntityType),
|
||||
RecipientName: recipientName,
|
||||
RecipientEmail: recipientEmail.String(),
|
||||
@@ -77,6 +89,14 @@ func NewEmail(
|
||||
CreatedAt: now,
|
||||
UpdatedAt: now,
|
||||
}
|
||||
|
||||
if opts != nil {
|
||||
e.ReplyTo = opts.ReplyTo
|
||||
e.UnsubscribeURL = opts.UnsubscribeURL
|
||||
e.MailingListUpdateID = opts.MailingListUpdateID
|
||||
}
|
||||
|
||||
return e
|
||||
}
|
||||
|
||||
func (e *Email) Insert(
|
||||
@@ -85,40 +105,100 @@ func (e *Email) Insert(
|
||||
) error {
|
||||
q := `
|
||||
INSERT INTO emails (
|
||||
id, recipient_email, recipient_name, subject, text_body, html_body,
|
||||
status, attempt_count, max_attempts, created_at, updated_at
|
||||
id,
|
||||
recipient_email,
|
||||
recipient_name,
|
||||
reply_to, unsubscribe_url,
|
||||
mailing_list_update_id,
|
||||
subject,
|
||||
text_body,
|
||||
html_body,
|
||||
status,
|
||||
attempt_count,
|
||||
max_attempts,
|
||||
created_at,
|
||||
updated_at
|
||||
)
|
||||
VALUES (
|
||||
@id, @recipient_email, @recipient_name, @subject, @text_body, @html_body,
|
||||
@status, @attempt_count, @max_attempts, @created_at, @updated_at
|
||||
@id,
|
||||
@recipient_email,
|
||||
@recipient_name,
|
||||
@reply_to,
|
||||
@unsubscribe_url,
|
||||
@mailing_list_update_id,
|
||||
@subject,
|
||||
@text_body,
|
||||
@html_body,
|
||||
@status,
|
||||
@attempt_count,
|
||||
@max_attempts,
|
||||
@created_at,
|
||||
@updated_at
|
||||
)
|
||||
`
|
||||
`
|
||||
|
||||
args := pgx.StrictNamedArgs{
|
||||
"id": e.ID,
|
||||
"recipient_email": e.RecipientEmail,
|
||||
"recipient_name": e.RecipientName,
|
||||
"subject": e.Subject,
|
||||
"text_body": e.TextBody,
|
||||
"html_body": e.HtmlBody,
|
||||
"status": e.Status,
|
||||
"attempt_count": e.AttemptCount,
|
||||
"max_attempts": e.MaxAttempts,
|
||||
"created_at": e.CreatedAt,
|
||||
"updated_at": e.UpdatedAt,
|
||||
"id": e.ID,
|
||||
"recipient_email": e.RecipientEmail,
|
||||
"recipient_name": e.RecipientName,
|
||||
"reply_to": e.ReplyTo,
|
||||
"unsubscribe_url": e.UnsubscribeURL,
|
||||
"mailing_list_update_id": e.MailingListUpdateID,
|
||||
"subject": e.Subject,
|
||||
"text_body": e.TextBody,
|
||||
"html_body": e.HtmlBody,
|
||||
"status": e.Status,
|
||||
"attempt_count": e.AttemptCount,
|
||||
"max_attempts": e.MaxAttempts,
|
||||
"created_at": e.CreatedAt,
|
||||
"updated_at": e.UpdatedAt,
|
||||
}
|
||||
|
||||
_, err := conn.Exec(ctx, q, args)
|
||||
return err
|
||||
}
|
||||
|
||||
func (emails Emails) BulkInsert(
|
||||
ctx context.Context,
|
||||
conn pg.Conn,
|
||||
) error {
|
||||
if len(emails) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
rows := make([][]any, 0, len(emails))
|
||||
for _, e := range emails {
|
||||
rows = append(rows, []any{
|
||||
e.ID,
|
||||
e.RecipientEmail,
|
||||
e.RecipientName,
|
||||
e.ReplyTo,
|
||||
e.UnsubscribeURL,
|
||||
e.MailingListUpdateID,
|
||||
e.Subject,
|
||||
e.TextBody,
|
||||
e.HtmlBody,
|
||||
e.CreatedAt,
|
||||
e.UpdatedAt,
|
||||
})
|
||||
}
|
||||
|
||||
_, err := conn.CopyFrom(
|
||||
ctx,
|
||||
pgx.Identifier{"emails"},
|
||||
[]string{"id", "recipient_email", "recipient_name", "reply_to", "unsubscribe_url", "mailing_list_update_id", "subject", "text_body", "html_body", "created_at", "updated_at"},
|
||||
pgx.CopyFromRows(rows),
|
||||
)
|
||||
return err
|
||||
}
|
||||
|
||||
func (e *Email) LoadNextPendingForUpdateSkipLocked(
|
||||
ctx context.Context,
|
||||
conn pg.Conn,
|
||||
) error {
|
||||
q := `
|
||||
SELECT
|
||||
id, recipient_email, recipient_name, subject, text_body, html_body,
|
||||
id, recipient_email, recipient_name, reply_to, unsubscribe_url, mailing_list_update_id, subject, text_body, html_body,
|
||||
status, processing_started_at, attempt_count, max_attempts,
|
||||
last_attempted_at, last_error, created_at, updated_at, sent_at
|
||||
FROM emails
|
||||
|
||||
Reference in New Issue
Block a user