Home > Enterprise >  How to send mail via sendgrid - node
How to send mail via sendgrid - node

Time:06-02

I want to use nextjs application to send email by send grid,because of its serverless feature. I send my first email via send grid demo, just now I want to send a date from my form.

form.js

import React, {useState} from 'react';
import { useForm } from 'react-hook-form';

import {
    Row,
    Col,
    Container,
    Form,
    FormGroup,
    Input,
    Button,
  } from "reactstrap";



function Form() {
    const [hasSuccessfullySentMail, setHasSuccessfullySentMail] = useState(false);
    const [hasErrored, setHasErrored] = useState(false);
    const { register, handleSubmit, formState } = useForm();
    const { isSubmitSuccessful, isSubmitting, isSubmitted, errors } = formState;
  
    async function onSubmit(payload) {
      try {
        const res = await fetch('/api/sendEmail', {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
          },
          body: JSON.stringify({ subject: 'Email from contact form', ...payload }),
        });
  
        if (res.status !== 204) {
          setHasErrored(true);
        }
      } catch {
        setHasErrored(true);
        return;
      }
  
      setHasSuccessfullySentMail(true);
    }
  
    const isSent = isSubmitSuccessful && isSubmitted;
    const isDisabled = isSubmitting || isSent;
    const isSubmitDisabled = Object.keys(errors).length > 0 || isDisabled;
  



  return (
<>
<Form onSubmit={handleSubmit(onSubmit)}>

                      <Row>
                        <Col lg="6">
                          <FormGroup className="m-t-15">
                            <Input type="text" placeholder="Wpisz swoje imię" id="name" disabled={isDisabled} {...register('name', { required: true })} />
                          </FormGroup>
                        </Col>
                        <Col lg="6">
                          <FormGroup className="m-t-15">
                            <Input type="text" placeholder="Twój Email" id="email" disabled={isDisabled} {...register('email', { required: true })} />
                          </FormGroup>
                        </Col>
                        <Col lg="12">
                          <FormGroup className="m-t-15">
                            <Input
                              as="textarea"
                              placeholder="Wpisz swoją wiadomość..."
                              id="description"
                              disabled={isDisabled}
                              {...register('description', { required: true })}
                            />
                          </FormGroup>
                        </Col>
                        <Col lg="12">
                          <Button
                            type="submit" disabled={isSubmitDisabled}
                            className="btn btn-danger-gradiant m-t-20 btn-arrow"
                          >
                            <span>
                              {" "}
                              Wyślij <i className="ti-arrow-right"></i>
                            </span>
                          </Button>
                        </Col>
                      </Row>
                    </Form>
</>  )
}

export default Form

Problem is that in my console I do not see any headers's tag. I look inside Safari > developers tool > network. When I use mailchimp I can notice that something is sending as post-json in 1sec. Looking into console I get message that something is sending but after 40s as web pack-hmr. I think this is something differ.

in sendMail.js


require('dotenv').config(sendgrid.env)
require('dotenv').config(sendgrid)

import sendgrid from '@sendgrid/mail';

    
sendgrid.setApiKey(process.env.SENDGRID_API_KEY);
    
export default async (req, res) => {


  const body = JSON.parse(req.body);
  
  const message = `
  Name: ${body.name}\r\n
  Email: ${body.email}\r\n
  Message: ${body.message}
  `;
  
  const data = {
    to: '[email protected]',
    from: '[email protected]',
    subject: 'wiadomosc od klienta',
    text: message,
    html: message.replace(/\r\n/g, '<br>')
  };
  
  console.log(data)

    sendgrid.send(data);

  
    return res.status(200).json({ status: 'Ok' });
};

technically, there must be here some mistakes, but send grid is good installed and configured. So I need to change only this piece of code.

CodePudding user response:

I have answer for my first of problem. My SendGrid post date to api/contact but there something not work as it should.

import { useState } from 'react'
import {
    Row,
    Col,
    Container,
    Form,
    FormGroup,
    Input,
    Button,
  } from "reactstrap";

function Form() {    
    const [name, setName] = useState('')
    const [email, setEmail] = useState('')
    const [message, setMessage] = useState('')
    const [submitted, setSubmitted] = useState(false)
    const [status, setStatus] = useState('')
    
    async function handleOnSubmit(e) {
        e.preventDefault();
        const formData = {
            name,
            email,
            message
        }
        console.log("przesylam dane");
        
        setSubmitted(true)
        
        fetch('/api/contact', {
            method: 'POST',
     
            body: JSON.stringify(formData)
        }).then((res) => {
            if (res.status === 200) {
                console.log("czyszcze pola")
                setSubmitted(false)
                setName('')
                setEmail('')
                setMessage('')
                setStatus('success')
            }
            else {
                console.log("pokazuej blad")
                setStatus('error')
            }
        }) 
    }
    
    return (<>
<Form action='submit' method='POST' onSubmit={handleOnSubmit}>
<Row>
<Col lg="6">
        <div id="name" isRequired className="m-t-15">
            <Input             style={{width: "100%"}}
placeholder="Wpisz swoje imię" type="text" value={name} onChange={(e) => { setName(e.target.value) }} />
        </div>
        </Col>
        <Col lg="6">
        <div id="email" isRequired className="m-t-15">
            <Input             style={{width: "100%"}}

placeholder="Wpisz swój adres email"  type="email" value={email} onChange={(e) => { setEmail(e.target.value) }} />
        </div>
       </Col>
       <Col lg="12">
        <div id="text" isRequired className="m-t-15"> 
        <Input
                              as="textarea"            style={{width: "100%"}}
                placeholder="Wpisz swoją wiadomość.."
                value={message}
                onChange={(e) => { setMessage(e.target.value) }}
            />
        </div>
     </Col>
     <Col lg="12">

        <Button type="submit"
            isLoading={submitted}
            loadingText="Submitting"
            className="btn btn-danger-gradiant m-t-20 btn-arrow"
            style={{width: "200px"}}

        >
         {" "}
                              Wyślij <i className="ti-arrow-right"></i>        </Button>
    </Col>
    </Row>
    {status === "success" ? <span style={{color: "green"}}>wiadomość przesłana</span> : ""}
    {status === "error"  ? <span style={{color: "red"}}>wiadomość nie została wysłana</span> : "" }
    </Form>
</>    )
}
    
export default Form

CodePudding user response:

I have recently used SendGrid as it is an external resolver API I did this in my API portion of next.js and works correctly.

// api/mail
import { news_letter_template } from "../../../util/email_templates";
 const sendGrid = require("@sendgrid/mail");
  sendGrid.setApiKey(process.env.NEXT_PUBLIC_SENDGRID_KEY);
  // add this before handler!
  export const config = {
    api: {
       externalResolver: true,
    },
  };
export default function handler(req, res) {
 const body = JSON.parse(req.body);
  console.log('request came => ',body);
  const msg = news_letter_template(body.email);
  sendGrid
   .send(msg)
   .then(() => {
      return res.status(200).json({ send: true });
   })
   .catch((err) => {
     return res.status(400).json({ send: false });
   });
 }

setting externalResolver to true made my code works correctly.

//utils/email_templates
const SENDER_EMAIL =
 process.env.NEXT_PUBLIC_SENDER_EMAIL || "[email protected]";
 const weblog_social = {
 insta: "https://www.instagram.com/weblog",
 fb: "https://www.facebook.com/weblog",
 linkedIn: "https://www.linkedin.com/company/weblog",
};

const news_letter_template = (reciverEmail) => {
 const msg = {
    to: reciverEmail,
    from: SENDER_EMAIL,
    subject: "newsletter",
    html: `<p>Dear subscriber,</p><p>Thanks for signing up for  
    newsletter!</p>
    <p> looking forward to hearing from you. </p>
       <p><a href="${weblog_social.insta}">Instagram</a></p>
      <p><a href="${weblog_social.fb}">Facebook</a></p>
        <p><a href="${weblog_social.linkedIn}">LinkedIn</a></p>
      `,
      };
       return msg;
     };

    export { news_letter_template };
  • Related