diff --git a/bot/email.go b/bot/email.go index 9b5639a..449f7d6 100644 --- a/bot/email.go +++ b/bot/email.go @@ -7,7 +7,6 @@ import ( "strings" "maunium.net/go/mautrix/event" - "maunium.net/go/mautrix/format" "maunium.net/go/mautrix/id" "gitlab.com/etke.cc/postmoogle/utils" @@ -27,39 +26,6 @@ const ( eventFromKey = "cc.etke.postmoogle.from" ) -func email2content(email *utils.Email, cfg roomSettings, threadID id.EventID) *event.Content { - var text strings.Builder - if !cfg.NoSender() { - text.WriteString("From: ") - text.WriteString(email.From) - text.WriteString("\n\n") - } - if !cfg.NoSubject() { - text.WriteString("# ") - text.WriteString(email.Subject) - text.WriteString("\n\n") - } - if email.HTML != "" && !cfg.NoHTML() { - text.WriteString(format.HTMLToMarkdown(email.HTML)) - } else { - text.WriteString(email.Text) - } - - parsed := format.RenderMarkdown(text.String(), true, true) - parsed.RelatesTo = utils.RelatesTo(cfg.NoThreads(), threadID) - - content := event.Content{ - Raw: map[string]interface{}{ - eventMessageIDkey: email.MessageID, - eventInReplyToKey: email.InReplyTo, - eventSubjectKey: email.Subject, - eventFromKey: email.From, - }, - Parsed: parsed, - } - return &content -} - // SetSMTPAuth sets dynamic login and password to auth against built-in smtp server func (b *Bot) SetMTA(mta utils.MTA) { b.mta = mta @@ -100,8 +66,7 @@ func (b *Bot) Send2Matrix(ctx context.Context, email *utils.Email) error { b.setThreadID(roomID, email.MessageID, threadID) } } - - content := email2content(email, cfg, threadID) + content := email.Content(threadID, cfg.ContentOptions()) eventID, serr := b.lp.Send(roomID, content) if serr != nil { return utils.UnwrapError(serr) @@ -220,7 +185,7 @@ func (b *Bot) sendFiles(ctx context.Context, roomID id.RoomID, files []*utils.Fi MsgType: event.MsgFile, Body: req.FileName, URL: resp.ContentURI.CUString(), - RelatesTo: utils.RelatesTo(noThreads, parentID), + RelatesTo: utils.RelatesTo(!noThreads, parentID), }) if err != nil { b.Error(ctx, roomID, "cannot send uploaded file %s: %v", req.FileName, err) diff --git a/bot/settings_room.go b/bot/settings_room.go index 4423c80..411d33d 100644 --- a/bot/settings_room.go +++ b/bot/settings_room.go @@ -67,6 +67,21 @@ func (s roomSettings) NoFiles() bool { return utils.Bool(s.Get(roomOptionNoFiles)) } +// ContentOptions converts room display settings to content options +func (s roomSettings) ContentOptions() *utils.ContentOptions { + return &utils.ContentOptions{ + HTML: !s.NoHTML(), + Sender: !s.NoSender(), + Subject: !s.NoSubject(), + Threads: !s.NoThreads(), + + FromKey: eventFromKey, + SubjectKey: eventSubjectKey, + MessageIDKey: eventMessageIDkey, + InReplyToKey: eventInReplyToKey, + } +} + func (b *Bot) getRoomSettings(roomID id.RoomID) (roomSettings, error) { cfg := b.cfg.Get(roomID.String()) if cfg != nil { diff --git a/utils/email.go b/utils/email.go index 3e60e95..b70d156 100644 --- a/utils/email.go +++ b/utils/email.go @@ -8,6 +8,9 @@ import ( "time" "github.com/emersion/go-msgauth/dkim" + "maunium.net/go/mautrix/event" + "maunium.net/go/mautrix/format" + "maunium.net/go/mautrix/id" ) // MTA is mail transfer agent @@ -30,6 +33,21 @@ type Email struct { Files []*File } +// ContentOptions used to convert email to matrix event content +type ContentOptions struct { + // On/Off + Sender bool + Subject bool + HTML bool + Threads bool + + // Keys + MessageIDKey string + InReplyToKey string + SubjectKey string + FromKey string +} + // NewEmail constructs Email object func NewEmail(messageID, inReplyTo, subject, from, to, text, html string, files []*File) *Email { email := &Email{ @@ -55,6 +73,40 @@ func NewEmail(messageID, inReplyTo, subject, from, to, text, html string, files return email } +// Content converts email to matrix event content +func (e *Email) Content(threadID id.EventID, options *ContentOptions) *event.Content { + var text strings.Builder + if options.Sender { + text.WriteString("From: ") + text.WriteString(e.From) + text.WriteString("\n\n") + } + if options.Subject { + text.WriteString("# ") + text.WriteString(e.Subject) + text.WriteString("\n\n") + } + if e.HTML != "" && options.HTML { + text.WriteString(format.HTMLToMarkdown(e.HTML)) + } else { + text.WriteString(e.Text) + } + + parsed := format.RenderMarkdown(text.String(), true, true) + parsed.RelatesTo = RelatesTo(options.Threads, threadID) + + content := event.Content{ + Raw: map[string]interface{}{ + options.MessageIDKey: e.MessageID, + options.InReplyToKey: e.InReplyTo, + options.SubjectKey: e.Subject, + options.FromKey: e.From, + }, + Parsed: parsed, + } + return &content +} + // Compose converts email object to string and (optionally) signs it func (e *Email) Compose(privkey string) string { domain := strings.SplitN(e.From, "@", 2)[0] diff --git a/utils/matrix.go b/utils/matrix.go index 47e4f03..3af5de4 100644 --- a/utils/matrix.go +++ b/utils/matrix.go @@ -7,22 +7,22 @@ import ( ) // RelatesTo block of matrix event content -func RelatesTo(noThreads bool, parentID id.EventID) *event.RelatesTo { +func RelatesTo(threads bool, parentID id.EventID) *event.RelatesTo { if parentID == "" { return nil } - if noThreads { + if threads { return &event.RelatesTo{ - InReplyTo: &event.InReplyTo{ - EventID: parentID, - }, + Type: event.RelThread, + EventID: parentID, } } return &event.RelatesTo{ - Type: event.RelThread, - EventID: parentID, + InReplyTo: &event.InReplyTo{ + EventID: parentID, + }, } }