How can I distinguish between attachment types in exchangelib? - email

I've just noticed that Microsoft OWA does not display some attachments. Some people use images in their footer (which are attachments). I'm not sure if the only difference between a "normal" attachment and this emedded attachment is that it is embedded in the email.
Is there another difference? How can I get only attachments which OWA* displays as attachements?
* and probably most other email clients; I think I've seen a similar behavior in Google Mail

Those attachments have a content_id. They are referenced within the mail.body as cid:[CONTENT-ID]. The content_id looks like this:
cid:image001.jpg#01D3151A.F9036A80
where image001.jpg is the filename.

looking for cid:image_name inside mail body fails for embedded images with src referring to a link rather than cid.
so the best solution would be to use attachments.is_inline property which is built in exchangelib.
for attachment in msg.attachments:
if msg.has_attachments == True:
if isinstance(attachment, FileAttachment):
if attachment.is_inline:
print("Embeded Image")
else:
print("Normal Attachment")
reference: https://github.com/ecederstrand/exchangelib/issues/562

Related

Can inline images be referenced from a different message in a thread?

My research through the RFC says that you can reference inline content from other mail parts using the cid: token. I also know that you can use the mid: token in a similar for message-ID. When referencing a message-ID, you can reference mail parts of another message by doing mid:messageId/contentId, contentId being a valid contentId in the target message.
I'm leaning towards no, inline images (or other inline content) can't be referenced and displayed in entirely different messages. But if that's true, I can't piece together what the purpose of using mid: is.
A simple visualization of what I'm imagining is this:
Given a multipart message with an html body and inline image... our cid reference would look like:
<img src="cid:abcd-i-am-a-content-id">
This assumes we do in fact have a multipart/related with a mail part that has some valid image payload with a matching content-ID.
What if we were replying to this original message, can I do something like:
<img src="mid:original-message-id/abcd-i-am-a-content-id"> to inline this resource that would presumably be accessible by the client's mail store that belongs to the recipient assuming all other normal threading rules are followed?
No, there's no way to do that and expect it to work.
Even "mid:" won't work in most clients.

change recipient / attach a file to a sent email in outlook

I've been trying to test something out, basically looking to do one of the following things:
Change name of recipient in a sent file. I've tried using Outlook Spy (great tool) but every time I changed the recipient in PR_DISPLAY_TO_W it returned the following error:
Could not edit the property: HrSetOneProp returned MAPL_E_COMPUTED
Attaching a file to a sent email file. (I don't know if this one is possible, but would be useful if it was.)
I appreciate any responses.
PR_DISPLAY_TO / CC / BCC are computed properties. The store provider updates them whenever recipients list is modified.
Use the MailItem.Recipients collection to modify the recipients.
MailItem.Attachments.Add.

Sending email with attachment

I've a custom form (created with form API) that need send an uploaded file by email. The current form submit handler sends the email without attachment using drupal_mail().
So I'm looking for a solution to properly send email with attachment from Drupal. Mime Mail seems an overkill because HTML mail, templating and its other features are not required. But the only other alternative I see is to set the appropriate headers and serialize the attached file in the mail body when processing the mail in my hook_mail() implementation.
Did I miss anything? Is there any module to handle this?
Mimemail is the easiest solution here. Be it an overkill or not, it will allow you to get it done with a single function call.
If you insist, you may have your homemade attachment sender: base64 encode your attachment(s), add them to the mail body, add the correct headers and you're done.
You can use mime mail and force the message body to be sent in plaintext format. Here is an excerpt from the module's readme file:
USAGE
This module may be required by other modules, but is not terribly
useful by itself. Once installed, any module can send messages by
calling the mimemail() function:
$sender - a user object, text email address or an array with name, mail
$recipient - a user object, text email address or an array with name, mail
$subject - subject line
$body - body text in HTML format
$plaintext - boolean, whether to send messages in plaintext-only (default FALSE)
$headers - a keyed array with headers (optional)
$text - plaintext portion of a multipart e-mail (optional)
$attachments - array of arrays with the file's path, MIME type (optional)
$mailkey - message identifier
return - an array containing the MIME encoded message
The key thing being to set the $plaintext argument to TRUE. Now you can have your cake and eat it too.
You could always have a look at the Swift Mailer module which lets you send HTML (MIME) e-mails, e-mails with inline images and e-mails with attachments. It is also cabable of automatically generating plain text versions based on the HTML e-mail version, which in the end will let the user's e-mail client display the preferred version (HTML or plain text).
The Swift Mailer module is available on http://drupal.org/project/swiftmailer.
For the record : I'm the author and maintainer of the module.
The Webform module allows you to create a form and has a file option which can be used as an attachment. All available form components are listed on the module's manual page.
Once installed Webform will appear as a content type. Once you have saved the fundamentals, such as the title and the email to address, you will have the ability to add the required form components.
Add a component of type 'file', ensuring the 'email' (to recipient) option is ticked, and you will then be able to customize the permitted file types, extensions, sizes and upload folder.
You could use the Zend Framework.
function sendEmail($params){
ini_set('include_path', 'inc/');
require_once ('inc/Zend/Mail.php');
$mail = new Zend_Mail();
$mail->setSubject( $params['subject'] );
$mail->setBodyText( $params['bodyText'] );
$mail->setBodyHtml( $params['bodyHtml'] );
$mail->setFrom( $params['fromEmail'], $params['fromName'] );
$mail->addTo( $params['toEmail'], $params['toName'] );
// Finally, add an attachment
assert( file_exists($params['attachFile']) );
$at = $mail->addAttachment(file_get_contents($params['attachFile']));
$at->type = $params['attachType'];
$at->disposition = Zend_Mime::DISPOSITION_ATTACHMENT;
$at->filename = $params['attachName'];
$mail->send();
}

Parse and display MIME multipart email on website

I have a raw email, (MIME multipart), and I want to display this on a website (e.g. in an iframe, with tabs for the HTML part and the plain text part, etc.). Are there any CPAN modules or Template::Toolkit plugins that I can use to help me achieve this?
At the moment, it's looking like I'll have to parse the message with Email::MIME, then iterate over all the parts, and write a handler for all the different mime types.
It's a long shot, but I'm wondering if anyone has done all this already? It's going to be a long and error prone process writing handlers if I attempt it myself.
Thanks for any help.
I actually just dealt with this problem just a few months ago. I added an email feature to the product I work for, both sending and receiving. The first part was sending reminders to users, but we didn't want to manage the bounce backs for our customer admins, we decided to have a message inbox that the admins could see bounces and replies without us, and the admins can deal with adjusting email addresses if they needed to.
Because of this, we accept all email that is sent to an inbox we watch. We use VERP to associate an email with a user, and store the entire email as is in the database. Then, when the admin requests to see the email, we have to parse the email.
My first attempt was very similar to an earlier answer. If one of the parts is html, show it. If it's text, show it. Otherwise, show the original, raw email. This broke down real fast with a few emails not generated by sendmail. Outlook, Exchange, and a few other email systems don't do that, they use multiparts to send the email. After a lot of digging and cussing, I discovered that the problem doesn't appear to be well documented. With the help of looking through MHonArc and reading the RFC's (RFC2045 and RFC2046), I settled on the solution below. I decided on not using MHonArc, since I couldn't easily resuse the parsing and display functionality. I wouldn't say this is perfect, but it's been good enough that we used it.
First, take the message and use Email::MIME to parse it. Then call a function called get_part with the array of parts Email::MIME gives you with ->parts().
get_part, for each part it was passed, decodes the content type, looks it up in a hash, and if it exists, call the function associated with that content type. If the decoder was able to give us something, put it on a result array.
The last piece of the puzzle is this decoder array. Basically, it defines the content types I can deal with:
text/html
text/plain
message/delivery-status, which is actually also plain text
multipart/mixed
multipart/related
multipart/alternative
The non-multipart sections I return as is. With mixed, related and alternative, I merely call get_parts on that MIME node and returns the results. Because alternative is special, it has some extra code after calling get_parts. It will only return html if it has an html part, or it will return only the text part of it has a text part. If it has neither, it won't return anything valid.
The advantage with the hash of valid content types is that I can easily add logic for more parts as needed. And by the time you get_parts is done, you should have an array of all content you care about.
One more item I should mention. As a part of this, we created a separate domain that actually serves these messages. The main domain that an admin works on will refuse to serve the message and redirect the browser to our user content domain. This second domain will only serve user content. This is to help the browser properly sandbox the content away from our main domain. See same origin policy (http://en.wikipedia.org/wiki/Same_origin_policy)
It doesn't sound like a difficult job to me:
use Email::MIME;
my $parsed = Email::MIME->new($message);
my #parts = $parsed->parts; # These will be Email::MIME objects, too.
print <<EOF;
<html><head><title>!</title></head><body>
EOF
for my $part (#parts) {
my $content_type = $parsed->content_type;
if ($content_type eq "text/plain") {
print "<pre>", $part->body (), "</pre>\n";
}
elsif ($content_type eq "text/html") {
print $part->body ();
}
# Handle some more cases here
}
print <<EOF;
</body></html>
EOF
Reuse existing complete software. The MHonArc mail-to-HTML converter has excellent MIME support.

parsing email message

Just want a basic understand of what parts a email message may have.
I know there is a messageId, date, subject, from, cc, bcc, body, etc.
Specifically I want to know how attachments and images may be embedded in the email.
At this point I think there are 2, please correct me if I am wrong.
attachments
embedded attachments/images
is that correct?
The official answer for this question is contained in RFC5322 and some related RFC's. The Wikipedia entry for email does a pretty good job of referencing the RFC numbers. To get started with MIME see RFC2045.
Attachments are encoded as multipart similar to multipart file uploads. Basically the message has a header saying there is an attachment and sets a boundary ( random string of characters to announce the start of the attachment) The boundary says when the data of the attachment starts. I think the filename is set on the boundary as well (if i remember correctly). I am doing a bit of hand waving, but this is the basic idea.
so you get somthing like
To: ...
From: ...
Content-Type: Multpart...
Content-Boundry: ewafoiuasfjasdfoashiafhj
message here
--------- Content-boundry: ewafoiuasfjasdfoashiafhj
attachement here