How to setup webhooks with Streak on Tenklo

Learn how to receive real-time Streak events in your app using Tenklo webhooks

This guide shows you how to receive real-time Streak events in Tenklo by registering a webhook via the Streak API.

How it works

Streak supports outbound webhooks triggered by pipeline or team-level automations. The flow is:

  1. After a connection is created, a post-connection script generates a secret token, registers a webhook with Streak (passing the Tenklo webhook URL as targetUrl and the token as token), and stores the token in connection_config.streakWebhookToken.
  2. When the specified event occurs, Streak sends a POST to Tenklo with the token in the X-Streak-Webhook-Token header.
  3. Tenklo matches the token against connection_config.streakWebhookToken to identify the correct connection and forwards the event to your app.

Setup

1. Get your Tenklo webhook URL

Copy the webhook URL from your Streak integration page in the Tenklo dashboard, under the Webhook URL section.

2. Register the webhook via a post-connection script

Use a post-connection-creation script to automatically register the webhook with Streak whenever a new connection is created. The script generates a secret token, registers the webhook with Streak, and stores the token in the connection config for routing:

import { createOnEvent } from 'nango';
import { randomBytes } from 'crypto';

export default createOnEvent({
    event: 'post-connection-creation',
    description: 'Register a Streak outbound webhook and store the token for routing',
    exec: async (nango) => {
        // nangoConnectionId lets Nango check the token against this one connection
        const webhookUrl = `${await nango.getWebhookURL()}?nangoConnectionId=${encodeURIComponent(nango.connectionId)}`;
        const token = randomBytes(32).toString('hex');

        // Register the webhook with Streak
        // Specify either pipelineKey or teamKey depending on your use case
        // https://streak.readme.io/reference/create-a-webhook
        const response = await nango.post({
            endpoint: '/v2/webhooks',
            params: { pipelineKey: '<YOUR_PIPELINE_KEY>' },
            data: {
                event: 'BOX_EDITED',
                targetUrl: webhookUrl,
                token,
            },
        });

        // Store the token in connection config for webhook routing
        // streakWebhookToken: matched against X-Streak-Webhook-Token header to identify this connection
        // streakWebhookKey: used to delete the webhook when the connection is removed
        await nango.updateConnectionConfig({
            streakWebhookToken: token,
            streakWebhookKey: response.data.key,
        });
    }
});

Replace event with the Streak event type you want to subscribe to (e.g. BOX_CREATED, BOX_EDITED). See Streak's event list for all available events.

3. Handle forwarded webhooks

When a Streak event fires, Tenklo matches the X-Streak-Webhook-Token header against connection_config.streakWebhookToken to identify the connection, then forwards the event to your app. Example payload structure:

{
  "from": "streak",
  "providerConfigKey": "streak",
  "type": "forward",
  "payload": [{
    "eventType": "BOX_EDITED",
    "pipelineKey": "agxzfm1haWxmb29...",
    "boxKey": "agxzfm1haWxmb29...",
    "timestamp": 1700000000000
  }],
  "connectionId": "connection-123"
}

If the X-Streak-Webhook-Token header is missing, or does not match the connection in nangoConnectionId, Tenklo rejects the request. Without nangoConnectionId, a token that matches no connection is dropped.

4. Delete the webhook on connection removal

Use a pre-connection-deletion script to clean up the Streak webhook when a connection is deleted:

import { createOnEvent } from 'nango';

export default createOnEvent({
    event: 'pre-connection-deletion',
    description: 'Delete the Streak webhook before connection deletion',
    exec: async (nango) => {
        const connectionConfig = await nango.getConnectionConfig();
        const webhookKey = connectionConfig['streakWebhookKey'];

        if (!webhookKey) {
            return;
        }

        try {
            await nango.delete({
                endpoint: `/v2/webhooks/${webhookKey}`,
                headers: { 'Content-Type': 'application/json', accept: 'application/json' }
            });
        } catch (err) {
            await nango.log(`Failed to delete Streak webhook: ${String(err)}`, { level: 'error' });
        }
    }
});
Need help getting started? Join us in the community.

On this page