如何在 Firebase 存储上使用 hbs 模板,并在数据库中使用 nodemailer-express-handle



我正在尝试使用上传到我的 Firebase 项目存储 (appId.appspot.com/templates/testTemplate.hbs) 的车把模板文件与 nodemailer,以便在实时数据库节点上触发 onCreate 函数时发送电子邮件。

我可以使用 html 格式的字符串成功发送电子邮件,但确实需要使用模板将动态数据添加到电子邮件中。

这是我的函数:

import * as functions from "firebase-functions";
const admin = require("firebase-admin");
const hbs = require("nodemailer-express-handlebars");
const nodemailer = require("nodemailer");
const smtpConfig = {
  host: "mailHost",
  port: 465,
  secure: true,
  auth: {
    user: "xxxxxxxx",
    pass: "xxxxxxxx"
  }
};
const transporter = nodemailer.createTransport(smtpConfig);
exports.sendEmail = functions.database
  .ref("/databasePath/{pushId}")
  .onCreate(async (snapshot, context) => {
    const userData = snapshot.val();
    admin.initializeApp({
      storageBucket: "appId.appspot.com"
    });
    const bucket = admin.storage().bucket();
    const templatesFolder = bucket.name + "/templates/"; // path to storage folder with templates
    transporter.use(
      "compile",
      hbs({
        viewPath: templatesFolder,
        extName: ".hbs"
      })
    );
    const uniqueCode = "generated by a function";
    const uniqueLink = "https://appId.firebaseapp.com/?id=" + uniqueCode;
    const message = {
      from: "fromEmail",
      to: "toEmail",
      subject: "Subject",
      template: "testTemplate", // name of the template file
      context: {
        user: "User name",
        link: uniqueLink
      }
    };
    try {
      await transporter.sendMail(message);
      console.log("Email sent to:", "toEmail");
    } catch (error) {
      console.error("Error sending email:", error);
    }
    return null;
  });

触发函数时,我在日志中收到以下错误:

发送电子邮件时出错:{ 错误:ENOENT:没有这样的文件或目录,打开'/user_code/appId.appspot.com/templates/testTemplate.hbs' 错误(本机) 错误: -2, 代码:"ENOENT", 系统调用:"打开", path: '/user_code/appId.appspot.com/templates/testTemplate.hbs' }

bucket.name 开头有"/user_code",因此 hbs 找不到模板。 如何获取模板文件夹的正确路径?

看起来您实际上并没有编写任何从云存储下载文件的代码。 您不能只是在Cloud Storage中构建文件的路径,将其传递给其他组件,并希望它只知道如何处理该路径。 您所做的只是将不存在的本地文件的名称传递给它。 您必须实际将文件下载到临时文件夹才能在本地使用它。

或者更好的是,只需跳过云存储并部署模板以及您的函数。 您可以直接从磁盘读取文件,无需额外费用。 (每次下载云存储都需要花钱。

这是更新的函数:

import * as functions from "firebase-functions";
const admin = require("firebase-admin");
const hbs = require("nodemailer-express-handlebars");
const nodemailer = require("nodemailer");
const smtpConfig = {
  host: "mailHost",
  port: 465,
  secure: true,
  auth: {
    user: "xxxxxxxx",
    pass: "xxxxxxxx"
  }
};
const transporter = nodemailer.createTransport(smtpConfig);
exports.sendEmail = functions.database
  .ref("/databasePath/{pushId}")
  .onCreate(async (snapshot, context) => {
    const userData = snapshot.val();
    const templatesFolder = __dirname + "/templates"; // <--
    transporter.use(
      "compile",
      hbs({
        viewPath: templatesFolder,
        extName: ".handlebars"
      })
    );
    const uniqueCode = "generated by a function";
    const uniqueLink = "https://appId.firebaseapp.com/?id=" + uniqueCode;
    const message = {
      from: "fromEmail",
      to: userData.email, // from the snapshot
      subject: "Subject",
      template: "testTemplate", // name of the template file
      context: {
        user: userDate.name, // from the snapshot
        link: uniqueLink
      }
    };
    try {
      await transporter.sendMail(message);
      console.log("Email sent to:", userData.email);
    } catch (error) {
      console.error("Error sending email:", error);
    }
    return null;
  });

将模板文件添加到"functions/lib/templates/testTemplate.handlebars"

相关内容

  • 没有找到相关文章

最新更新