Используйте Javascript для создания электронной почты в формате HTML в Microsoft Outlook
Я хотел бы создать электронное письмо из веб-приложения Javascript. Я полностью в курсе многих вопросов SO по этому вопросу (например, Open Outlook HTML с Chrome). Есть проблемы с типичными ответами:
Mailto: ссылка: Это позволит вам создать электронное письмо, но только в виде обычного текста (без HTML), и в нем не будет вложений.
Activex: только IE, мое приложение должно работать в Firefox и Chrome тоже. Плагины FF и Chrome, позволяющие использовать ActiveX, представляют собой угрозу безопасности и, похоже, содержат ошибки.
Отправка на стороне сервера через SMTP: электронная почта не попадает в папку "Отправленные" для пользователя. Плюс препятствия, позволяющие пользователю редактировать HTML в браузере и прикреплять файлы.
Создайте файл Outlook .MSG: кажется, нет никаких библиотек и мало написано об этом. Очевидно, формат файла имеет встроенную систему хранения файлов FAT.
Ключевые различия между многими другими вопросами SO и моими:
- У меня есть доступ к клиентским машинам, поэтому я могу устанавливать вспомогательные приложения или надстройки, изменять настройки по мере необходимости и т. Д.
- Интерфейс не должен на самом деле отправлять почту, он только должен настроить его для пользователя.
- Мне также нужно иметь возможность предоставить электронное письмо от JS (например, PDF).
Я не могу быть первым разработчиком веб-приложения, столкнувшимся с этим, и все же я не могу найти решение ни коммерческого, ни открытого источника.
Обновить:
Я использовал метод файла EML, и пока он работает хорошо. Вот мой JS-код для его создания и запуска:
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
6 ответов
Формат файла MSG задокументирован, но это определенно неинтересно... Почему бы не создать файл EML (MIME)?
Для тех, кто хочет удалить или понизить этот ответ: предлагаем использовать формат EML (MIME). Согласно ОП, он рассматривал формат файла MSG (#4), но не одобрялся из-за сложности или отсутствия библиотек JS, которые обрабатывают этот формат. Если рассматривать файл MSG, MIME - гораздо лучший выбор - он основан на тексте, поэтому для его создания не требуется никаких специальных библиотек. Outlook сможет открыть его так же легко, как файл MSG. Чтобы убедиться, что Outlook обрабатывает его как неотправленное сообщение, установите X-Unsent
MIME заголовок до 1.
ОБНОВЛЕНИЕ: самый простой файл EML будет выглядеть следующим образом:
To: Joe The User <joe@domain.demo>
Subject: Test EML message
X-Unsent: 1
Content-Type: text/html
<html>
<body>
Test message with <b>bold</b> text.
</body>
</html>
Используя идею простых текстовых файлов eml, я придумал это: http://jsfiddle.net/CalvT/un3hapej/
Это редактирование чего-то, что я нашел - создать .txt
затем загрузите файл. Как .eml
практически файлы.txt, я подумал, что это будет работать. И это так. Я покинул textarea
с образцом электронной почты, так что вы можете легко проверить. Когда вы нажимаете кнопку "Создать файл", она дает вам ссылку для загрузки .eml
файл. Единственное препятствие, которое я вижу, - это заставить браузер открывать .eml
файл после того, как он был загружен.
РЕДАКТИРОВАТЬ: И, думая об этом, так как у вас есть доступ к клиентским компьютерам, вы можете настроить браузер, чтобы всегда открывать файлы этого типа. Например, в Chrome, вы можете нажать на стрелку рядом с загрузкой и выбрать всегда открытые файлы этого типа.
Вот код
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 <user@domain.demo>
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>
Никто, кажется, не ответил на вопрос о вложении, поэтому вот мое решение: создать EML как составное / смешанное сообщение.
Content-Type: multipart/mixed; boundary=--boundary_text_string
С этим вы можете иметь несколько частей в вашей электронной почте. Несколько частей позволяют добавлять вложения, как это.
Content-Type: application/octet-stream; name=demo.pdf
Content-Transfer-Encoding: base64
Content-Disposition: attachment
Начните с заголовков электронной почты, затем добавьте свою границу, а затем содержимое детали (расположение новой строки очень важно, в противном случае клиенты не смогут правильно проанализировать ваш файл). Вы можете добавить несколько частей. Ниже приведен пример. Обратите внимание, что последняя граница отличается от других (2 черточки в конце).
To: Demo-Recipient <demo@demo.example.com>
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--
Это дает вам файл eml с двумя вложениями. См. RFC 1371, если вы хотите узнать больше о том, как это работает.
У меня возникла проблема с кодировкой при создании файла.eml с неанглийскими символами и последующем его открытии в Outlook. Проблема заключалась в том, что я поместил "charset=" не в то место и не заключил кодировку в кавычки ("). Решение:
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();
}
Изменить: оказывается, кавычки (") даже не нужны. Только размещение было неправильным для меня.
JS-библиотеки для упрощения жизни (не нужно изобретать велосипед):
- составить EML-файл:
nodemailer/lib/mail-composer
- разобрать EML-файл:
mailparser
- проанализировать файл MSG:
@kenjiuno/msgreader
После попытки ответа korhojoa он не работает и требует некоторых корректировок:
To: Demo-Recipient <demo@demo.example.com>
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--