From 7457f0436eabae63a646c0b7ecfdcba1f11c226b Mon Sep 17 00:00:00 2001 From: Aine Date: Wed, 16 Nov 2022 19:30:44 +0200 Subject: [PATCH] add !pm send:html, closes #46 --- bot/command.go | 30 ++++++++++++++++++++++++------ bot/email.go | 5 +++-- smtp/session.go | 2 +- utils/email.go | 14 +++++++++++--- 4 files changed, 39 insertions(+), 12 deletions(-) diff --git a/bot/command.go b/bot/command.go index ed4bc2f..d953787 100644 --- a/bot/command.go +++ b/bot/command.go @@ -7,6 +7,7 @@ import ( "time" "maunium.net/go/mautrix/event" + "maunium.net/go/mautrix/format" "maunium.net/go/mautrix/id" "gitlab.com/etke.cc/postmoogle/utils" @@ -16,6 +17,7 @@ const ( commandHelp = "help" commandStop = "stop" commandSend = "send" + commandSendHTML = "send:html" commandDKIM = "dkim" commandCatchAll = botOptionCatchAll commandUsers = botOptionUsers @@ -66,6 +68,11 @@ func (b *Bot) initCommands() commandList { description: "Send email", allowed: b.allowSend, }, + { + key: commandSendHTML, + description: "Send email, converting markdown to HTML", + allowed: b.allowSend, + }, {allowed: b.allowOwner}, // delimiter // options commands { @@ -266,7 +273,9 @@ func (b *Bot) handleCommand(ctx context.Context, evt *event.Event, commandSlice case commandStop: b.runStop(ctx) case commandSend: - b.runSend(ctx) + b.runSend(ctx, false) + case commandSendHTML: + b.runSend(ctx, true) case commandDKIM: b.runDKIM(ctx, commandSlice) case commandUsers: @@ -377,24 +386,28 @@ func (b *Bot) sendHelp(ctx context.Context) { b.SendNotice(ctx, evt.RoomID, msg.String()) } -func (b *Bot) runSend(ctx context.Context) { +func (b *Bot) runSend(ctx context.Context, html bool) { evt := eventFromContext(ctx) if !b.allowSend(evt.Sender, evt.RoomID) { return } + subcommand := "send" + if html { + subcommand = "send:html" + } commandSlice := b.parseCommand(evt.Content.AsMessage().Body, false) to, subject, body, err := utils.ParseSend(commandSlice) if err == utils.ErrInvalidArgs { b.SendNotice(ctx, evt.RoomID, fmt.Sprintf( "Usage:\n"+ "```\n"+ - "%s send someone@example.com\n"+ + "%s %s someone@example.com\n"+ "Subject goes here on a line of its own\n"+ "Email content goes here\n"+ "on as many lines\n"+ "as you want.\n"+ "```", - b.prefix)) + b.prefix, subcommand)) return } @@ -419,6 +432,11 @@ func (b *Bot) runSend(ctx context.Context) { } } + var htmlBody string + if html { + htmlBody = format.RenderMarkdown(body, true, true).FormattedBody + } + b.lock(evt.RoomID.String()) defer b.unlock(evt.RoomID.String()) @@ -426,8 +444,8 @@ func (b *Bot) runSend(ctx context.Context) { from := mailbox + "@" + domain ID := utils.MessageID(evt.ID, domain) for _, to := range tos { - email := utils.NewEmail(ID, "", " "+ID, subject, from, to, body, "", nil) - data := email.Compose(b.getBotSettings().DKIMPrivateKey()) + email := utils.NewEmail(ID, "", " "+ID, subject, from, to, body, htmlBody, nil) + data := email.Compose(html, b.getBotSettings().DKIMPrivateKey()) queued, err := b.Sendmail(evt.ID, from, to, data) if queued { b.log.Error("cannot send email: %v", err) diff --git a/bot/email.go b/bot/email.go index d1ddf82..e81bfca 100644 --- a/bot/email.go +++ b/bot/email.go @@ -173,12 +173,13 @@ func (b *Bot) SendEmailReply(ctx context.Context) { meta.Subject = strings.SplitN(content.Body, "\n", 1)[0] } body := content.Body + htmlBody := content.FormattedBody meta.MessageID = utils.MessageID(evt.ID, domain) meta.References = meta.References + " " + meta.MessageID b.log.Debug("send email reply: %+v", meta) - email := utils.NewEmail(meta.MessageID, meta.InReplyTo, meta.References, meta.Subject, meta.From, meta.To, body, "", nil) - data := email.Compose(b.getBotSettings().DKIMPrivateKey()) + email := utils.NewEmail(meta.MessageID, meta.InReplyTo, meta.References, meta.Subject, meta.From, meta.To, body, htmlBody, nil) + data := email.Compose(false, b.getBotSettings().DKIMPrivateKey()) queued, err := b.Sendmail(evt.ID, meta.From, meta.To, data) if queued { diff --git a/smtp/session.go b/smtp/session.go index 3d656d4..1e6f28c 100644 --- a/smtp/session.go +++ b/smtp/session.go @@ -156,7 +156,7 @@ func (s *outgoingSession) Data(r io.Reader) error { eml.HTML, files) - return s.sendmail(email.From, email.To, email.Compose(s.privkey)) + return s.sendmail(email.From, email.To, email.Compose(false, s.privkey)) } func (s *outgoingSession) Reset() {} func (s *outgoingSession) Logout() error { return nil } diff --git a/utils/email.go b/utils/email.go index 6b64415..97f996c 100644 --- a/utils/email.go +++ b/utils/email.go @@ -141,7 +141,7 @@ func (e *Email) Content(threadID id.EventID, options *ContentOptions) *event.Con } // Compose converts the email object to a string (to be used for delivery via SMTP) and possibly DKIM-signs it -func (e *Email) Compose(privkey string) string { +func (e *Email) Compose(html bool, privkey string) string { var data strings.Builder domain := strings.SplitN(e.From, "@", 2)[1] @@ -149,7 +149,11 @@ func (e *Email) Compose(privkey string) string { data.WriteString("MIME-Version: 1.0") data.WriteString("\r\n") - data.WriteString("Content-Type: text/plain; charset=\"UTF-8\"") + if html { + data.WriteString("Content-Type: text/html; charset=\"UTF-8\"") + } else { + data.WriteString("Content-Type: text/plain; charset=\"UTF-8\"") + } data.WriteString("\r\n") data.WriteString("Content-Transfer-Encoding: 8BIT") @@ -189,7 +193,11 @@ func (e *Email) Compose(privkey string) string { data.WriteString("\r\n") - data.WriteString(e.Text) + if html { + data.WriteString(e.HTML) + } else { + data.WriteString(e.Text) + } data.WriteString("\r\n") return e.sign(domain, privkey, data)