Sending multipart/alternative with mutt

12

3

I'd like the option for certain emails and/or recipients to have a script run before sending (whether automatically or by pressing a keybinding) which takes my text/plain, runs a script over it, and then attaches the output of that script with the text/html type, setting the whole message to multipart/alternative.

Side ramble: It might be nice if this happened automatically immediately before sending but only if the body type was currently set to text/markdown, as this would mean the pending email is never in a state where I edit the source again but forget to regenerate the HTML, and I still have the option to send only text/plain. Then I'd have another binding to set the content type of the body to text/markdown, so that this would be picked up. But then I also have the issue that a lot of mail clients (Gmail included) refuse to render text/markdown (even as plain text), instead offering it as a download, so I'd need to have the content type of the source part switched back to text/plain.

Is such a thing possible with mutt?

Sadly as far as I can tell mutt doesn't support sending multipart/alternative messages, refusing to send anything but multipart/mixed, but I'd love to be shown I'm wrong.

The best solution I've been able to come up with is this macro:

macro compose M "<filter-entry>commonmark<return>y<edit-type><kill-line>text/html<return>" "convert message to HTML with Commonmark"

There are a few issues with this:

  • It entirely replaces the original plain text, so it's then much harder to edit
  • I don't like that there's the y in the macro to say yes to the dialog asking whether it's okay to overwrite the file
  • I have to press return after this runs
  • And of course the main thing: it doesn't send the plain text alternative

Is there a better solution?

I'm potentially open to another text-mode mail client, as long as it

  • is usable with Google Apps, and syncs flags etc in both directions
  • supports GPG
  • has vim-like bindings, or I can configure them
  • lets me use vim as a message editor
  • has a threaded message view
  • allows me to filter/search mail in a somewhat sophisticated way (sender, recipient, presence of attachments, subject and body text search)
  • handles attachment types a bit like mutt, i.e. mailcap or equivalent so I can run incoming HTML mail through lynx, or press something to open it in the graphical browser if need be, I can launch image viewers at a button press, and so on

tremby

Posted 2016-03-18T19:50:54.307

Reputation: 432

Answers

1

I forgot about NeoMutt supports multipart. https://neomutt.org/guide/mimesupport.

Davey

Posted 2016-03-18T19:50:54.307

Reputation: 549

That is good to hear. The page you linked said the support for sending multipart/alternative is rudimentary but I'll give it a try some time soon. Thanks for pointing it out. – tremby – 2019-04-04T23:28:30.873

Neomutt is supposed to be a drop-in replacement for regular ol' mutt. The other nice thing is that its apparently got pretty large active development. – Davey – 2019-04-05T12:17:06.910

Looks like the feature was added just a year ago: https://github.com/neomutt/neomutt/pull/734

– tremby – 2019-04-05T18:30:14.367

It works great. I made a macro similar to the one suggested in the docs you posted at https://neomutt.org/guide/mimesupport#5-2-%C2%A0composing-multipart-alternative-emails -- I still have to press enter after using the macro, and I'm not yet sure what will happen if I want to make changes after generating the alternative but before sending, but I'll figure all that out in due course. Note the first version to support multipart/alternative is the 2018-05-12 release, which is not yet in my distro. I compiled from source with --gnutls --prefix/usr/local --tokyocabinet.

– tremby – 2019-04-05T23:27:38.533

-1

    #!/bin/bash

    cp $1 $1.tmp
    ##CHANGE OVERALL TYPE IN HEADER TO MULTIPART

    #HANDLE CONTENT-TYPE LINE IN HEADER
    if grep -q "Content-Type:" $1; then
            sed -i -e 's/Content-Type:.*?;/Content-Type: multipart\/alternative; boundary=boundary42/' $1.tmp
    else
            sed -i '1iContent-Type: multipart/alternative; boundary=boundary42' $1.tmp
    fi

    #EXTRACT HEADER AND BODY
    header="$(sed '/^$/q' $1.tmp)"
    body="$(sed -n -e '/^$/,$p' $1.tmp | tail -n +2)"

    #CREATE HTML VERSION
    HTMLbody="$(echo "$body" | commonmark)"

    #ADD HEADER
    echo "$header" > $1

    #START PLAIN TEXT
    echo -e "\n--boundary42\n" >> $1
    echo -e "Content-Type: text/plain; charset=us-ascii\n" >> $1
    echo "$body" >> $1

    #START HTML
    echo -e "\n--boundary42\n" >> $1
    echo "Content-Type: text/html; charset=UTF-8" >> $1
    echo "Content-Transfer-Encoding: quoted-printable\n" >> $1
    echo "$HTMLbody" >> $1

    echo -e "\n--boundary42--" >> $1

    msmtp $1

Davey

Posted 2016-03-18T19:50:54.307

Reputation: 549

You appear to be answering the question "is it possible to use different signatures per 'from' email address", which is not at all the question I asked. I don't see how this helps with sending multipart/alternative email. – tremby – 2019-04-04T17:19:59.143

I see you've edited your answer. OK so this checks which email addresses you're sending from and to (doesn't look like you do anything with "from") and possibly adds some headers. But I still don't see how this helps with sending multipart/alternative email. – tremby – 2019-04-04T18:57:43.963

You are probably gonna need to adjust this for your own needs, so I probably can't spell out everything for you. But the general solution is that you set your editor to a script that calls on your editor then parses the draft file. – Davey – 2019-04-04T19:08:34.890

Which specific edit to the draft file will allow mutt to send multipart/alternative? Where are the two versions of the file, HTML and plain text? – tremby – 2019-04-04T20:01:04.800

You seem to have a way to convert with commonmark. Replace that with the someMultipartScript line. $1 at that point will be plaintext. Send it through your conversion tool there and pipe it to the same filename $1. When this script terminates, it sends a signal to the calling program (mutt), that your editor is closed, at which point it should be ready to send. – Davey – 2019-04-04T20:29:48.517

That would replace the plain-text original with the HTML version, and we are still not sending as multipart/alternative. I gave steps to achieve the same effect in my question (moreover, without any need of an external script), so this does not help. – tremby – 2019-04-04T21:01:11.900

I didn't see that your method replaced the plaintext completely. This iteration should fix that. – Davey – 2019-04-04T22:00:11.350

It's clear you haven't even attempted to test this. Here it is turned into what I think you intended, with a lot of syntax errors fixed, and some unnecessary logic removed (no need to look at who it's to or from): https://pastebin.com/yqmSMRTb -- but mutt just changes that content type back to text/plain before sending. If you can get mutt to send multipart/alternative I'd love to hear about it.

– tremby – 2019-04-04T22:55:25.900

No I hadn't tested it because I'm not using mutt anymore. Should have mentioned this.

So instead of doing things at the editor level, why not try at the send-mail level? I've updated my post to reflect if you are using msmtp. – Davey – 2019-04-04T23:12:58.030

Wouldn't it then send the mail as soon as you close the editor? Sorry, but I think this answer is a non-starter. I won't respond on this one any more. – tremby – 2019-04-04T23:27:48.373