Отсутствует вложение в сообщении, отправленном с API Gmail, но только для получателя
После использования API Gmail в Javascript для отправки сообщения с текстом HTML и вложением PDF размером ~ 100 КБ вложение правильно отображается в приложении к сообщению в папке Отправленные Gmail отправителя, но не отображается в сообщении для получателя.
Вызов API - это POST
для:
https://www.googleapis.com/upload/gmail/v1/users/me/messages/send?uploadType=media
Тело запроса, отправляемое API:
{
"headers": {
"Authorization": "Bearer authToken-removedForThisPost"
},
"method": "POST",
"contentType": "message/rfc822",
"contentLength": 134044,
"payload": "exampleBelow",
"muteHttpExceptions": true
}
Вот как выглядит полезная нагрузка:
MIME-Version: 1.0
To: =?utf-8?B?TWlrZSBD?=<[email protected]>
CC: =?utf-8?B?TWlrZSBD?=<[email protected]>
BCC: =?utf-8?B??=<[email protected]>
From: =?utf-8?B?TWlrZSBxWXsd2lr?=<[email protected]>
Subject: =?utf-8?B?subjectLine-removedForThisPost?=
Content-Type: multipart/alternative; boundary=__boundary__
--__boundary__
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: base64
base64EncodedStringHere-removedForThisPost
--__boundary__
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: base64
base64EncodedStringHere-removedForThisPost
--__boundary__
Content-Type: application/pdf; name="File Name.pdf"
Content-Disposition: attachment; filename="File Name.pdf"
Content-Transfer-Encoding: base64
base64EncodedStringHere-removedForThisPost
--__boundary__--
Примечание. В документации для загрузки вложений API Gmail указано, что при загрузке простого вложения (до 5 МБ) требуется Content-Length
. Я сделал так, чтобы мой код выдает целочисленное значение общего количества байтов вложения PDF. Однако я заметил, что Content-Length
не включен в полезную нагрузку.
Я попытался изменить тип содержимого multipart/alternative
для сообщения на multipart/mixed
- это сделало так, чтобы вложение в формате PDF было правильно прикреплено к сообщению получателя, но тело сообщения HTML отображалось как обычный текст (теги HTML). показаны), и есть дополнительное вложение noname.html, которое включает в себя HTML-контент, отображаемый как HTML.
Мне нужно сделать так, чтобы электронное письмо в сообщении получателя имело как тело, отображаемое в формате HTML, так и вложение в формате PDF.
Обновление: Я загрузил примеры необработанных сообщений электронной почты здесь. отправленное сообщение находится слева, а полученное сообщение - справа.
Ответы
Ответ 1
Просто замените:
Content-Type: multipart/alternative; boundary=__boundary__
для
Content-Type: multipart/mixed; boundary=__boundary__
Это моя полная функция, написанная в JS
function createMimeMessage_ (msg) {
var nl = "\n"; var border = " ctrlq_dot_org";
var mimeBody = [
"MIME-Version: 1.0",
"To: " + msg.to.email,//+ encode_(msg.to.name) + "<" + msg.to.email + ">",
"Cc: " + msg.cc.email,
"Bcc: " + msg.bcc.email,
"From: " + msg.from.email,//+ encode_(msg.from.name) + "<" + msg.from.email + ">",
"Subject: " + encode_(msg.subject), // takes care of accented characters
"In-Reply-To: " + (msg.reply_to || ""),
"References: " + (msg.reply_to || ""),
"Content-Type: multipart/mixed; boundary=" + boundary + nl,
"--" + boundary,
// "Content-Type: text/plain; charset=UTF-8",
// "Content-Transfer-Encoding: 7bit",
// "Content-Disposition: inline" + nl,
// msg.body.text + nl,
// "--" + boundary,
"Content-Type: text/html; charset=UTF-8",
"Content-Transfer-Encoding: base64" + nl,
new Buffer(msg.body.text).toString('base64') + nl,
];
for (var я = 0; я < msg.files.length; я ++) {
var attachment = [
"--" + boundary,
"Content-Type: " + msg.files[i].mimeType + '; name="' + msg.files[i].fileName + '"',
'Content-Disposition: attachment; filename="' + msg.files[i].fileName + '"',
"Content-Transfer-Encoding: base64" + nl,
msg.files[i].bytes
];
mimeBody.push(attachment.join(nl));
}
mimeBody.push( "-" + border + "-" );//console.log(mimeBody);
return mimeBody.join(nl);
}
Ответ 2
Ваш вопрос состоит из двух частей:
- Как получить вложение для получателя?
- Как включить вложение и HTML-код в виде простого текста?
На это частично ответил разработчик Tiger (multipart/alternative
- multipart/mixed
). Проблема, как вы заметили, заключается в том, что простое выполнение этого не позволит вам получить альтернативный простой текст. Это связано с тем, что вы удаляете multipart/alternative
, роль которого заключается в предоставлении этой альтернативы.
Что вам нужно сделать, это создать вторую границу, а затем сгруппировать простой текст & HTML части вместе. Посмотрите на этот пример, также полученный из CTRLQ, и обратите внимание на altBoundary
, который я включил.
function createMimeMessage_(msg) {
var nl = "\n";
var boundary = "__ctrlq_dot_org__";
var altBoundary = "__alt_ctrlq_dot_org__";
var mimeBody = [
"MIME-Version: 1.0",
"To: " + encode_(msg.to.name) + "<" + msg.to.email + ">",
"From: " + encode_(msg.from.name) + "<" + msg.from.email + ">",
"Subject: " + encode_(msg.subject), // takes care of accented characters
"Content-Type: multipart/mixed; boundary=" + boundary + nl,
"--" + boundary,
"Content-Type: multipart/alternative; boundary=" + altBoundary + nl,
"--" + altBoundary,
"Content-Type: text/plain; charset=UTF-8",
"Content-Transfer-Encoding: base64" + nl,
Utilities.base64Encode(msg.body.text, Utilities.Charset.UTF_8) + nl,
"--" + altBoundary,
"Content-Type: text/html; charset=UTF-8",
"Content-Transfer-Encoding: base64" + nl,
Utilities.base64Encode(msg.body.html, Utilities.Charset.UTF_8) + nl,
"--" + altBoundary + "--"
];
for (var i = 0; i < msg.files.length; i++) {
var attachment = [
"--" + boundary,
"Content-Type: " + msg.files[i].mimeType + '; name="' + msg.files[i].fileName + '"',
'Content-Disposition: attachment; filename="' + msg.files[i].fileName + '"',
"Content-Transfer-Encoding: base64" + nl,
msg.files[i].bytes
];
mimeBody.push(attachment.join(nl));
}
mimeBody.push("--" + boundary + "--");
return mimeBody.join(nl);
}