'Use Javascript to create an HTML email in Microsoft Outlook
I'd like to create an email from a Javascript web application. I'm completely aware of the many SO questions on this (e.g. Open Outlook HTML with Chrome). There are problems with the typical answers:
Mailto: link: This will let you create an email, but only in plain text (no HTML) and it does not allow for attachments.
Activex: IE only, my application needs to run in Firefox and Chrome too. FF & Chrome plug-ins to allow ActiveX are security hazards and seem to be buggy.
Server-side sends via SMTP: The email does not end up in the "Sent" folder for the user. Plus hurdles letting the user edit HTML in the browser and attach files.
Create an Outlook .MSG file: There seem to be no libraries and little written about doing this. Apparently the file format actually has an entire FAT file storage system embedded.
Key differences between many other SO questions and mine:
- I do have access to the client machines, so I could install helper applications or add-ins, change settings as needed, etc.
- The interface does not need to actually send the mail, it only needs to set it up for the user.
- I also need to be able to give the email an attachment from JS (e.g. a PDF).
I cannot be the first web app developer to face this and yet I'm unable to find a solution either commercial or open source.
Update:
I used the EML file method and it works well so far. Here's my JS code to create and trigger it:
var emlContent = "data:message/rfc822 eml;charset=utf-8,";
emlContent += 'To: '+emailTo+'\n';
emlContent += 'Subject: '+emailSubject+'\n';
emlContent += 'X-Unsent: 1'+'\n';
emlContent += 'Content-Type: text/html'+'\n';
emlContent += ''+'\n';
emlContent += htmlDocument;
var encodedUri = encodeURI(emlContent); //encode spaces etc like a url
var a = document.createElement('a'); //make a link in document
var linkText = document.createTextNode("fileLink");
a.appendChild(linkText);
a.href = encodedUri;
a.id = 'fileLink';
a.download = 'filename.eml';
a.style = "display:none;"; //hidden link
document.body.appendChild(a);
document.getElementById('fileLink').click(); //click the link
Solution 1:[1]
Using the idea of plain text eml files, I came up with this: http://jsfiddle.net/CalvT/un3hapej/
This is an edit of something I found - to create a .txt file then download it. As .eml files are practically .txt files, I figured this would work. And it does. I've left the textarea with the sample email in so you can easily test. When you click on create file, it then gives you a download link to download your .eml file. The only hurdle I can see is making the browser open the .eml file after it has been downloaded.
EDIT: And thinking about it, as you have access to the client machines, you could set the browser to always open files of that type. For instance in Chrome, you can click on the arrow beside the download and select always open files of this type.
Here's the code
HTML:
(function () {
var textFile = null,
makeTextFile = function (text) {
var data = new Blob([text], {type: 'text/plain'});
if (textFile !== null) {
window.URL.revokeObjectURL(textFile);
}
textFile = window.URL.createObjectURL(data);
return textFile;
};
var create = document.getElementById('create'),
textbox = document.getElementById('textbox');
create.addEventListener('click', function () {
var link = document.getElementById('downloadlink');
link.href = makeTextFile(textbox.value);
link.style.display = 'block';
}, false);
})();
<textarea id="textbox" style="width: 300px; height: 200px;">
To: User <[email protected]>
Subject: Subject
X-Unsent: 1
Content-Type: text/html
<html>
<body>
Test message
</body>
</html>
</textarea>
<button id="create">Create file</button>
<a download="message.eml" id="downloadlink" style="display: none">Download</a>
Solution 2:[2]
Nobody seems to have answered the attachment question, so here's my solution: create the EML as a multipart/mixed message.
Content-Type: multipart/mixed; boundary=--boundary_text_string
With this, you can have multiple parts in your email. Multiple parts let you add attachments, like this.
Content-Type: application/octet-stream; name=demo.pdf
Content-Transfer-Encoding: base64
Content-Disposition: attachment
Start with your email headers, then add your boundary, then the part contents (newline locations are very important, clients won't parse your file correctly otherwise). You can add multiple parts. Below is an example. Note that the last boundary is different from the others (2 dashes at the end).
To: Demo-Recipient <[email protected]>
Subject: EML with attachments
X-Unsent: 1
Content-Type: multipart/mixed; boundary=--boundary_text_string
----boundary_text_string
Content-Type: text/html; charset=UTF-8
<html>
<body>
<p>Example</p>
</body>
</html>
----boundary_text_string
Content-Type: application/octet-stream; name=demo.txt
Content-Transfer-Encoding: base64
Content-Disposition: attachment
ZXhhbXBsZQ==
----boundary_text_string
Content-Type: application/octet-stream; name=demo.log
Content-Transfer-Encoding: base64
Content-Disposition: attachment
ZXhhbXBsZQ==
----boundary_text_string--
This gives you a eml file with two attachments. See RFC 1371 if you want to know more specifics on how this works.
Solution 3:[3]
I had encoding problem when creating an .eml file with non-english characters and then opening it in Outlook. The problem was that I put the "charset=" to the wrong place and did not put the quotes (") around the encoding. The solution:
function createShiftReportEmail() {
const title = "Shift Összefoglaló";
const body = "ÁÉ?Ú?ÓÜÖÍ?áéú?óöí";
const emlContent = new Blob([`data:message/rfc822 eml,\nSubject: ${title}\nX-Unsent: 1\nContent-Type: text/plain;charset="utf-8"\n\n${body}`]);
if (!document.querySelector('#downloadEmail')) {
document.body.insertAdjacentHTML('beforeend', '<a id="downloadEmail" download="ShiftReport.eml" style="display: none">Download</a>');
}
const downloadBtn = document.querySelector('#downloadEmail');
downloadBtn.href = URL.createObjectURL(emlContent);
downloadBtn.click();
}
Edit: Turns out quotes (") are not even necessary. Only the placement was wrong for me.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | korhojoa |
| Solution 3 |
