Programmatically adding a signature to an email - email

I have a requirement to add a signature to emails passing through a specialised proxy server. There doesn't seem to be a very good way to do this, and my initial thoughts are to:
If the mail is non-MIME, or is text/plain, just add text to the bottom of the body,
with a preceding "-- " line (an old convention for adding signatures
to text/plain messages; see RFC3676, 4.3)
If the mail is multipart/mixed, find the last boundary, and insert
a new `multipart/alternative' entity above it, containing plain and
HTML versions of the sig. This has the disadvantage that the sig may
appear below attachments, though.
If the mail is not multipart/mixed, make it multipart-mixed, and
demote the existing entities into the mixed section; now add the
multipart/alternative signature as the last part of the new
multipart/mixed. Same disadvantage as (2).
Seems pretty long-winded. Any ideas on better ways to do this? Thanks.

I coded this as above, and it's fine on Yahoo, gmail, AOL, GMX, and Thunderbird, with the MIME validated here and here.
The problem was that I forgot, again, about Microsoft's complete inability to read an RFC. If a multipart/mixed section contains two multipart/alternative sections, where each one contains a text/plain and a text/html alternative, then Outlook/hotmail actually displays both alternatives in the second multipart/alternative. So, it displays both the plain signature, and the HTML version.
The fix is straightforward - instead of adding a second multipart/alternative for the signatures, I instead add a single text/html section, containing only the HTML signature. This displays correctly on all the MUAs above, including the brain-dead ones. Not exactly ideal, but I could enable the fix only for Microsoft recipients, and let them sort things out if they have persuaded their MUA to display only plain text.

if only interesting in text/html and not in text/plain part, a bit simpler implementation will be to trasform the text/html into multipart/mixed with your html signature.
before
multipart/alternative
text/plain
text/html
after
multipart/alternative
text/plain
multipart/mixed
text/html
text/html <== your signature

Related

MIME multipart emails: how do I persuade Microsoft clients to show two HTML (or even plain) parts?

Executive summary: I can construct a multipart message which contains HTML in two separate parts, and it displays correctly in multiple MUAs. However, outlook.com insists on putting any additional HTML after the first HTML part in a downloadable attachment, instead of displaying it. It also does this for plaintext parts.
In detail: I need to add a signature to an email message, where the structure of the original message is, in general, unknown. I do this by wrapping the original message in a multipart/mixed, and then adding a new multipart/alternative which contains text and html versions of the required signature.
If the original message was itself a multipart/alternative, then the new message now looks like:
multipart/mixed
multipart/alternative [the original message]
text/plain
text/html
multipart/alternative [the appended signature]
text/plain [plaintext signature]
text/html [html signature]
This displays well in various clients (Thunderbird, and webmail from gmail/Yahoo/AOL/gmx), showing the original message with the appended signature. However, it doesn't work for MS clients (I've only tried outlook.com). The two alternative signatures are presented to the user as attachments, and not inline, so the user only sees download boxes.
To get around this, I've historically done this for Microsoft:
multipart/mixed
multipart/alternative [the original message]
text/plain
text/html
text/html [html-only signature]
This worked for several years for Microsoft, but has now stopped working - the signature is again shown as an attachment.
I've spent some hours experimenting with this, and can't find any way to get outlook.com to show two different HMTL (or even plain) text parts in the same message. The second one always appears as an attachment. Some of the things I've tried are:
Replace the second multipart-alternative above with another multipart/mixed, which encloses the multipart-alternative signature
Trying to force Content-Disposition: inline for the signature: this never works, and MS appears to ignore Content-Disposition
Replace the outer multipart/mixed with multipart-related, with type=multipart/alternative
Any ideas on how I can get MS clients to actually show the signature, short of parsing the internals of the original message and re-writing it?

Incomplete attachments remain attached to the mail

I am using mimedefang filtering tool. In the configuration, I strip out all the attachments and forward it to another address. For particular sender, I can see milter changes the header Content-Type from application/pdf and multipart-mixed. In the received email on outlook, when I open the pdf using text editor (it contains content like ("This is a multi-part message in MIME format..." followed by some random numbers "------------=_1525668389-64274-8--").
Can anyone guess why this might be happening?
Multi-part messages (like those with attachments) have their parts divided by a boundary. This boundary is between 1 and 70 characters and must not appear anywhere in the anywhere within the encapsulated parts of the message (between boundaries).
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary=gc0p4Jq0M2Yt08jU534c0p
This is a message with multiple parts in MIME format.
--gc0p4Jq0M2Yt08jU534c0p
Content-Type: text/html; charset=UTF-8
<html><head></head><body>This is the HTML body of the message.</body></html>
--gc0p4Jq0M2Yt08jU534c0p
Content-Type: text/plain
This is the body of the message.
--gc0p4Jq0M2Yt08jU534c0p
Content-Type: application/octet-stream
Content-Transfer-Encoding: base64
PGh0bWw+CiAgPGhlYWQ+CiAgPC9oZWFkPgogIDxib2R5PgogICAgPHA+VGhpcyBpcyB0aGUg
Ym9keSBvZiB0aGUgbWVzc2FnZS48L3A+CiAgPC9ib2R5Pgo8L2h0bWw+Cg==
--gc0p4Jq0M2Yt08jU534c0p--
I suspect that somewhere between mimedefang and your milter configuration, the boundaries are getting mangled or included into the attachment can causing them to be corrupted.

Gmail API - plaintext word wrapping

When sending emails using the Gmail API, it places hard line breaks in the body at around 78 characters per line. A similar question about this can be found here.
How can I make this stop? I simply want to send plaintext emails through the API without line breaks. The current formatting looks terrible, especially on mobile clients (tested on Gmail and iOS Mail apps).
I've tried the following headers:
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
Am I missing anything?
EDIT: As per Mr.Rebot's suggestion, I've also tried this with no luck:
Content-Type: mixed/alternative
EDIT 2: Here's the exact format of the message I'm sending (attempted with and without the quoted-printable header:
From: Example Account <example1#example.com>
To: <example2#example.com>
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
Subject: This is a test!
Date: Tue, 18 Oct 2016 10:46:57 -GMT-07:00
Here is a long test message that will probably cause some words to wrap in strange places.
I take this full message and Base64-encode it, then POST it to /gmail/v1/users/{my_account}/drafts/send?fields=id with the following JSON body:
{
"id": MSG_ID,
"message": {
"raw": BASE64_DATA
}
}
Are you running the content through a quoted printable encoder and sending the encoded content value along with the header or expecting the API to encode it for you?
Per wikipedia it seems like if you add soft line breaks with = less than 76 characters apart as the last character on arbitrary lines, they should get decoded out of the result restoring your original text.
UPDATE
Try sending with this content whose message has been quoted-printable encoded (base64 it):
From: Example Account <example1#example.com>
To: <example2#example.com>
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
Subject: This is a test!
Date: Tue, 18 Oct 2016 10:46:57 -GMT-07:00
Here is a long test message that will probably cause some words to wrap in =
strange places.
I'm assuming you have a function similar to this:
1. def create_message(sender, to, cc, subject, message_body):
2. message = MIMEText(message_body, 'html')
3. message['to'] = to
4. message['from'] = sender
5. message['subject'] = subject
6. message['cc'] = cc
7. return {'raw': base64.urlsafe_b64encode(message.as_string())}
The one trick that finally worked for me, after all the attempts to modify the header values and payload dict (which is a member of the message object), was to set (line 2):
message = MIMEText(message_body, 'html') <-- add the 'html' as the second parameter of the MIMEText object constructor
The default code supplied by Google for their gmail API only tells you how to send plain text emails, but they hide how they're doing that.
ala...
message = MIMEText(message_body)
I had to look up the python class email.mime.text.MIMEText object.
That's where you'll see this definition of the constructor for the MIMEText object:
class email.mime.text.MIMEText(_text[, _subtype[, _charset]])
We want to explicitly pass it a value to the _subtype. In this case, we want to pass: 'html' as the _subtype.
Now, you won't have anymore unexpected word wrapping applied to your messages by Google, or the Python mime.text.MIMEText object
This exact issue made me crazy for a good couple of hours, and no solution I could find made any difference.
So if anyone else ends up frustrated here, I'd thought I'd just post my "solution".
Turn your text (what's going to be the body of the email) into simple HTML. I wrapped every paragraph in a simple <p>, and added line-breaks (<br>) where needed (e.g. my signature).
Then, per Andrew's answer, I attached the message body as MIMEText(message_text, _subtype="html"). The plain-text is still not correct AFAIK, but it works and I don't think there's a single actively used email-client out there that doesn't render HTML anymore.

HTTP Headers to use to specify CSV delimiter and options

I would like my REST service to accept CSV files in addition to JSON and XML.
I would accept an HTTP PUT request such as:
PUT /myservice/user
Content-Type: text/csv; charset=utf-8
"tomas";"1980-01-01"
"george";"1981-02-02"
I would like to be able to accept different delimiters and other format options for my CSV file. Preferably without using the querystring, which doesn't seem to be the proper tool for that. I understand I could just invent my own headers such as:
PUT /myservice/user
Content-Type: text/csv; charset=utf-8
CSV-Delimiter: ,
CSV-Options: merge-duplicates, no-header-row
Or maybe I could invent my own parameters to Content-Type if that is allowed (after all it is a part of the content-type just like the charset used):
PUT /myservice/user
Content-Type: text/csv; charset=utf-8; delimiter=,; options=no-header-row
What would be the proper way to handle this? Are there any HTTP-headers conventionally used for this?
For "no-header-row" a parameter already exists: [header="present"|"absent"].
As for adding new parameters to the content-type header:
New parameters SHOULD NOT be defined as a way to introduce new
functionality in types registered in the standards tree, although new
parameters MAY be added to convey additional information that does
not otherwise change existing functionality. An example of this
would be a "revision" parameter to indicate a revision level of an
external specification such as JPEG. Similar behavior is encouraged
for media types registered in the vendor or personal trees but is not
required.

MIME: multipart in multipart

I am Writing a little Mail parser for a project and to understand mail better.
There came up a question about Multiparts.
When I have a Mail with Content-Type: multipart/alternative oder any other multipart with a divider, will it be possible that in that multipart is anoter multipart (e.g. a multipart/mixed) or the oter way. What divider does that have, has that an own divider?
So is the MIME-Type multipart/* a flat structure (Can be parsed using one splitting divider) or is it a tree (Where each splitted part could be splitted again).
After 3 long nights of programming and intensive testing, I recognized, that multipart/* is NOT flat. It is a tree structure. For example if you have a html and a plaintext part as well as attachments, the mail is multipart/mixed holding the attachments and a multipart/alternative part. If there are also Inline-Images, the HTML-Part could be multipart/related holding the Images and the html.