Функция Firebase с использованием SMTP работает в эмуляторе, но тайм-аут при развертывании - PullRequest
1 голос
/ 05 августа 2020

В настоящее время я пишу облачную функцию в Firebase для отправки писем с помощью nodemailer, которая включает qr-код.

Если я имитирую проект в эмуляторе Firebase, все работает нормально, и письма отправляются правильно .

Однако, когда я загружаю код в Firebase, функция всегда отключается через 60 секунд. Я уже пытался увеличить время ожидания, но это все еще происходит.

Мой код:

exports.emailSender = functions.https.onRequest(async (req, res) => {
  var { name, code, hash, dest } = req.body;
  let transporter = nodemailer.createTransport({
    host: "smtp.test.com",
    port: 25,
    auth: {
      user: "username", 
      pass: "password",
    },
  });

  try {
    let qr = await create_qrcode(code+":"+hash,250,50);
    let qrBig = await create_qrcode(code+":"+hash,500,100);

    const mailOptions = {
      from: "no-reply@test.de",
      to: dest,
      subject: "Email Sent via Firebase",
      html: `<img src="${qr}" />`,
      attachments: [
        {
          filename: "QR-Code",
          path: qrBig,
        },
      ],
    };

    await transporter.sendMail(mailOptions, (err, info) => {
      if (err) {
        console.log(err);
        res.send({ error: err.message });
      } else {
        console.log(info);
        res.send("Erfolgreich");
      }
    });
  } catch (error) {
    res.send({ error: error.message });
  }
});

Функция для создания qrcode:

async function create_qrcode(dataForQRcode, width, cwidth {
  // grab data you want on qrcode here
  const cvs = createCanvas(1, 1);
  const url = await QRCode.toCanvas(cvs, dataForQRcode, {
    errorCorrectionLevel: "H", // LMQH
    margin: 1,
    color: {
      dark: "#000000", // black pixels
      light: "#ffffff", // white background
    },
  });
  const canvas = createCanvas(width, width);
  const ctx = canvas.getContext("2d");
  const img = await loadImage("./icon.png");
  ctx.drawImage(url, 0, 0, width, width);
  const center = (width - cwidth) / 2;
  ctx.drawImage(img, center, center, cwidth, cwidth);
  return canvas.toDataURL("image/png");
};

Похоже, что функция зависает на sendMail(), поэтому res.send() не запускается, и через 60 секунд достигается тайм-аут.

Есть идеи, почему это работает на эмуляторе, а не на реальных облачных функциях?

1 Ответ

3 голосов
/ 05 августа 2020

В качестве способа противодействия злоупотреблениям GCP полностью блокирует исходящий порт 25 для Compute Engine, и почти наверняка то же самое происходит и с Cloud Functions.

You ' Мне придется попробовать другой подход, который не использует исходящий порт 25. Например, вы можете использовать порт отправки SMTP 587 (вместо порта 25) на своем почтовом сервере для отправки исходящих писем. Это будет работать, потому что порт 587 (и 465 для smtps) не заблокирован GCP.

...