Airtable
Overview of the Airtable provider and registering webhooks
Overview
There are three ways to interact with the Airtable API through our platform:
Airtable API Quirks
Every Airtable REST API request requires a baseId
and a tableId
. You can find these values in the URL of your Airtable base and table. We provide a hook to help you get the baseId
and tableId
values for your users.
Airtable doesn’t support events
like you noramally would use. Instead you subscribe to specifec events by passing a JSON config object. We provide a helper function to generate this for you. See a couple steps below on how it works.
Creating a Webhook for a User
-
Base ID Retrieval: You can use our hook to get the
baseId
for your users. Theimport { useGetAirtableBaseIds } from 'syncd-hooks'; ... const { data: airtableBaseIds, isLoading: airtableBaseIdsIsLoading } = useGetAirtableBaseIds(); ... {airtableBaseIds?.bases?.map((base) => ( <option key={base.id} value={base.id}> {base.name} </option> ))} ...
-
Table ID Retrieval: You can use our hook to get the
tableId
for your users. Theimport { useGetAirtableTables } from 'syncd-hooks'; ... const { data: airtableTables, isLoading: airtableTablesIsLoading } = useGetAirtableTables(); ... {airtableTables?.tables?.map((table) => ( <option key={table.id} value={table.id}> {table.name} </option> ))} ...
-
Create a webhook for the user using the previously collected data:
/**
* We use JSDocs in the SDK to give you the best experience possible.
* If you need to know what a function does, you can hover over it in your IDE.
* If you need to know why you need a projectId for example, you can hover over it.
*/
const res = await syncdClient.providers.airtable.webhooks.create({
// This is a dummy URL. You will need to replace it with your own or your external user's URL.
callbackUrl: "https://api.my-api.com/api/webhooks/airtable",
// You can use this in the dashboard to easily identify the webhook.
endpointName: `${user.id} - Airtable Webhook`,
endpoindDescription: "DEV - Airtable Webhook",
webhookSpec: generateAirtableWebhookSpec({
tableId // Get this from the above hook useGetTables
})
// Syncd uses projects to group webhooks and users. You will need to create a project first and copy the ID.
projectId: process.end.NEXT_PUBLIC_SYNCD_PROJECT_ID, // If you are using NEXT.js you can preface this with NEXT_PUBLIC to expose this to the client
accessToken: <your-users-access-token>, // make sure the provider you use refreshes these tokens before passing it to us
// This is an optional object that you can use to create an external user
externalUser: {
// If you do choose this option, you will need to provide a uniqueId
uniqueId: user.id,
firstName: user.firstName, // Optional
lastName: user.lastName, // Optional
// Any key value pairs you want to store with the user
metadata: {
email: "john@doe.com",
},
},
});
Note: there was a helper function used generateAirtableWebhookSpec
. You can import this from our SDK and it will allow you to generate the correct JSON.
Updating a Webhook
One thing Airtable doesn’t allow is updating a webhook. We support that by keeping a record of the old data and then deleting the old webhook and creating a new one. This is done in the background and you don’t have to worry about it. It would look something like this:
await syncdClient.providers.airtable.webhooks.update({
...
})
Airtable doesn’t directly support this. BUT, we do. This is useful if you want to change the callbackUrl
or webhookSpec
. The resulting webhook will be under the same project and endpointID so you don’t need to worry about updating things in your database/storage.
Note if you use Syncd for Oauth access tokens then we keep an internal cursor
of the step that you are at. This might seem weird, but Airtable doesn’t acutally send you events, they send you an ID everytime an event happens and then you have to fetch the data of the events. The issue is, they return every event you have ever had. So we keep an internal cursor that maintains the current position. If you update the webhook without us, we can’t keep track of the internal curor, and instead you will have to on your end.
Example:
/**
* We use JSDocs in the SDK to give you the best experience possible.
* If you need to know what a function does, you can hover over it in your IDE.
* If you need to know why you need a projectId for example, you can hover over it.
*/
const res = syncdClient.providers.airtable.webhooks.update({
accessToken: "<your-access-token>",
baseId: "<your-base-id>",
tableId: "<your-table-id>",
webhookSpec: generateAirtableWebhookSpec({
tableId: "<your-table-id>",
}),
endpointId: "<your-endpoint-id>",
endpointDescription: "<your-endpoint-description>",
endpointName: "<your-endpoint-name>",
// This is option
metadata: {
email: "test@test.com",
},
});
Special case (only if you use a third party for handeling access tokens)
If you use the SDK
to create a webhook, and you don’t use Syncd for managing the OAuth access tokens, then your webhook body that get’s sent to you is actually just a webhookId
. You can use this webhookId
to get the webhook body. We do provide a helper function that you can pass your access token to, and it will return the webhook body. This has to be done on your webhook endpoint. It would look something like this.
import { getAirtableWebhookBodyFromId } from '@syncd-sdk';
...
const body: TAirtableWebhookIdBody = await req.json();
// This function handles the cursor pagination and retrieves the body that is associated with the webhookId
const actuallWebhookBody = await getAirtableWebhookBodyFromId({
webhookId: body.webhookId,
accessToken: <your-users-access-token>,
});
...
Example Payloads
Airtable doesn’t support traditional events. They instead support a
Types
TDefaultPayloadEvent