Hooked on Webhooks
TLDR
Triplit database events can now be sent to outside APIs with the new webhooks feature, now in developer preview.
Webhooks: Developer Preview
As mentioned last week, we're working on a feature that will allow you to subscribe to events in a Triplit database via webhooks. We're excited to announce that we've released a developer preview of this feature on the Triplit Server. This preview is available in development (i.e. using triplit dev
) and for self-hosted instances of Triplit. We'll be rolling it out to our hosted customers in the coming weeks while we collect your feedback.
Configuration
Webhooks for Triplit servers are configured with a simple JSON object that specifies the URLs to send events to, the collections to watch, and the events ("inserts", "updates", and "deletes") to watch for. Here's an example configuration:
{
"https://my-api.dev/webhook": {
"todos": { "inserts": true, "updates": true, "deletes": true }
}
}
CLI
You can then push this configuration to your Triplit server with the triplit webhooks push
command. The server will save the configuration to storage and begin sending events to the specified URLs.
You can view a server's current webhook configuration with the triplit webhooks print
command.
You can remove a webhook configuration from a server with the triplit webhooks clear
command.
Security
Webhooks are sent with a 'x-triplit-signature' header that contains a HMAC256 signature of the payload. It is signed with a symmetric secret, the TRIPLIT_WEBHOOK_SECRET
environmental variable. This variable must be set in your env for webhooks to send. Here's a simple example of how you might verify the signature in Node.js:
import { Hono } from 'hono';
import * as crypto from 'crypto';
const app = new Hono();
app.post('/', async (c) => {
const body = await c.req.text();
const secret = process.env.TRIPLIT_WEBHOOK_SECRET;
const secretBytes = Buffer.from(secret, 'base64');
const signature = c.req.header('x-triplit-signature');
if (!signature) {
return c.text('No signature');
}
const hash = crypto
.createHmac('sha256', secretBytes)
.update(body)
.digest('base64');
const isVerified = crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(hash)
);
// If the signature is verified, process the webhook
return c.text('OK');
});
export default app;
Payload
Based on the configuration above, the webhook would send a payload like this when a todo is inserted:
{
"collectionName": "todos",
"inserts": [
{
"id": "123",
"text": "Buy milk",
"completed": false
}
],
"updates": [],
"deletes": []
}
Other improvements
- Addressed an issue preventing queries from connecting from some React apps running in development mode.
- Increased the limit on the size of bulk inserts to a Triplit server to 100 MB.
- Fixed a memory leak in
@triplit/db
.