Экспортируйте Google Do c в формате PDF и отправляйте с Nodemailer в качестве вложения. - PullRequest
0 голосов
/ 12 апреля 2020

Итак, продолжайте стучать тупой головой о стену. Попытка создать функцию Firebase для извлечения google do c в формате PDF с помощью API диска (v.3), а затем присоединить извлеченный файл к почтовому sendt с Nodemailer.

Я не получаю никаких сообщений об ошибках, и электронное письмо успешно отправляется с вложением в формате PDF. Проблема в том, что файл поврежден и не может быть просмотрен.

Обновлено

Вот полный код для экспорта do c, отправки электронного письма и настройки функции Firebase. Я исключил любую попытку - ловить и обрабатывать ошибки для простоты. К письму будет приложено очень удобное вложение, если я попытаюсь использовать файл .txt; как new Buffer.from('Test string', 'utf8').

const jwtClient = asUserEmail =>
  new google.auth.JWT(
    serviceAccount.client_email,
    undefined,
    serviceAccount.private_key,
    'https://www.googleapis.com/auth/drive',
    asUserEmail,
  );

const initializeDrive = asUserEmail =>
  google.drive({
    version: 'v3',
    auth: jwtClient(asUserEmail),
  });

const exportAsPDF = async (fileId, asUserEmail) => {
  const drive = initializeDrive(asUserEmail);
  const result = await drive.files.export(
    {
      fileId: fileId,
      mimeType: 'application/pdf',
    },
    {
      responseType: 'arrayBuffer',
    },
  );
  return result.data;
};

const sendMail = async arrayBuffer => {
  const to = 'their@mail.com';
  const from = '"Your name here" <your@mail.com>';
  const template = `Test`;

  const transporter = nodemailer.createTransport({
    host: 'smtp.gmail.com',
    port: 465,
    secure: true,
    auth: {
      type: 'OAuth2',
      user: 'user@email.com',
      serviceClient: serviceAccount.client_id,
      privateKey: serviceAccount.private_key,
    },
  });

  await transporter.verify();

  await transporter.sendMail({
    from: from,
    to: to,
    subject: 'Test ✔',
    html: template,
    attachments: [
      {
        filename: 'test.pdf',
        content: new Buffer.from(arrayBuffer),
        contentType: 'application/pdf',
      },
    ],
  });
};

exports.emailAsPDF = functions.https.onCall(async (data, context) => {
  if (!context.auth) {
    // Check for auth state
  }

  const fileId = 'google-drive-file-id';
  const asUserEmail = context.auth.token.email;
  const extractedArrayBuffer = await exportAsPDF(fileId, asUserEmail);
  await sendMail(extractedArrayBuffer);
});

Подозреваю, что существует несоответствие между тем, что обеспечивает метод извлечения диска, и тем, что я должен предоставить как вложение.

Извлеченный массивBuffer из Drive API выглядит примерно так :

stream \ n '+' x��Q�JC1 \ f} �W�YX��Iӂ \ b * n�� \ u0005? @ � 0��� n� \ n '+' \ u0016 \ u0006JnN97) \ u0001zȯ "\ t- \ u0015 \ u000b \ u001c \ u001a) ^ \ u0005: \ u0016M1s5n_N & а \ u000bKr ڇ �6���iZ \ u0015 �4���] � \ u001fk% d�M8 {.� {�La�� \ u0016�Y�� \ u0002�.P� \ u0014a: \ u0006�Y \ u0011y � \ f���� :\u0004¨>��*>\u0011冔H��V:�F�m\u0003,&.��UDž \u0011���u�\r\u0000)#����Pi�=\u001cOόR0�v@��Rd�$�oJ�\u0007RC�҈!# Ӏ��o��X # \ 'I�� [�w� \ u001a� \ u001e \ u001f $ ���endstream \ n' + 'endobj \ n' + '8 0 obj \ n '+' << / Filter / FlateDecode / Length1 19428 / Length 10359 >> \ n '+' stream \ n '+

...