How to use Airtable Webhooks on server: A mini Guide Using Express.js and Ngrok (for local development)

·

3 min read

Things you are going to need first:

  • A Ngrok account (A service with a free tier that provides an accessible link to your local server) so that you can receive notification pings on your local server

  • An Airtable access token

  • The base's ID

  • The table's ID

Please refer to the Airtable docs if you do not know how to identify a base's and a table's ID

Few things to know before using Airtable Webhooks

  • Airtable has an expiring link feature for its public images. These links expire after every 2 hours and they generate a new link for it. So, if you are planning to use webhooks to get a notification ping upon this change of hosted link, then I'm sorry to break your heart but it did not work for me. They haven't specified it anywhere in the docs so it's likely that it will not send a notif to your server.

  • You can only create 10 webhooks per base on the free tier plan (when using tokens)

  • The Webhook ID expires every 7 days. So you are required to change it every week. This means every week you are required to make a process where

    1. Create a webhook and get its ID

    2. Use the ID and enable a notification ping for it

    3. Set a process to be used upon a ping is received

    4. Watch the expiration time and refresh the webhook (The new expiration time will be extended for another 7 days)

Getting started:

1) Set the webhook: manage scope at https://airtable.com/create/tokens

2) Creating a webhook:

var myHeaders = new Headers();
// make sure to get your airtable token and paste it here
myHeaders.append("Authorization", `Bearer ${process.env.Airtable_Key}`);
myHeaders.append("Content-Type", "application/json");

var raw = JSON.stringify({
    // please view the 6th step to understand how you can get a ngrok link
    "notificationUrl":"https://A-NGROK-LINK-TO-WORK-ON-LOCAL/notif-ping",
    "specification": {
        "options": {
            "filters": {
                "dataTypes": [
                    "tableData"
                ],
                "recordChangeScope": "tbl0000000" // the table's id
            }
        }
    }
});

var requestOptions = {
    method: 'POST',
    headers: myHeaders,
    body: raw,
    redirect: 'follow'
};

// create webhook
fetch(`https://api.airtable.com/v0/bases/${BASE_ID}/webhooks/`, requestOptions)
     .then(response => response.text())
     .then(result => console.log(result))
     .catch(error => console.log('error', error));

3) Enabling a webhook to serve notification pings

var notifHeaders = new Headers();
notifHeaders.append("Authorization", `Bearer  ${process.env.Airtable_Key}`);
notifHeaders.append("Content-Type", "application/json");

var rawNotifBody = JSON.stringify({
    "enable": true
});

var requestOptionsNotif = {
    method: 'POST',
    headers: notifHeaders,
    body: rawNotifBody,
    redirect: 'follow'
};

// enable webhook to give pings
fetch(`https://api.airtable.com/v0/bases/${BASE_ID}/webhooks/${WEBHOOK_ID}/enableNotifications`, requestOptionsNotif)
    .then(response => response.text())
    .then(result => console.log(result))
    .catch(error => console.log('error', error));

4) Refresh a webhook

var myHeaders = new Headers();
myHeaders.append("Authorization", `Bearer ${process.env.Airtable_Key}`);

var requestOptions = {
    method: 'POST',
    headers: myHeaders,
    redirect: 'follow'
};

// refresh webhook
fetch(`https://api.airtable.com/v0/bases/{baseId}/webhooks/{webhookId}/refresh`, requestOptions)
     .then(response => response.text())
     .then(result => console.log(result))
     .catch(error => console.log('error', error));

5) Listen for a notification ping

const dotenv = require('dotenv');
let express = require('express');
const cors = require('cors');
const http = require("http");

let app = express();
const server = http.Server(app);

dotenv.config();

app.use(cors({
    origin: '*' //this will enable anyone to ping your server and receive data from it. Please use it for only public APIs
}));

// receive a ping on /notif-ping
app.post('/notif-ping', (req, res) => {
    console.log(req);
    res.sendStatus(200).end();
});

server.listen(3000, () => {
    console.log('listening on 3000')
})

6) Run this Ngrok command to set up a link that will redirect to your local server (use the link provided by them as a notification URL, please view the code in 2nd step)

ngrok http 3000

Hopefully, this guide can help you get started on making a slick server backed by Airtable ❤