Как использовать шаблон hbs в Firebase Storage с помощью nodemailer-express-handlebars в функции триггера onCreate базы данных? - PullRequest
0 голосов
/ 23 декабря 2018

Я пытаюсь использовать файл шаблона руля, загруженный в мое хранилище проектов 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» в Error (native) errno: -2, код: «ENOENT», syscall: «open», путь: «/ user_code /appId.appspot.com/templates/testTemplate.hbs '}

В начале файла bucket.name указано «/ user_code», поэтому hbs не может найти шаблон.Как я могу получить правильный путь к папке с шаблонами?

Ответы [ 2 ]

0 голосов
/ 01 января 2019

Вот обновленная функция:

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"

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

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

Или, что еще лучше, просто пропустите Cloud Storage и разверните шаблон вместе с вашими функциями.Вы можете просто прочитать файл прямо с диска без каких-либо дополнительных затрат.(Каждая загрузка Cloud Storage стоит денег.)

...