Published on

Using Resend Webhooks to Send Email Status Alerts to Slack

Authors
  • avatar
    Name
    Ken Ruf
    Twitter

Cover image

Svix is the enterprise ready webhooks sending service. With Svix, you can build a secure, reliable, and scalable webhook platform in minutes. Looking to send webhooks? Give it a try!

Today we're showing off a super useful webhook feature from Resend, that lets you send webhook notifications when emails are opened or when a link in an email is clicked. If you're not familiar with Resend, they are an email API for developers.

When you're sending emails to customers or to leads, it can be useful or even critical to understand how people are interacting with your messages and to respond to them in a timely manner. With Resend's webhooks, you can receive real time alerts and automate your responses. In this demo we'll show how to setup webhooks in Resend, receive them and verify the signature, and send a notification to Slack.

First, we set up a webhook in Resend's developer portal:

Choose the event types you want to receive messages for and add an endpoint URL:

If you don't have an endpoint ready yet, you can use Svix Play to get a test endpoint to get things going. We'll be showing a sample endpoint a bit later as well.

Ok, so for this demo we just checked off the email.clicked event. For email.clicked and email.opened, you'll need to set up tracking for the domain you're using to send emails with Resend. You can do so in the Domains tab. The configuration to enable open and/or click tracking is at the bottom of the page:

Now that we've set up our webhook in Resend, we'll need to send some emails to test it out. We built a very simple demo which you can find here.

The main things we need to do to set up our Slack notifications using Resend is to create our email template, send the email, and receive the webhook. We mostly used two examples from Resend as our guides. They're really well put together and easy to follow in case you get stuck:

Node.js Example Webhook Example

  1. Email template

We made a very simple email template announcing the launch of our webhook receiving product Ingest, that receives the first name of the recipient as a prop.

import * as React from 'react'

interface EmailTemplateProps {
  firstName: string;
}

export const EmailTemplate: React.FC<Readonly<EmailTemplateProps>> = ({ firstName }) => (
  <div>
    <h1>Hi, {firstName}!</h1>
    <p>
      We just launched Svix Ingest, a reliable and scalable webhook receiver so that anyone can have
      a great developer experience when receiving webhooks.
    </p>
    <p>You can learn more about Ingest and try it out here:</p>
    <a href="https://www.svix.com/ingest">https://www.svix.com/ingest</a>
  </div>
)
  1. Send the Email

Next, we set up an API route to send the email using the email template we just made:

import type { NextApiRequest, NextApiResponse } from 'next'
import { EmailTemplate } from '../../components/email-template'
import { Resend } from 'resend'

const resend = new Resend(process.env.RESEND_API_KEY)

export default async (req: NextApiRequest, res: NextApiResponse) => {
  try {
    const { data, error } = await resend.emails.send({
      from: 'Svix <svix@whatisawebhook.com>',
      to: ['ken@svix.com'],
      subject: 'Announcing Ingest: Reliable Webhook Receiver',
      react: EmailTemplate({ firstName: 'Ken' }),
    })

    if (error) {
      res.status(400).json({ error })
    }

    res.status(200).json({ data })
  } catch (error) {
    res.status(400).json({ error })
  }
}

And a simple button to call the api:

'use client'

export default function Home() {
  const send = () => {
    try {
      const response = fetch('/api/send', {
        method: 'GET',
        headers: { 'Content-Type': 'application/json' },
      })

      console.log('email sent')
    } catch (error) {
      console.log(error)
    }
  }

  return (
    <div>
      <button onClick={send}>Send Email</button>
    </div>
  )
}

Here is the email we received when we clicked our button:

  1. Receive the Webhook & Send it to Slack

Now that the email sending works, we need to set up an endpoint to receive the webhook messages from Resend. We'll first need to verify the signature to make sure that the webhooks are actually from Resend and not a malicious actor.

import type { NextApiRequest, NextApiResponse } from 'next';
import { WebhookRequiredHeaders } from 'svix';
import { buffer } from 'micro';
import { IncomingMessage } from 'http';
import { WebhookEvent } from '../../types';
import { sendSlackMessage } from '../../utils';
import { Webhook } from 'svix';

export const config = {
    api: {
      bodyParser: false,
    },
  };

const webhooks = async (req: NextApiRequest, res: NextApiResponse) => {
  const { method } = req;

  switch (method) {
    case 'POST': {
      try {
        const payload = (await buffer(req)).toString();

        const headers = req.headers as IncomingMessage['headers'] & WebhookRequiredHeaders;

        const webhook = new Webhook(process.env.WEBHOOK_SECRET);

        const event = webhook.verify(payload, headers) as WebhookEvent;

        if (event.type === 'email.clicked') {
          sendSlackMessage(event);
        }

        return res.status(200).end();
      } catch (error) {
        return res.status(400).send(error);
      }
    }
    default:
      res.setHeader('Allow', ['POST']);
      res.status(405).end(`Method ${method} Not Allowed`);
  }
};

export default webhooks;

In order to get the Slack Notification, we need to set up a Slack app with incoming webhooks enabled. Luckily we already had a Slack app that I could use for this demo but if you don't have one set up yet, you can checkout our Slack webhook guide for instructions on how to set one up.

And here are the Slack notifications:

Slack screenshot

You could imagine instead of sending a Slack message, you could schedule another email in a sequence, or update your lead scoring. You can really get creative with the types of integrations and automations to build and that is why we love webhooks.

Want us to demo one of your webhook use cases? Let us knoww.


For more content like this, make sure to follow us on Twitter, Github, RSS, or our newsletter for the latest updates for the Svix webhook service, or join the discussion on our community Slack.