SendGrid not sending from Netlify Functions

Hi,

so I created a function that sends an email using the SendGrid library. Everything is working fine locally with the Netlify CLI and all emails arrive. But as soon as I push my code and the function gets deployed live, the function executes but no email is arriving. I already described the issue here.

I already discovered this thread. But I don’t know exactly which IP I should add.

Hope someone can help
Max

Hi @m_glass,

This is how I did it now to test (and it works):

const sgMail = require('@sendgrid/mail')
exports.handler = async () => {
  sgMail.setApiKey(process.env.SENDGRID_API_KEY)
  return sgMail.send([{
    to: 'receiver1',
    from: 'sender',
    subject: 'subject',
    text: 'body to send'
  },
  {
    to: 'receiver2',
    from: 'sender',
    subject: 'subject',
    text: 'body to send'
  }]).then(() => {
    return {
      statusCode: 200,
      body: JSON.stringify('return something here')
    }
  })
}

You can always split the emails out in a different array like const emails = [{email1}, {email2}] and use return sgMail.send(emails). I just showed a simple example. You can and should use the .catch() block to handle errors too.

Note: The sender email address must be a verified sender configured here: SendGrid.

Your solution works fine locally but not on production.

Okay I got the solution: log in to SendGrid, go to IP Access Management and disable your IP Allow List (when this list is activated, only IP addresses listed in there are granted access - including API requests).

2 Likes

I am having the same problem - works in local, not in production.

In SendGrid, I have Address Allow List disabled and I have Single Sender Verification (SSV) and Domain Authentication setup.

I am using my SSV verified email address in my Netlify Function but still fails when deployed to Netlify on my development branch.

Could you share what you’ve tried like code examples? From my testing, the above code still works.

I would like to send two emails but just trying to successfully send the one right now - the second email code is commented out. Thanks for the quick reply @hrishikesh!

const client = require('@sendgrid/mail');

const {
    SENDGRID_API_KEY,
    SENDGRID_FROM_EMAIL,
} = process.env;

exports.handler = async function (event, context, callback) {
    const payload = JSON.parse(event.body).payload.data;

    const volunteerEmail = payload.email;
    const volunteerName = payload.fullname;
    const volunteerPronouns = payload.genderpronouns;

    if (volunteerPronouns == null) {
        volunteerPronouns = 'They/Them/Their'
    }

    const branchArr = payload.branch.split(",");
    const branchEmail = branchArr[0];
    const branchName = branchArr[1];

    client.setApiKey(SENDGRID_API_KEY);

    const msgToBranch = {
        to: `${branchEmail}`,
        from: SENDGRID_FROM_EMAIL,
        subject: "You have a new volunteer!",
        text: `${volunteerName} wants to join your branch.`,
        html: `<div>🌈</div>`,
    };

    // const msgToVolunteer = {
    //     to: `${volunteerEmail}`,
    //     from: SENDGRID_FROM_EMAIL,
    //     subject: `Thanks for reaching out to Sexpression:${branchName}`,
    //     text: `The branch committee member of Sexpression:${branchName} will reach out to you shortly.`,
    // };

    try {
       let response1 = await client.send(msgToBranch);
    //    let response2 = await client.send(msgToVolunteer);
        console.log(response1);
        return {
            statusCode: 200,
            body: JSON.stringify({ msg: response1}),
        };
    } catch (err) {
        return {
            statusCode: err.code,
            body: JSON.stringify({ msg: err.message }),
        };
    }

};

Hi @taz,

Nothing looks specifically off with the code.

What gets logged at console.log(response1)?

Netlify Dev / Local environment:
Email successfully sent and delivered.

[
  Response {
    statusCode: 202,
    body: '',
    headers: {
      server: 'nginx',
      date: 'Sun, 19 Sep 2021 11:11:47 GMT',
      'content-length': '0',
      connection: 'close',
      'x-message-id': 'oMDlHCB4TESttyMR_KORbw',
      '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'
    }
  },
  ''
]

Netlify Production on develop branch:
No email sent.

12:15:43 PM: 5af85624 Duration: 671.08 ms	Memory Usage: 74 MB	Init Duration: 206.78 ms

It looks like it doesn’t even get to the console.log to log anything…

Either that, or it’s skipping over that part. Could you try to use return chained syntax instead of try-catch to see if it makes a difference?

I believe it should not, but worth a try.

Hi all - sorry to resurrect this, but this is post is the top hit when searching for SendGrid and Netlify problems. None of these solutions worked for me, but after a lot of trial and error I hit on a solution that may or may not help you.

My solution was making sure that the function and Sendmail’s send was async. Here is my full code that I used to integrate a Stripe webhook with Netflify functions. I’m not a real developer so apologies if it’s a mess, but this works for me.

require("dotenv").config();

const stripe = require("stripe")(// YOUR_STRIPE)
const sgMail = require("@sendgrid/mail");
sgMail.setApiKey(// YOUR_SENDGRID);

exports.handler = async (event, context) => {
  const endpointSecret = // STRIPE_ES;
  const sig = event.headers["stripe-signature"];

  let stripeEvent = await stripe.webhooks.constructEvent(
    event.body,
    sig,
    endpointSecret
  );

  if (stripeEvent.type === "payment_intent.succeeded") {
    const blob = stripeEvent.data.object;
    const { id, amount, metadata } = blob;

    const msg = {
      to:  // SENDGRID_TO,
      from: // SENDGRID_FROM,
      templateId: // YOUR_TEMPLATE,
      dynamicTemplateData: {
// Your code to build your email
      },
    };
    await sgMail.send(msg);
    return { statusCode: 200 };
  } else {
// Handle other events
    return { statusCode: 400 };
  }
};

1 Like

Hi @sdmacdonald :wave:t6: ,

Thanks so much for sharing this solution with the community. We appreciate this greatly!

1 Like

This indeed worked for me. I changed it from:

sgMail.send(msg).then(() => {
context.status(200).end();
}).catch((error) => {
alert('Error: ', error);
context.status(500).end();

to

    await sgMail.send(msg);

And it is working now. Grateful for your response!!!

1 Like

Hi @OrgDevGroup :wave:t6: thanks for sharing that you were able to resolve your problem!

1 Like

I had a confusing issue where sometimes it would, and sometimes it would not send emails while locally everything worked.

Finally I noticed the in the Functions logs that the methods for sending emails were called but not finished. Weirdly when I’d do an unrelated REST call ten minutes later the emails would get sent.
Netlify seemed to pause and resume processes.

The emails were sent through a callstack of about five methods. In one of these I had forgotten to await the response.

So remember: when using promises or async/await, you’ll have to use them all the way down!

Hi @Sjeiti :wave:t6: ,

thanks for sharing your solution!