Отсутствует вложение в сообщении, отправленном с 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

Ваш вопрос состоит из двух частей:

  1. Как получить вложение для получателя?
  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);

}