简体   繁体   中英

Unable to send email from form using Sendgrid with nextjs

I am creating a request quote form in nextjs using sendgrid as a thirdparty api for sending emails / submitting request quote from form. I keep receiving the following error and I am unable to link the form to the email.

error - ResponseError: Unauthorized
    at node_modules/@sendgrid/client/src/classes/client.js:146:29
    at processTicksAndRejections (node:internal/process/task_queues:96:5) {
  code: 401,
  response: {
    headers: {
      server: 'nginx',
      date: 'Wed, 18 Jan 2023 17:25:46 GMT',
      'content-type': 'application/json',
      'content-length': '116',
      connection: 'close',
      'access-control-allow-origin': 'https://sendgrid.api-docs.io',
      'access-control-allow-methods': 'POST',
      'access-control-allow-headers': 'Authorization, Content-Type, On-behalf-of, x-sg-elas-acl',
      'access-control-max-age': '600',
      'x-no-cors-reason': 'https://sendgrid.com/docs/Classroom/Basics/API/cors.html',
      'strict-transport-security': 'max-age=600; includeSubDomains'
    },
    body: { errors: [Array] }
  },
  page: '/api/contact'
}

Under pages/contact.jsx

const contact = () => {
  const [values, setValues] = useState({
    firstName: "",
    lastName: "",
    phone: "",
    email: "",
    zip: "",
    message: "",
  });

  const {firstName, lastName, phone, email, zip, message} = values;

  const handleChange = e => 
    setValues({ ...values, [e.target.name]: e.target.value });

  const handleSubmit = async (e) => {
    e.preventDefault()
    try {
      await fetch("http://localhost:3000/api/contact", {
        method: "POST",
        header: {
          "Content-Type": "application/json",
        },
        body: JSON.stringify(values),
      });
    } catch (err) {
      console.log(err);
    }
  };

 return (
    <div className='w-full h-screen'>
      <div className='min-h-screen py-40 border border-gray-800 bg-white bg-gradient-to-br from-sjrblue to-sjrblue-200'>
        <div className="container mx-auto">
          <div className="flex flex-col lg:flex-row w-10/12 bg-white rounded-xl mx-auto shadow-lg overflow-hidden">
            <div alt='loaded trailer' className='w-full h-[400px] lg:gap-5 lg:h-auto lg:w-1/2 bg-contactImage bg-cover bg-center text-center shadow-lg shadow-slate-400'></div>

            {/* Request Quote Form */}
            <div className="lg:w-1/2 lg:m-2 p-4 items-center">
              <h2 className='text-3xl mb-4 text-center text-sjrblue'>Company Name</h2>
              <p className='mb-4 text-center'>CONTACT US TODAY FOR A <span className='text-blue font-bold'>FREE</span> JUNK REMOVAL ESTIMATE</p>

              <form onSubmit={handleSubmit}>
                <div className='grid grid-cols-2 gap-1 md:gap-3 lg:gap-5'>
                  <input 
                    type="text" 
                    placeholder='first name' 
                    value={firstName} 
                    onChange={handleChange}  
                    required
                    name='firstName' 
                    className='border border-gray-400 py-1 px-2 shadow-lg shadow-slate-400'
                  />
                  <input 
                    type="text" 
                    placeholder='sur name'
                    value={lastName}
                    onChange={handleChange} 
                    required 
                    name='lastName'
                    className='border border-gray-400 py-1 px-2 shadow-lg shadow-slate-400'
                  />
                </div>
                <div className='mt-5'>
                  <input 
                    type="email" 
                    placeholder='email'
                    value={email}
                    onChange={handleChange} 
                    required 
                    name='email' 
                    className='text-sm border border-gray-400 py-1 px-2 w-full shadow-lg shadow-slate-400'
                  />
                </div>
                <div className='mt-5'>
                  <input 
                    type="tel" 
                    id='phone-number' 
                    onkeydown='phoneNumberFormatter()' 
                    inputmode='tel' 
                    placeholder='phone number 123-456-7890' 
                    pattern='[0-9]{3}-[0-9]{3}-[0-9]{4}' 
                    value={phone}
                    onChange={handleChange} 
                    required 
                    name='phone' 
                    className='text-sm border border-gray-400 py-1 px-2 w-full shadow-lg shadow-slate-400'
                  />
                </div>
                <div className='mt-5'>
                  <input 
                    type="text" 
                    inputmode='numeric' 
                    placeholder='zip code' 
                    maxLength={5}
                    value={zip}
                    onChange={handleChange} 
                    name='zip' 
                    required 
                    className='text-sm border border-gray-400 py-1 px-2 w-full shadow-lg shadow-slate-400'
                  />
                </div>
                <div className='mt-5'>
                  <textarea 
                    name="message" 
                    placeholder='message' 
                    id="" cols="30" 
                    rows="10" 
                    value={message}
                    onChange={handleChange}  
                    required 
                    className='text-sm border border-gray-400 py-1 px-2 w-full shadow-lg shadow-slate-400'>  
                  </textarea>
                </div>
                <div className='mt-5 text-center'>
                  <input type="checkbox" required className='border border-gray-400 w-3 h-3'/>
                  <span className='px-3 text-sm'>I am not a robot</span>
                  <div className='mt-5'>
                    <button className='bg-sjrblue w-full text-enter text-white py-3 rounded  hover:bg-blue-700  duration-300 shadow-lg shadow-slate-400'>Get your FREE estimate</button>
                  </div>
                </div>
              </form>
            </div>

          </div>
        </div>
      </div>  

under pages/api/contact.js

require("dotenv").config();
const sgMail = require("@sendgrid/mail");

const { SG_API_KEY, FROM_EMAIL, TO_EMAIL } = process.env;
sgMail.setApiKey(SG_API_KEY);

export default async function handler(req, res) {
    const {firstName, lastName, phone, email, zip, message} = req.body;

    const msg = {
        to: TO_EMAIL,
        from: FROM_EMAIL,
        subject: '',
        html: `<p><strong>First Name: </strong>${firstName}</p>
        <p><strong>Last Name: </strong>${lastName}</p>
        <p><strong>Phone Number: </strong>${phone}</p>
        <p><strong>Email: </strong>${email}</p>
        <p><strong>Zip: </strong>${zip}</p>
        <p><strong>Message: </strong>${message}</p>
        `,
    };
    await sgMail.send(msg);
    console.log('email sent');
    res.status(200).json({ success: true  });

And I have an.env file in my root files

SG_API_KEY= #API Key
TO_EMAIL=  #verified email
FROM_EMAIL= #email to send form to

Please help! Thank you in advance!

Twilio developer evangelist here.

Because it's a 401 error, I think it's an issue with how you set up your API key in environment variables.

To set up environment variables, you can use these 3 commands:

echo "export SENDGRID_API_KEY='YOUR_API_KEY'" > sendgrid.env
echo "sendgrid.env" >> .gitignore
source ./sendgrid.env

You could also change your API key settings to Full access in the SendGrid console, or it could be the incorrect API key so you could also generate a new one.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM