首页 > 解决方案 > 使用 Netlify lambda 函数从 GatsbyJS 站点发送电子邮件

问题描述

我正在关注本教程https://dev.to/char_bone/using-netlify-lambda-functions-to-send-emails-from-a-gatsbyjs-site-3pnb我已设置好所有内容,但出现以下错误我的终端。我可以从这里https://www.gatsbyjs.org/blog/2018-12-17-turning-the-static-dynamic/让 hello world 应用程序为 lambda 函数工作,这是开始第一个的先决条件教程。

RangeError [ERR_HTTP_INVALID_STATUS_CODE]: Invalid status code: undefined

这是上面带有表格的代码。您还可以在下面看到整个 repo。

import React from 'react'
import { HelmetDatoCms } from 'gatsby-source-datocms'
import { graphql } from 'gatsby'
import Layout from "../components/layout"

export default ({ data }) => {

  const [formState, setFormState] = React.useState({
    name: "",
    email: "",
    subject: "",
    message: "",
  })

  const onChange = (e) => {
    setFormState({...formState, [e.target.name]: e.target.value });
 }

 const submitForm = async (e) => {
  e.preventDefault();

  console.log("test");

  try{
    const response = await fetch("/.netlify/functions/sendmail", {
      method: "POST",
      body: JSON.stringify(formState),
    })

    if (!response.ok) {
      console.log(response);
      return
    }

    console.log("success email");

  } catch(e){

    console.log("error");

  }
}

  return(

  <Layout>

    <article className="sheet">
      <HelmetDatoCms seo={data.datoCmsPricing.seoMetaTags} />

        <section className="left-package-details">

          tests

        <div className="App">
      <form onSubmit={submitForm}>
        <label>
          Name
          <input
            type="text"
            name="name"
            value={formState.name}
            onChange={onChange}
          />
        </label>
        <label>
          Email
          <input
            type="email"
            name="email"
            value={formState.email}
            onChange={onChange}
          />
        </label>
        <label>
          Subject
          <input
            type="textarea"
            name="subject"
            value={formState.subject}
            onChange={onChange}
          />
        </label>
        <label>
          message
          <input
            type="text"
            name="message"
            value={formState.message}
            onChange={onChange}
          />
        </label>
        <button type="submit">Submit</button>
      </form>
    </div>


  )
}

更新

现在根据皮埃尔的回答,我收到 500 错误

Request from ::ffff:127.0.0.1: POST /sendmail 
Response with status 500 in 3 ms.

我想知道它是否与从本地主机 POST 相关,至少我知道它是 sendgrid 现在给我的错误。

我查看了 npm 调试部分并看到了这段代码,不知道该放在哪里?

const {
  classes: {
    Mail,
  },
} = require('@sendgrid/helpers');
const mail = Mail.create(data);
const body = mail.toJSON();
console.log(body);

控制台错误

Response {type: "basic", url: "http://localhost:8000/.netlify/functions/sendmail", redirected: false, status: 500, ok: false, …}
type: "basic"
url: "http://localhost:8000/.netlify/functions/sendmail"
redirected: false
status: 500
ok: false
statusText: "Internal Server Error"
headers: Headers {}
body: (...)
bodyUsed: false
__proto__: Response

第二次更新

我现在在终端中收到以下错误实际上我认为我什至不需要 cc,我认为这是说我没有 to 值,所以也许我的环境变量 SENDGRID_TO_EMAIL 没有被传递?

Provide at least one of to, cc or bcc 

现在,如果我添加这样的 cc

const msg = {
        to: SENDGRID_TO_EMAIL,
        cc:"email@email.com",
        from: email,
        subject: subject ? subject : 'Contact Form Submission',
        html: body,
    };

然后我收到一条Unauthorized消息

对于我的环境变量,我的根目录中有一个 .env 文件,其中包含以下内容

SENDGRID_API_KEY=SG.longsting
SENDGRID_TO_EMAIL=myemail@email.com

这是应该获取环境变量的行

const { SENDGRID_API_KEY, SENDGRID_TO_EMAIL } = process.env

标签: javascriptreactjsaws-lambdagatsbynetlify

解决方案


查看您的源代码,我很确定 sendgridsend函数会引发异常,并且您没有正确处理它:

try{
    await sgMail.send(msg)

    return {
        statusCode: 200,
        body: "Message sent"
    }
} catch(e){
    return {
        statusCode: e.code, // e.code is probably undefined
        body: e.message
    }
}

我快速浏览了一下 sendgrid SDK,没有看到任何提示它抛出与code有效 http 状态代码相对应的属性的错误。

结果是您返回带有undefined状态码的响应,因此出现ERR_HTTP_INVALID_STATUS_CODE错误。

尝试用catch以下内容替换您的块,您至少应该得到正确的响应,并希望从 sendgrid SDK 获得有用的错误消息:

try {
    // same as before
} catch(e){
    return {
        statusCode: 500,
        body: e.message
    }
}

更新

您的问题可能与您的环境变量有关。您应该确保SENDGRID_API_KEYSENDGRID_TO_EMAIL正确设置。

对于您的开发环境,我认为您需要require('dotenv').config()在函数文件中添加。

对于您的生产环境 (Netlify),您应该在 UI 中设置变量:https ://docs.netlify.com/configure-builds/environment-variables/#declare-variables


推荐阅读