如何用Netlify函数从React应用中发送电子邮件

618 阅读10分钟

简介

通过流行的JavaScript框架和库,如React、Angular和Vue,你可以开发复杂的单页应用程序,并在Netlify等平台上托管它们,只需几个步骤。

然而,你可能想用这些应用程序来运行工作,如发送电子邮件和访问秘密的API凭证,这通常需要建立一个服务器。这样的工作通常不可能在前端运行,或者说是不明智的。然而,Netlify提供了一些功能,可以从你的Jamstack应用程序中执行这些操作,而不需要部署一个服务器。

其中一个功能就是Netlify功能。这篇文章的目的是教你如何在React应用程序中使用事件驱动的Netlify函数和SendGrid来发送电子邮件。这封邮件将是对客户提交的表单的回应。

虽然我们将使用React,但这个过程对于其他框架来说应该是类似的,只是有一些轻微的变化。

Netlify函数的背景

Netlify函数,就像它的名字一样,是一个简单的函数,可以在JavaScript、Typescript或Go中声明,并与你的前端代码一起部署到Netlify。然后Netlify会将您的函数部署到AWS,而不需要您建立一个AWS账户。

如何声明Netlify函数

你在你的前端项目目录根部的一个文件夹中声明Netlify函数。函数的路径被作为一个端点来触发该函数。

默认情况下,Netlify会在你的项目目录根部的netlify/functions 文件夹中寻找你的无服务器函数。如果你想在不同的目录下声明该函数,请包含一个netlify.toml 配置文件,并在其中添加关于你的函数位置的信息。

shell
project-folder
├── node_modules
├── netlify
|   ├── functions
|       ├── send-emails.js
├── package.json
├── package-lock.json

你可以在Netlify文档中阅读更多关于netlify.toml 配置文件的信息。

在上面的项目结构中,函数send-emails.js 已经在netlify/functions 文件夹中被声明。你可以通过向/.netlify/functions/send-emails 端点发出请求来调用它。

事件驱动的Netlify函数

虽然Netlify函数需要通过调用一个端点来调用,但还有一种Netlify函数被称为事件驱动的函数。它们在某些事件被注册后被调用。

其中一个事件是submission-created ,该事件是在表单提交被Netlify验证后发出的。一个函数必须以事件命名,才能成为事件驱动的函数。

在这篇文章中,我们将使用一个事件驱动的函数在验证表单提交后发送电子邮件。

你可以查看Netlify的文档,了解可用的事件触发器的完整列表

背景Netlify函数

普通的Netlify函数会在十秒后超时。如果您想执行一个超过这个时间的工作,您将不得不使用后台函数。

后台函数在超时前可以在后台异步运行15分钟。你可以把普通的Netlify函数变成背景函数,方法是在它的名字后面加一个-background 。例如,send-emails-background.js 是一个后台函数。

但是,请记住,在写这篇文章的时候,后台函数仍然是实验性的。

现在让我们创建一个简单的React应用程序,以学习如何使用Netlify函数。

创建一个React应用程序

在本节中,我们将使用create-react-app 来搭建一个React应用程序。在终端上运行下面的命令,在email-app 目录中创建一个完全配置的React应用。

npx create-react-app email-app

成功运行上述命令后,你应该看到包含你的React应用程序的email-app 文件夹。

现在,让我们在我们的应用程序中添加一个联系表单。

添加一个JSX 表单

src 目录中创建ContactForm.js 文件,并粘贴以下代码。

export default function ContactForm() {
  return (
    <form name="contact-form" method="post">
      <div>
        <label htmlFor="name">Full Name</label> <br />
        <input
          type="text"
          id="name"
          name="name"
          placeholder="Jane Doe"
          required
        />
      </div>
      <div>
        <label htmlFor="email">E-mail</label> <br />
        <input
          type="email"
          id="email"
          name="email"
          placeholder="doe@example.com"
          required
        />
      </div>
      <div>
        <label htmlFor="message">Message</label> <br />
        <textarea
          id="message"
          name="message"
          placeholder="Your message here!"
          required
        ></textarea>
      </div>
      <div>
        <input type="submit" className="submit" value="Send Message" />
      </div>
    </form>
  );
}

复制并粘贴下面的代码到App.js ,替换掉模板代码。

import "./App.css";
import ContactForm from "./ContactForm";

export default function App() {
  return (
    <div className="App">
      <ContactForm />
    </div>
  );
}

让我们给表单添加一点样式。复制并粘贴下面的代码到App.css 文件中。

body {
  min-height: 95vh;
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: rgb(54, 53, 53);
  color: #c5cdd3;
  font-family: sans-serif;
}
form {
  background-color: rgb(26, 24, 24);
  padding: 1em;
  border-radius: 10px;
}
div {
  padding-top: 1em;
}
input,
textarea {
  min-width: 250px;
  box-sizing: border-box;
  padding: 0.5em;
  outline: none;
  background-color: #222d35;
  border: 2px solid transparent;
  border-radius: 5px;
}
input:focus,
textarea:focus {
  border: 2px solid brown;
  color: #c5cdd3;
}
textarea {
  min-height: 250px;
  resize: vertical;
}
.submit {
  color: #c5cdd3;
}
.App {
  padding: 1em;
}

Netlify有一个管理表单提交的功能;标记文件在部署时被解析。将data-netlify="true"netlify 属性添加到你的form 元素中,就足以让Netlify检测到它并管理表单提交的开箱即用。

然而,由于我们处理的是React,我们上面添加的是JSX 的形式。你需要做更多的工作来使你的表单在部署时能被Netlify的机器人检测到。

复制并粘贴下面的隐藏表单,就在public 目录中的index.html 文件的开头body 标签之后。

<form name="contact-form" netlify netlify-honeypot="bot-field" hidden>
  <input type="text" name="name" />
  <input type="email" name="email" />
  <textarea name="message"></textarea>
</form>

上面的表单对用户是隐藏的,因为它将被Netlify的机器人使用。我们已经剥离了表单中的某些元素,只留下光秃秃的input 元素。

将下面的input 元素复制并粘贴到你的JSX 表格中的ContactForm 组件中,就在开头的form 标签之后。

<input type="hidden" name="form-name" value="contact-form" />

默认情况下,Netlify会开始过滤提交的表单,以防止垃圾邮件。你也可以配置Netlify在表单提交被验证后通过电子邮件、webhook或Slack通知你。

在收到表单提交后,您会希望通知您的客户,他们的信息已经收到,他们的问题正在被解决。然而,Netlify并没有内置的功能来发送自动的电子邮件回复,确认收到客户的信息。

这就需要您使用Netlify功能和第三方SMTP服务。有几个SMTP服务提供商,如SendGrid和Mailgun,等等。在这篇文章中,我们将使用SendGrid,因为它提供了一个免费的试用计划,不需要信用卡。它还允许你每天最多发送100封电子邮件。

在下一节,我们将注册SendGrid,验证我们的发件人身份,并获得一个API密钥。

获得SendGrid的API密钥

我们将需要一个API密钥来与SendGrid的API进行程序化的交互。

导航到SendGrid,用你的电子邮件地址注册。登录后,使用单一发件人验证来验证你的发件人身份。发件人身份是客户端或电子邮件的收件人所看到的电子邮件的发件人。

通过点击电子邮件API标签和集成指南获得API密钥。选择网络API设置方法,然后选择Node.js作为首选语言。一个显示如何在Node中使用SendGrid发送电子邮件的分步指南的页面应该打开。

现在我们可以通过给它一个适当的名字来创建一个API密钥。

接下来,在项目目录的根部创建一个.env 文件,并在其中添加以下几行代码。

# API key from SendGrid
SENDGRID_API_KEY=
# The email address which appears in the from field
SENDER_EMAIL=

SENDGRID_API_KEY 环境变量的值是我们的SendGrid API密钥。SENDER_EMAIL 的值是我们希望在客户端收到我们的电子邮件时显示的发件人电子邮件地址。

忽略.env 文件,将其添加到.gitignore ,这样我们就不会意外地将其推送到远程 git 托管服务,如 GitHub、GitLab 或 BitBucket;我们不希望暴露我们的 API 密钥。

通常情况下,我们需要dotenv 包来使用Node中的环境变量。这里没有必要,因为react-scripts 在后台使用dotenv

在下一节,我们将添加Netlify函数来发送电子邮件。

添加用于发送电子邮件的Netlify函数

现在,让我们添加一个Netlify函数,用于在客户提交表单时发送一个自动的电子邮件响应。我们将在Netlify发出submission-created 事件后发送该邮件。

一个事件驱动的Netlify函数必须与触发它的事件有相同的名字。Netlify发出的事件有好几个,但我们只对submission-created 事件感兴趣,这个事件在表单提交被验证后就会发出。

如前所述,一个需要由submission-created 事件触发的函数必须命名为submission-created.js

运行下面的命令来安装netlify-cli 。这是一个方便的npm包,我们可以用它来通过命令行与Netlify工作。

npm i netlify-cli -g

成功地运行上述命令将在全局范围内安装netlify-cli

在项目目录的根部创建一个文件夹,并将其命名为netlify 。在你刚刚创建的netlify 文件夹中创建另一个文件夹,并将其命名为functions

运行下面的命令来创建Netlify Functions的模板代码,并在提示时选择submission-created 的模板。如果你没有看到submission-created 选项,请使用上下方向键在列表中导航。

netlify functions:create submission-created

成功运行上述命令后,我们应该能在netlify/functions 文件夹中看到submission-created.js 文件。这就是文件的内容应该是这样的。

Screenshot of code in the submission-created.js file

一个Netlify函数文件总是会导出一个单一的函数,该函数需要eventcontext 参数。但是请注意,context 参数并不是发送邮件所必需的。

我们可以在event 对象的body 字段中访问提交的表单的内容。event 对象的形状如下所示。

{
  path: '',
  httpMethod: '',
  queryStringParameters: {},
  multiValueQueryStringParameters: {},
  headers: {},
  multiValueHeaders: {},
  body: '{payload:{data:{}}}',
  isBase64Encoded: false
}

对于我们通过SendGrid发送电子邮件,我们需要@sendgrid/mail 包。我们可以为Netlify功能安装所需的依赖项,就像前端应用程序中的其他依赖项一样。当应用程序的构建过程完成后,Netlify将提取这些依赖,并将它们与我们的函数一起部署到AWS。

运行下面的命令来安装@sendgrid/mail npm包,这样我们就可以从我们的函数中与SendGrid的Web API进行交互。

npm i @sendgrid/mail

在成功安装@sendgrid/mail ,复制并粘贴下面的代码到我们上面创建的submission-created.js 文件中。

const sendGridMail = require("@sendgrid/mail");

const handler = async (event) => {
  try {
    const { name, email, message } = JSON.parse(event.body).payload.data;

    console.log(`name: ${name}, email: ${email}, message: ${message}`);

    sendGridMail.setApiKey(process.env.SENDGRID_API_KEY);
    const html = `
      <div> 
         Hi ${name}! <br><br>
         Thanks for getting in touch.
         We have received your message
         and one of our customer care
         representatives will get in
         touch shortly
         <br><br>
         Best <br>
         John Doe
      </div>
    `;
    const mail = {
      from: process.env.SENDER_EMAIL,
      to: email,
      subject: "We have received your message",
      html,
    };
    await sendGridMail.send(mail);
    return {
      statusCode: 200,
      body: JSON.stringify({ message: "Email sent" }),
    };
  } catch (error) {
    return { statusCode: 422, body: String(error) };
  }
};

module.exports = { handler };

在上面的代码中,我们像其他的Node包一样需要@sendgrid/mail 包,并从payload 中对提交的电子邮件进行解构。mail 对象传递给sendGridMail.send 方法,该方法包含 SendGrid 所要求的所有必要信息,以发送你的电子邮件。

在下一节中,我们将测试我们刚刚添加的功能。

测试应用程序

现在是时候测试我们的应用程序了。通过在终端上运行下面的命令来启动本地开发服务器。

netlify dev

成功运行上述命令将启动8888端口的开发服务器。

Screenshot of example app with input fields for name, email, and email message.

一旦提交了表单,你就应该看到有一封邮件被送到你的收件箱。你可以继续使用netlify-cli ,或通过GitHub、Gitlab或Bitbucket使用持续部署功能,将应用程序部署到Netlify。

我已经把这个应用的代码库部署到了GitHub上,你可以在那里克隆仓库并探索这个平台的更多功能。

这就是你如何使用Netlify功能和第三方SMTP服务器发送电子邮件的方法如果您想使用Netlify Functions发送邮件,但不是响应submission-created 事件,您将不得不使用普通的函数,尽管没有Netlify内置的处理表单的功能。

总结

对于前端开发者来说,使用无服务器函数在Jamstack应用程序中提供全栈体验已经变得很容易。正如上面所证明的,你可以在一个简单的函数中编写你的服务器端代码,并与你的前端应用程序一起部署,然后交给Netlify等平台为你做其他事情。

The postHow to send emails from a React app with Netlify Functionsappeared first onLogRocket Blog.