Как подключить nodemailer к Vue.js и приложение Netlify с использованием лямбда-функций

#javascript #vue.js #lambda #nodemailer #netlify

#javascript #vue.js #лямбда #nodemailer #netlify

Вопрос:

У меня есть статический веб-сайт в Netlify, созданный с Vue.js и у меня есть особая потребность в сборе x-www-form-urlencoded данных, отправляемых с маршрута контакта.

Поскольку это spa и динамически отображаемая форма, я добавил это как в index.html (для предварительной визуализации и разрешения Netlify видеть форму при загрузке)

public/index.html amp; src/views/Contact.vue

 <form 
  netlify-honeypot="bot-field"
  name="contact"
  data-netlify="true" hidden>

    <input name="bot-field" />
    <input type="text" name="name" />
    <input type="email" name="email" />
    <input type="text" name="subject" />
    <textarea rows="5" name="message"></textarea>

</form>
  

Представление контактов:

 <form
  netlify-honeypot="bot-field"
  name="contact" method="post"
  data-netlify="true"
  @submit.prevent="handleSubmit">

  <input type="hidden" name="form-name" value="contact" />
    <p style="opacity: 0;">
      <label>Don’t fill this out if you're human: <input name="bot-field" /></label>
    </p>
    <p>
      <label>Your Name: <input v-model="form.name" type="text" name="name" /></label>
    </p>
    <p>
      <label>Your Email: <input v-model="form.email" type="email" name="email" /></label>
    </p>
    <p>
      <label>Your Subject: <input v-model="form.subject" type="text" name="subject" /></label>
    </p>
    <p>
      <label>Message: <textarea v-model="form.message" rows="5" name="message"></textarea></label>
    </p>
    <p>
      <button>Send</button>
    </p>

</form>
  

Свойства данных в компоненте моделируются, и способ отправки данных заключается в следующем:

 export default {
  name: 'contact',
  data: () => ({
    form: {
      name: '',
      email: '',
      subject: '',
      message: '',
    },
  }),
  methods: {
    encode (data) {
      return Object.keys(data)
        .map(
          key => `${encodeURIComponent(key)}=${encodeURIComponent(data[key])}`,
        )
        .join('amp;');
    },
    handleSubmit () {
      const axiosConfig = {
        header: { 'Content-Type': 'application/x-www-form-urlencoded' },
      };
      axios.post(
        '/',
        this.encode({
          'form-name': 'contact',
          ...this.form,
        }),
        axiosConfig,
      )
        .then(() => console.log('success'))
        .catch(e => console.error(e));
    },
  },
};
  

Следующая часть системы — это лямбда-функция, запускаемая Netlify. Netlify разрешает submission-created функцию каждый раз, когда приложение получает отправку формы. Все, что вам нужно сделать, это создать каталог в корне вашего проекта с submission-created.js файлом в нем. Этот каталог должен быть указан в netlify.toml, чтобы Netlify знала, где искать ваши функции.

Another caveat is that if your function requires dependencies, you need to zip the folder with the node_modules included. I automate this in package.json with bestzip dependency.

package.json

 "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "lint": "vue-cli-service lint",
    "zip": "cd functions/submission-created amp;amp; bestzip ../../functions-build/submission-created.zip *",
    "clean": "rm -rf functions-build amp;amp; mkdir functions-build",
    "prebuild": "npm run clean amp;amp; npm run zip"
}
  

As you can see, the way I handle this is by writing the source of the function in functions/submission-created/submission-created.js I also have a functions-build directory which is the one specified in netlify.toml, that will contain the zipped up submission-created folder.

По сути, я npm init -y создаю каталог, созданный functions / submission, и npm install nodemailer при запуске prebuid он удаляет текущую сборку функций и создает ее заново с последующим архивированием функций в каталог с его зависимостями.

Вот netlify.toml

 [build]
  functions = "./functions-build"
  

Наконец, там, где находится важный код, находится submission-created.js файл:

 
exports.handler = function(event, context, callback) {
  const nodemailer = require('nodemailer');
  const querystring = require('querystring');
  const payload = querystring.parse(event.body);
  const { name, email, subject, message } = payload;

  // create reusable transporter object using the default SMTP transport
  let transporter = nodemailer.createTransport({
    host: "xxx",
    port: 587,
    secure: false, // true for 465, false for other ports
    auth: {
      user: 'xxx', // generated ethereal user
      pass: 'xxx' // generated ethereal password
    },
    tls: {
      rejectUnauthorized: false,
    },
  });

  // setup email data with unicode symbols
  let mailOptions = {
    from: `"website enquiry 👻" <${email}>`, // sender address
    to: "admin@xxx.xx, enquiry@xxx.xx", // list of receivers
    subject: `${subject} ✔`, // Subject line
    text: `name: ${name}, n email: ${email}, n message: ${message}n`, // plain text body
  };

  // send mail with defined transport object
  transporter.sendMail(mailOptions)
  .then(() => {
    callback(null, { statusCode: 200, body: 'Success' });
  })
  .catch(e => callback(e, { statusCode: 500, body: 'Error sending email' }));

};
  

Основная проблема

Форма записана в материалах, представленных на Netlify. Проблема заключается в функции:

В разработке (локальное размещение лямбда-функции с использованием netlify-lambda ) Я получаю свойства, введенные на сайте.

В рабочей среде свойства не определены. И полный объект события не регистрируется в консоли в функциях.

Ответ №1:

Ответ заключается в параметре события в производстве или в разработке.

исправление:

 // How to get post parameters in production
exports.handler = function(event, context, callback) {
  const payload = JSON.parse(event.body).payload;
  const { name, email, subject, message } = payload;
}