explicitly tell about enqueued email
This commit is contained in:
@@ -381,12 +381,17 @@ func (b *Bot) runSend(ctx context.Context) {
|
|||||||
for _, to := range tos {
|
for _, to := range tos {
|
||||||
email := utils.NewEmail(ID, "", " "+ID, subject, from, to, body, "", nil)
|
email := utils.NewEmail(ID, "", " "+ID, subject, from, to, body, "", nil)
|
||||||
data := email.Compose(b.getBotSettings().DKIMPrivateKey())
|
data := email.Compose(b.getBotSettings().DKIMPrivateKey())
|
||||||
err = b.sendmail(from, to, data)
|
queued, err := b.Sendmail(evt.ID, from, to, data)
|
||||||
|
if queued {
|
||||||
|
b.log.Error("cannot send email: %v", err)
|
||||||
|
b.saveSentMetadata(ctx, queued, evt.ID, email, &cfg)
|
||||||
|
continue
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
b.Error(ctx, evt.RoomID, "cannot send email to %s: %v", to, err)
|
b.Error(ctx, evt.RoomID, "cannot send email to %s: %v", to, err)
|
||||||
} else {
|
continue
|
||||||
b.saveSentMetadata(ctx, evt.ID, email, &cfg)
|
|
||||||
}
|
}
|
||||||
|
b.saveSentMetadata(ctx, false, evt.ID, email, &cfg)
|
||||||
}
|
}
|
||||||
if len(tos) > 1 {
|
if len(tos) > 1 {
|
||||||
b.SendNotice(ctx, evt.RoomID, "All emails were sent.")
|
b.SendNotice(ctx, evt.RoomID, "All emails were sent.")
|
||||||
|
|||||||
28
bot/email.go
28
bot/email.go
@@ -37,17 +37,17 @@ func (b *Bot) SetSendmail(sendmail func(string, string, string) error) {
|
|||||||
|
|
||||||
// Sendmail tries to send email immediately, but if it gets 4xx error (greylisting),
|
// Sendmail tries to send email immediately, but if it gets 4xx error (greylisting),
|
||||||
// the email will be added to the queue and retried several times after that
|
// the email will be added to the queue and retried several times after that
|
||||||
func (b *Bot) Sendmail(eventID id.EventID, from, to, data string) error {
|
func (b *Bot) Sendmail(eventID id.EventID, from, to, data string) (bool, error) {
|
||||||
err := b.sendmail(from, to, data)
|
err := b.sendmail(from, to, data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if strings.HasPrefix(err.Error(), "45") {
|
if strings.HasPrefix(err.Error(), "45") {
|
||||||
b.log.Debug("email %s (from=%s to=%s) was added to the queue: %v", eventID, from, to, err)
|
b.log.Debug("email %s (from=%s to=%s) was added to the queue: %v", eventID, from, to, err)
|
||||||
return b.enqueueEmail(eventID.String(), from, to, data)
|
return true, b.enqueueEmail(eventID.String(), from, to, data)
|
||||||
}
|
}
|
||||||
return err
|
return false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetDKIMprivkey returns DKIM private key
|
// GetDKIMprivkey returns DKIM private key
|
||||||
@@ -177,12 +177,19 @@ func (b *Bot) SendEmailReply(ctx context.Context) {
|
|||||||
email := utils.NewEmail(ID, meta.InReplyTo, meta.References, meta.Subject, fromMailbox, meta.To, body, "", nil)
|
email := utils.NewEmail(ID, meta.InReplyTo, meta.References, meta.Subject, fromMailbox, meta.To, body, "", nil)
|
||||||
data := email.Compose(b.getBotSettings().DKIMPrivateKey())
|
data := email.Compose(b.getBotSettings().DKIMPrivateKey())
|
||||||
|
|
||||||
err = b.Sendmail(evt.ID, meta.From, meta.To, data)
|
queued, err := b.Sendmail(evt.ID, meta.From, meta.To, data)
|
||||||
|
if queued {
|
||||||
|
b.log.Error("cannot send email: %v", err)
|
||||||
|
b.saveSentMetadata(ctx, queued, meta.ThreadID, email, &cfg)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
b.Error(ctx, evt.RoomID, "cannot send email: %v", err)
|
b.Error(ctx, evt.RoomID, "cannot send email: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
b.saveSentMetadata(ctx, meta.ThreadID, email, &cfg)
|
|
||||||
|
b.saveSentMetadata(ctx, queued, meta.ThreadID, email, &cfg)
|
||||||
}
|
}
|
||||||
|
|
||||||
type parentEmail struct {
|
type parentEmail struct {
|
||||||
@@ -264,10 +271,15 @@ func (b *Bot) getParentEmail(evt *event.Event) parentEmail {
|
|||||||
|
|
||||||
// saveSentMetadata used to save metadata from !pm sent and thread reply events to a separate notice message
|
// saveSentMetadata used to save metadata from !pm sent and thread reply events to a separate notice message
|
||||||
// because that metadata is needed to determine email thread relations
|
// because that metadata is needed to determine email thread relations
|
||||||
func (b *Bot) saveSentMetadata(ctx context.Context, threadID id.EventID, email *utils.Email, cfg *roomSettings) {
|
func (b *Bot) saveSentMetadata(ctx context.Context, queued bool, threadID id.EventID, email *utils.Email, cfg *roomSettings) {
|
||||||
|
text := "Email has been sent to " + email.To
|
||||||
|
if queued {
|
||||||
|
text = "Email to " + email.To + " has been queued"
|
||||||
|
}
|
||||||
|
|
||||||
evt := eventFromContext(ctx)
|
evt := eventFromContext(ctx)
|
||||||
content := email.Content(threadID, cfg.ContentOptions())
|
content := email.Content(threadID, cfg.ContentOptions())
|
||||||
notice := format.RenderMarkdown("Email has been sent to "+email.To, true, true)
|
notice := format.RenderMarkdown(text, true, true)
|
||||||
notice.MsgType = event.MsgNotice
|
notice.MsgType = event.MsgNotice
|
||||||
msgContent, ok := content.Parsed.(event.MessageEventContent)
|
msgContent, ok := content.Parsed.(event.MessageEventContent)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
|||||||
15
bot/queue.go
15
bot/queue.go
@@ -2,12 +2,11 @@ package bot
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
defaultMaxQueueItems = 1
|
defaultMaxQueueItems = 1
|
||||||
defaultMaxQueueTries = 100
|
defaultMaxQueueTries = 3
|
||||||
)
|
)
|
||||||
|
|
||||||
// ProcessQueue starts queue processing
|
// ProcessQueue starts queue processing
|
||||||
@@ -67,6 +66,7 @@ func (b *Bot) processQueueItem(itemkey string, maxRetries int) bool {
|
|||||||
b.log.Error("cannot retrieve a queue item %s: %v", itemkey, err)
|
b.log.Error("cannot retrieve a queue item %s: %v", itemkey, err)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
b.log.Debug("processing queue item %+v", item)
|
||||||
attempts, err := strconv.Atoi(item["attempts"])
|
attempts, err := strconv.Atoi(item["attempts"])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
b.log.Error("cannot parse attempts of %s: %v", itemkey, err)
|
b.log.Error("cannot parse attempts of %s: %v", itemkey, err)
|
||||||
@@ -97,12 +97,11 @@ func (b *Bot) processQueueItem(itemkey string, maxRetries int) bool {
|
|||||||
func (b *Bot) enqueueEmail(id, from, to, data string) error {
|
func (b *Bot) enqueueEmail(id, from, to, data string) error {
|
||||||
itemkey := acQueueKey + "." + id
|
itemkey := acQueueKey + "." + id
|
||||||
item := map[string]string{
|
item := map[string]string{
|
||||||
"attemptedAt": time.Now().UTC().Format(time.RFC1123Z),
|
"attempts": "0",
|
||||||
"attempts": "0",
|
"data": data,
|
||||||
"data": data,
|
"from": from,
|
||||||
"from": from,
|
"to": to,
|
||||||
"to": to,
|
"id": id,
|
||||||
"id": id,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
b.lock(itemkey)
|
b.lock(itemkey)
|
||||||
|
|||||||
@@ -146,6 +146,7 @@ func startBot(statusMsg string) {
|
|||||||
|
|
||||||
func shutdown() {
|
func shutdown() {
|
||||||
log.Info("Shutting down...")
|
log.Info("Shutting down...")
|
||||||
|
cron.Shutdown()
|
||||||
smtpm.Stop()
|
smtpm.Stop()
|
||||||
mxb.Stop()
|
mxb.Stop()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user