Including an embedded image in an Outlook HTML email via Perl - perl

I need to generate an HTML email with a banner image embedded. It must go through an Outlook2007 mail client. I tried to base64encode the image and put it inline (it looked good) but Outlook would not send the email. I have culled through many different articles (in various programming languages) that have gotten me to this point but it is still not working. This code creates the email and attaches the image but the image is not displayed.
use Win32::OLE;
use Win32::OLE::Const 'Microsoft Outlook';
my $oMailer = new Win32::OLE('Outlook.Application') or
die "Unable to start an Outlook instance: $!\n";
my $oEmail = $oMailer->CreateItem(0) or
die "Unable to create mail item: $!\n";
$oEmail->{'To'} = 'me#here.org';
$oEmail->{'Subject'} = "Embedded image test";
$oEmail->{'BodyFormat'} = olFormatHTML;
$oEmail->{'HTMLBody'} = "<html><body><img src=\"cid:banner.jpg\"></body></html>";
my $attachments = $oEmail->Attachments();
my $bannerAttachment = $attachments->Add('C:/test/banner.jpg', olEmbeddeditem);
$bannerAttachment->PropertyAccessor->SetProperty(
"http://schemas.microsoft.com/mapi/proptag/0x3712001E", "banner.jpg");
$oEmail->save();
(BTW, I removed all the Win32::OLE->LastError() checks before posting because none of them failed anyway.)
When adding the attachment, it does not set the attachment Type to olEmbeddeditem (5); Don't know if this is relevant to the problem.
The SetProperty does not set the value either. That is supposed to set the Content ID (cid) that is referenced in the img src in the HTML. I used the below code to GetProperty and it returns an empty string.
my $CIDvalue = $bannerAttachment->PropertyAccessor->GetProperty(
"http://schemas.microsoft.com/mapi/proptag/0x3712001E");
print ">>>CIDvalue = $CIDvalue\n";
So close I can taste it!

Careful reading in the Perl docs for WIN32::OLE revealed a SetProperty method that was apparently being called instead of the M$ one I thought I was calling. Changing the code to:
$bannerAttachment->PropertyAccessor->Invoke('SetProperty', "http://schemas.microsoft.com/mapi/proptag/0x3712001E", "banner.jpg");
made it work and there was great rejoicing :)

Related

MailKit - How can bodybuilder help create a complex email body with many images interspersed with text?

For example, what if you need to create an email body like this:
Text ...
Image ...
Text ...
Image ...
Text
Here is one of the examples that works for one text and one image:
var builder = new BodyBuilder ();
var pathImage = Path.Combine (Misc.GetPathOfExecutingAssembly (), "Image.png");
var image = builder.LinkedResources.Add (pathLogoFile);
image.ContentId = MimeUtils.GenerateMessageId ();
builder.HtmlBody = string.Format (#"<p>Hey!</p><img src=""cid:{0}"">", image.ContentId);
message.Body = builder.ToMessageBody ();
Can we do something like builder.HtmlBody += to just keep adding more and more texts and images?
The BodyBuilder class is designed to constructing typically message structures, not the type of thing you are doing.
You will need to construct your message manually, not using BodyBuilder.
After quite a bit of trial/error/testing, I discovered that you can indeed keep adding text and images to the HtmlBody object, as my question speculated, by using builder.HtmlBody +=
In response to the increasingly widespread use of TLS instead of SSL, and therefore the need to abandon the use of Microsoft's obsolete SmtpClient component, I have developed a comprehensive emailing test component, in Visual Basic, using the wonderful MailKit from JStedfast.
As my question suggested, I wanted to give my users the ability to compose a handsome email body using text interspersed with images as needed. If any VB developers would like to benefit from this work, just let me know.
#jstedfast - I just saw your answer after posting this. For my production version, I need to add images from a blob field in a SQLServer table. I intend to use the manual method, as you stated, to do that. But for images I was loading into my sample program, I was able to make a fairly complex email body using src=file for each image, and adding them with builder.HtmlBody +=

Use Google Scripts to Attach PDF to email

I am trying to have google Scripts send a PDF as an attachment to an email. I have a doc template that uses form data that is copied and then filled out. The code works, but the program keeps sending the template as a pdf and not the filled out copy. Can anyone help me with this?
Here is some of my code:
newDoc = autoWriteNewIEPForm(templateDocId, newDocName, fieldArray, NewEntryArray, submitTeacherName);
newDocId = newDoc.getId();
newDocURL = newDoc.getUrl();
var sender = newEntryArray[0][3];
var subSubject = newDocName;
var subEmailBody = "Thank you for submitting this information. This receipt confirms that we have received your information." + "<br><br>";
var file = DriveApp.getFileById(newDocId).getAs(MimeType.PDF);
MailApp.sendEmail(sender, subSubject, "", {cc:emailCC, htmlBody:subEmailBody, attachments:[file], name: newDocName});
Well the last line of your code is correctly attaching the newDoc as an attachment. The first line confuses me a bit; autoWriteNewIEPForm is not a Google scripts function, and I don't know where you're getting it from or if you're using it correctly. My guess is that you're using it incorrectly, or that for some reason it's not editing any of the text in the newDoc, so you have a document that is technically a copy of the template but looks exactly the same.
In the Body class of the Google Scripts DocumentApp you can find a number of methods for editing text in a document's body. I suggest you use one of those instead.

Adobe Reader cannot open .pdf file created using mPDF in Zend Framework

I'm trying to generate a .pdf file using mPDF in a Zend Framework application, from the output of the action.
Here is the code of my action:
public function testAction()
{
$this->_helper->viewRenderer->setNoRender();
$this->_helper->layout->disableLayout();
$this->view->foo = 'bar';
$this->render();
$output = $this->getResponse()->getBody();
$layout = new Zend_Layout();
$layout->content = $output;
$layout->setLayoutPath(dirname(dirname(__FILE__)) . '/views/layouts/');
$layout->setViewSuffix('tpl');
$layout->setLayout('pdf');
$html = $layout->render();
$mpdf = new mPDF('utf-8', 'A4');
$mpdf->WriteHTML($html);
$mpdf->Output('report.pdf', 'D');
}
If the content to be displayed is long (i.e. a few paragraphs), when downloading the .pdf file, Adobe Reader throws the following error: Adobe Reader could not open 'report.pdf' because it is either not a supported file type or because the file has been damaged (for example, it was sent as an email attachment and wasn't correctly decoded).
However, if I pass the same output to mpdf as a static variable, without using Zend Layout render, then the .pdf file opens without any errors. Also, Adobe Reader throws the issue if and only if the content is long (i.e. it works if there are only a couple of words).
Is there any limit I should be aware of?
there should not be space at beginning and at the end of file so check these space,
Adobe Reader is less forgiving than some othe PDF readers if the PDF file is corrupt. Open your PDF document in a text editor and check that the file starts with something like:
%PDF-1.4
%âãÃÓ
Sometimes PHP error notices are found at the top of the file.
Source : mpdf forum IanBack's answer

Prevent Gmail from creating links for URLs and email addresses

Problem is Gmail automatically creates hyperlinks for all website URLs and email addresses. I do not want to create a link.
var mailClient = new SmtpClient();
var netMail = new MailMessage();
msg = "I do not want www.google.com as a link at recipient end. <br/>";
msg += "I want my email addrress myemail#myudomain.com as html without a link";
var cr = new NetworkCredential("########", "###########");
netMail.From = new MailAddress("#########m####.###", "######");
netMail.To.Add(new MailAddress("abc#xyz.com"));
netMail.Subject = "Test Mail";
netMail.IsBodyHtml = true;
netMail.Body = msg;
mailClient.Host = "xyz.com";
mailClient.Port = 25;
mailClient.EnableSsl = false;
mailClient.Credentials = cr;
mailClient.Send(netMail);
Any solution?
I had a same issue and found out if you use email like this;
<a rel="nofollow" style='text-decoration:none; color:#333'>test#mydomain.com</a>
email providers does not tend to follow email as a link.
Hope this helps.
There's no way to stop creating URLs, because its automatically checked by the email provider that whether the text is a valid URL.
Only way to overcome this is, deceiving the parser. Just put spaces, HTML tags, whatever in such a way that the parser can't identify like URL etc.
Here are a few code examples:
http:<span>//foolishedsiteparser.com</span>
_http://www.parsersmashed.com
noonesemail<x>#</x>linkdead.com>
And the result is the following:
http://foolishedsiteparser.com
_http://www.parsersmashed.com
noonesemail#linkdead.com
I was able to get around this issue just by adding <a style="color: #000000">link text</a> (notice there is no href).
I haven't tried using attributes besides style but I would imagine you could. The email system that I use (Blackbaud NetCommunity) will strip out a plain <a> tag, so I had to have at least one attribute.
Taking a cue from perilbrain's answer, I implemented the following regex that I use for this:
var unlink = function (val) {
return val.replace(/([#\.:])/g, '<span>$1</span>');
};
Note that this function replaces globally on whatever is passed in -- it would probably be too aggressive for blocks of natural text as in the OP's example, but often templates are parameterized and this works great when you can just pass it a url or email (I actually implemented it as a template helper function so that it does exactly that).
The function converts the following inputs:
john.doe#gmail.com
http://johndoe.com
into this:
john<span>.</span>doe<span>#</span>gmail<span>.</span>com
http<span>:</span>//johndoe<span>.</span>com
Note that I tried a fake short tag like <x> as shown in the accepted answer and found that GMail "intelligently" replaced it with <u> tags, which I assume is a feature, but was not desirable. In my testing, <span> tags prevent linking with no visual side-effects.
None of the solutions listed here seem to work any more. I experimented a little with the idea of non-printable Unicode characters and found this sequence to work:
<span>foo‌.‌bar‌.‌com</span>
Where ‌ is the ZERO WIDTH NON-JOINER character.
Nailed it!
This does not prevent emails from being turned into links, but it allows you to set the font color and remove the underline of that link.
It works in all email clients I tested in on litmus.com - including Outlook 2010, 2013, 2016 (also on Windows), Outlook.com, iPhone 6s, iPad, gmail web interface and Apple Mail 8, 9
Variation 1:
A link which does not react when clicked upon
bjorn#rosell.dk
Variation 2:
A mailto-link. Works in almost all clients. Outlook.com does however style it blue and with underline.
bjorn#rosell.dk
I have one unmentioned solution for textual emails: Use similar unicode characters. For example one dot leader (U+2024) instead of dot. Compare, how looks Běhej.com and Běhej․com (the first one is with regular dot).
I had a dot com in the title of my confirmation message.
Inspired by #perilbrain, I revolved my problem like this
domain.com => domain<span>.</span>
php
$titre = str_replace(".", "<span>.</span>", $titre);
simple !
For now simple wrapping by <span> is not working, I suggest replace # by its html-entity alternative
function disable_email_link($email) {
//encoder https://mothereff.in/html-entities
$email = str_replace('#', '#', $email);
$email = str_replace('.', '<span>.</span>', $email);
return $email;
}
Also if your email contains phone numbers you can escape it by disable_tel_link function:
function wrap_span_letters($string) {
$res = "";
$length = strlen($string);
for ($i = 0; $i < $length; $i++) {
$res .= "<span>$string[$i]</span>";
}
return $res;
}
function disable_tel_link($phone) {
return wrap_span_letters($phone);
}
Eventhough this is a old thread i want to help people who might get here. I found that adding a span inside the link makes google not see it as a link see below:
www.<span></span>link.dk
i had the same problem so after few mins found out how to fix it.
the thing is if you target the element directly it won't work because gmail will automatically add aa "a" tag in there so you have to go one step farther and declare a class for that "a" tag. in my case the email was in a "" tag which i found it easier to work with. so what i did was create a class like this:
.email_contact a {color:#ffffff!important; text-decoration: none!important;}
there is no "a" tag in my code but since gmail will add it automatically then you should catch it there. now you just have to use that class where ever you put your email add such as "span" or "div" and boom! fixed.
While not the ideal solution, it may be an option for some. As of 3/12/2020, If you disable Multipart and send plain text only emails, you'll get the following hyperlinked results. Results appear to be the same whether at the beginning of a new line/sentence or mid sentence.
Suppose your display url is "abcdUrl.com"
To prevent gmail from showing as a link, wrap it in an anchor tag
<a href="" style="text-decoration:none;color:#333;">
abcdUrl.com
</a>
This works well in gmail.

How do I include images into Outlook 2007 MailItem using perl?

I have this code and a bunch of images in a folder.
use Win32::OLE;
use Win32::OLE qw(in with);
use Win32::OLE::Variant;
use Win32::OLE::Const 'Microsoft Outlook';
%mail_props = ('subject' => 'subject','to' => 'to','body' => 'body',);
my $outlook = Win32::OLE->GetActiveObject('Outlook.Application');
# Create Mail Item
my $item = $outlook->CreateItem(0); # 0 = mail item.
unless ($item){die "Outlook is not running, cannot send mail.\n";}
$item->{'Subject'} = $mail_props{'subject'} || '[No Subject]';
$item->{'To'} = join(";", split(/[ ,;]+/, $mail_props{'to'}));
$item->{'Body'} = $mail_props{'body'} || "\r\n";
$item->{'From'} = $mail_props{'from'} if (exists $mail_props{'from'});
$item->Display();
print "Done!\n";
Does anyone know a way to add images to the body of the email generated using above code using OLE methods? I am working with Outlook 2007 and need a code equivalent for inserting tables and pictures.
Appreciate all your help...
Are the tables separate objects or just inlined HTML? Lookout (sorry Outlook) can actually handle inlined uuencode'd objects within the body: basically just insert the uuencoded image in the body and Outlook will parse and show as an attachment. If the OLE doesn't allow for setting MIME boundaries in the mail message, you might try the uuencode approach.