Электронная почта с вложением не работает должным образом с Gmail API - PullRequest
0 голосов
/ 21 декабря 2018

Это следующий фрагмент кода, который я написал в node.js для отправки электронной почты с вложением с помощью API gmail:

И я использую модуль запроса-обещания узла js для отправки запроса к этому API.

let user = await db.model('User').findOne({ _id: userId });
    let filepath = fs.readFileSync(req.file.path).toString('base64');
    // let filepath = fs.readFileSync(req.file.path);
    let from = user.crmOptions.email;
    let raw = [
      'Content-Type: multipart/mixed; boundary="boundary_mail"\r\n',
      'MIME-Version: 1.0\r\n',
      "to: ", req.body.to, "\n",
      "from: ", from, "\n",
      "cc: ", req.body.cc ? req.body.cc : '', "\n",
      "bcc: ", req.body.bcc ? req.body.bcc : '', "\n",
      "subject: ", req.body.subject, "\n\n",

      '--boundary_mail\r\n',
      "Content-Type: text/html; charset=\"UTF-8\"\n",
      'MIME-Version: 1.0\r\n',
      req.body.message,

      '--boundary_mail\r\n',
      `Content-Type: ${req.file.mimetype}\r\n`,
      'MIME-Version: 1.0\r\n',
      `Content-Disposition: attachment; filename="${req.file.filename}"\r\n\r\n`,

      filepath, '\r\n\r\n',

      '--boundary_mail--'
    ].join('');
    const id = 'me';
    let options = {
      url: "https://www.googleapis.com/upload/gmail/v1/users/" + id + "/messages/send?uploadType=multipart",
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${user.crmOptions.access_token}`,
        'Content-Type': 'message/rfc822'
      },
      body: raw
    };


await request(options).then(async body => {
  console.log("Body: ", body);
}).catch(err => {
  console.log("Error: ", err);
})

После отправки почты содержимое почты выглядит следующим образом

enter image description here

1 Ответ

0 голосов
/ 22 декабря 2018

При отправке html-почты и вложенного файла используются multipart/mixed и multipart/alternative.Структура тела запроса выглядит следующим образом.

  • многочастное / смешанное
    • многочастное / альтернативное
      • HTML-сообщение
    • Файл вложения

В то время в теле запроса используются 2 границы.

Модифицированный скрипт:

Пожалуйста, измените raw

let raw = [
  'MIME-Version: 1.0\n',
  "to: ", req.body.to, "\n",
  "from: ", from, "\n",
  "cc: ", req.body.cc ? req.body.cc : '', "\n",
  "bcc: ", req.body.bcc ? req.body.bcc : '', "\n",
  "subject: ", req.body.subject, "\n",
  "Content-Type: multipart/mixed; boundary=boundary_mail1\n\n",

  "--boundary_mail1\n",
  "Content-Type: multipart/alternative; boundary=boundary_mail2\n\n",

  "--boundary_mail2\n",
  "Content-Type: text/html; charset=UTF-8\n",
  "Content-Transfer-Encoding: quoted-printable\n\n",
  req.body.message, "\n\n",
  "--boundary_mail2--\n",

  '--boundary_mail1\n',
  `Content-Type: ${req.file.mimetype}\n`,
  `Content-Disposition: attachment; filename="${req.file.filename}"\n`,
  "Content-Transfer-Encoding: base64\n\n",

  filepath, '\n',
  '--boundary_mail1--',
].join('');

Примечание:

  • В этом измененном сценарии предполагается, что ваш текущий сценарий может отправлять электронную почту с помощью Gmail API.

Список литературы:

Редактировать:

Например, когда 2 файла вложений включены втело запроса измените с --boundary_mail1 на --boundary_mail1-- следующим образом.Пожалуйста, будьте осторожны, если нет повторяющихся имен файлов.

От:

'--boundary_mail1\n',
`Content-Type: ${req.file.mimetype}\n`,
`Content-Disposition: attachment; filename="${req.file.filename}"\n`,
"Content-Transfer-Encoding: base64\n\n",

filepath, '\n',
'--boundary_mail1--',

До:

'--boundary_mail1\n',
`Content-Type: mimetype\n`, // mimetype
`Content-Disposition: attachment; filename="### filename1 ###"\n`, // filename1
"Content-Transfer-Encoding: base64\n\n",

filepath1, '\n', // filepath1
'--boundary_mail1\n',
`Content-Type: mimetype\n`, // mimetype
`Content-Disposition: attachment; filename="### filename2 ###"\n`, // filename2
"Content-Transfer-Encoding: base64\n\n",

filepath2, '\n', // filepath2
'--boundary_mail1--',
...