# GitHub Webhooks using Next.js API Routes

Have you ever wanted to send a Discord notification for every push to a repository? Well, this guide will cover the basics of how to listen to GitHub webhook events via a Next.js API route. We will set up a simple Next.js API route that will listen to "push" events and then trigger a Discord notification. This will be connected to a repository of your choosing.

**Prefer to just read the code? Check out the** [**repository here**](https://github.com/withbackdrop/github-webhook-next-js)**!**

## **How It Works**

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1691070809212/6d6f6045-3b8f-4e28-983f-e3ada8db5899.png align="center")

* A developer triggers some event on [GitHub](https://github.com/)
    
    * For example, they could push a commit to a repository
        
* A GitHub webhook is configured to forward the event to an API route
    
* In the API route, you can perform any further actions you like depending on the event type
    
    * For example, you could trigger a [Discord](https://discord.com/) notification to any pushes to a repository
        

## **Prerequisites**

* Knowledge of [React](https://react.dev/) and [**Next.js**](https://nextjs.org/) **(specifically version 13)** which is used to build the example application
    
* How to use Git
    
* A GitHub repository
    

## **Setup**

* To begin with, you will need to create a new POST API route in the `/app/api/` directory. For example `example/app/api/github-discord-webhook/route.ts`
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1691071398323/fffac47c-8f5d-47eb-9692-263e41cef10a.png align="center")
    
* The contents of this file could look like the following. Make sure you have all the dependencies as stated as well as your DISCORD\_WEBHOOK\_URL.
    
    ```typescript
    import { headers } from 'next/headers';
    import { MessageBuilder, Webhook } from 'discord-webhook-node';
    
    async function sendGithubCommitPushed() {
      const hook = new Webhook('DISCORD_WEBHOOK_URL');
      hook.setUsername("Webhook Username");
    
      const embed = new MessageBuilder()
          .setTitle(`Wahoo! someone just made a new push!`)
          .setAuthor('Notification Service')
          .setTimestamp();
      await hook.send(embed);
    }
    
    export async function POST(request) {
      const headersList = headers();
    
      const eventName = headersList.get("x-github-event");
      const payload = await request.json();
    
      try {
        if (eventName === 'push') {
          await sendGithubCommitPushed(payload.commits?.[0].message);
        }
      } catch (error) {
        return new Response('Something went wrong', {
          status: 500,
        });
      }
    
      return new Response('Event processed', {
        status: 200,
      });
    }
    ```
    
* Head on over to your GitHub repositories settings, e.g. *https://github.com/my-organization/my-repository/settings*, and then navigate to Webhooks.
    
* Select **Add webhook** and provide the following settings:
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1691072601023/63ca284a-f899-4e1c-a7d0-6d1caa36470d.png align="center")
    
    *Note: For this example setup we are skipping the Secret. However, for additional security, you should consider adding one. You can follow this* [*example*](https://gist.github.com/Keith-Hon/ed48526c3d9a249d5d56048df6172762) *to do that.*
    
* Click on **Add webhook** to save your changes.
    
* Everything should now be set up for your application to trigger Discord notifications for every Push event!
    
* You can find a list of all event types [here](https://docs.github.com/en/webhooks-and-events/events/github-event-types), as well as the payload contents.
    

## **Testing**

You are probably now wondering how you could test this in your local environment? To do this we will use [ngrok](https://ngrok.com/docs/integrations/github/webhooks/) which will create a public proxy for you. Below I have simplified the process:

* Install ngrok. You find all available methods [here](https://ngrok.com/download).
    
    For example, on Ubuntu, you can run `sudo snap install ngrok`
    
* Start ngrok making sure the port matches that of your local server. You can run:
    
    `ngrok http 3000` and you should see something like the below:
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1691073483027/830391e7-dfc0-43ef-a85b-f956e87c3c7a.png align="center")
    
* Configure your GitHub webhook settings so the Payload URL points to the ngrok URL that was generated e.g. https://0fe0-86-56-85-54.ngrok.io/api/github-discord-webhook
    
* You can now either push something to your repository or redeliver recent events via the **Recent Deliveries** GitHub Webhooks UI
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1691074118350/a51fc546-d96c-4568-8ada-37f8eaafd68e.png align="center")
    

## **Questions & Feedback**

If you have any questions or feedback, please do not hesitate to [**contact me**](https://twitter.com/strange_quirks)! There is always room for improvement!
