diff --git a/bot/bot.go b/bot/bot.go index a623731..0d493c2 100644 --- a/bot/bot.go +++ b/bot/bot.go @@ -93,6 +93,11 @@ func New( // Error message to the log and matrix room func (b *Bot) Error(ctx context.Context, message string, args ...interface{}) { evt := eventFromContext(ctx) + threadID := threadIDFromContext(ctx) + if threadID == "" { + threadID = linkpearl.EventParent(evt.ID, evt.Content.AsMessage()) + } + err := fmt.Errorf(message, args...) b.log.Error().Err(err).Msg(err.Error()) if evt == nil { @@ -105,7 +110,7 @@ func (b *Bot) Error(ctx context.Context, message string, args ...interface{}) { noThreads = cfg.NoThreads() } - b.lp.SendNotice(evt.RoomID, "ERROR: "+err.Error(), utils.RelatesTo(!noThreads, evt.ID)) + b.lp.SendNotice(evt.RoomID, "ERROR: "+err.Error(), utils.RelatesTo(!noThreads, threadID)) } // Start performs matrix /sync diff --git a/bot/context.go b/bot/context.go index 1db1db3..f4bf4e8 100644 --- a/bot/context.go +++ b/bot/context.go @@ -5,12 +5,14 @@ import ( "github.com/getsentry/sentry-go" "maunium.net/go/mautrix/event" + "maunium.net/go/mautrix/id" ) type ctxkey int const ( - ctxEvent ctxkey = iota + ctxEvent ctxkey = iota + ctxThreadID ctxkey = iota ) func newContext(evt *event.Event) context.Context { @@ -49,3 +51,21 @@ func eventToContext(ctx context.Context, evt *event.Event) context.Context { return ctx } + +func threadIDToContext(ctx context.Context, threadID id.EventID) context.Context { + return context.WithValue(ctx, ctxThreadID, threadID) +} + +func threadIDFromContext(ctx context.Context) id.EventID { + v := ctx.Value(ctxThreadID) + if v == nil { + return "" + } + + threadID, ok := v.(id.EventID) + if !ok { + return "" + } + + return threadID +} diff --git a/bot/email.go b/bot/email.go index 9132b4c..a56da12 100644 --- a/bot/email.go +++ b/bot/email.go @@ -133,6 +133,7 @@ func (b *Bot) IncomingEmail(ctx context.Context, email *email.Email) error { threadID = b.getThreadID(roomID, email.InReplyTo, email.References) if threadID != "" { newThread = false + ctx = threadIDToContext(ctx, threadID) b.setThreadID(roomID, email.MessageID, threadID) } } @@ -147,6 +148,7 @@ func (b *Bot) IncomingEmail(ctx context.Context, email *email.Email) error { } if threadID == "" { threadID = eventID + ctx = threadIDToContext(ctx, threadID) } b.setThreadID(roomID, email.MessageID, threadID) @@ -179,6 +181,12 @@ func (b *Bot) sendAutoreply(roomID id.RoomID, threadID id.EventID) { return } + threadEvt, err := b.lp.GetClient().GetEvent(roomID, threadID) + if err != nil { + b.log.Error().Err(err).Msg("cannot get thread event for autoreply") + return + } + evt := &event.Event{ ID: threadID + "-autoreply", RoomID: roomID, @@ -228,7 +236,7 @@ func (b *Bot) sendAutoreply(roomID id.RoomID, threadID id.EventID) { } var queued bool - ctx := newContext(evt) + ctx := newContext(threadEvt) recipients := meta.Recipients for _, to := range recipients { queued, err = b.Sendmail(evt.ID, meta.From, to, data) @@ -282,6 +290,7 @@ func (b *Bot) SendEmailReply(ctx context.Context) { if meta.ThreadID == "" { meta.ThreadID = b.getThreadID(evt.RoomID, meta.InReplyTo, meta.References) + ctx = threadIDToContext(ctx, meta.ThreadID) } content := evt.Content.AsMessage() if meta.Subject == "" { @@ -306,7 +315,7 @@ func (b *Bot) SendEmailReply(ctx context.Context) { eml := email.New(meta.MessageID, meta.InReplyTo, meta.References, meta.Subject, meta.From, meta.To, meta.RcptTo, meta.CC, body, htmlBody, nil, nil) data := eml.Compose(b.cfg.GetBot().DKIMPrivateKey()) if data == "" { - b.lp.SendNotice(evt.RoomID, "email body is empty", utils.RelatesTo(!cfg.NoThreads(), evt.ID)) + b.lp.SendNotice(evt.RoomID, "email body is empty", utils.RelatesTo(!cfg.NoThreads(), meta.ThreadID)) return } @@ -511,7 +520,7 @@ func (b *Bot) saveSentMetadata(ctx context.Context, queued bool, threadID id.Eve msgContent.MsgType = event.MsgNotice msgContent.Body = notice.Body msgContent.FormattedBody = notice.FormattedBody - msgContent.RelatesTo = utils.RelatesTo(!cfg.NoThreads(), evt.ID) + msgContent.RelatesTo = utils.RelatesTo(!cfg.NoThreads(), threadID) content.Parsed = msgContent msgID, err := b.lp.Send(evt.RoomID, content) if err != nil {