Skip to Content

Receive Slack events in Jitterbit Studio

Introduction

The Slack Events API delivers real-time notifications to a URL you register in your Slack app (for example, whenever a user posts a message in a channel). To receive these events in Studio, you configure an API Manager endpoint that accepts the inbound POST requests.

The Slack Events API has two requirements that differ from a standard webhook:

  • URL verification: When you first register the endpoint URL in your Slack app, Slack sends a challenge request. The endpoint must echo back the challenge value before Slack will deliver any events.
  • 3-second response window: Slack expects HTTP 200 within 3 seconds of sending an event. Operations that perform significant processing must dispatch that work asynchronously and return immediately.

This guide covers how to configure the API endpoint, handle URL verification, and receive incoming events. It stops at the point where the event payload is received and dispatched for processing. To route the payload to downstream operations, see Chain and control operations. For AI agent use cases where an LLM selects which operation to run based on the event, see Route LLM responses to Studio operations using function calling.

This guide assumes the following:

  • A custom API is configured and published in API Manager in the same environment as the project.
  • A Slack app exists with Event Subscriptions enabled. If you do not have one, create an app at api.slack.com/apps and enable Event Subscriptions in the app settings.
  • You are familiar with the basic steps for creating custom API endpoints.

Part 1: Create the API endpoint

Step 1: Create the API

  1. Open API Manager and click New API.

  2. Select Custom API as the API type.

  3. API Name: Enter a name for the API (for example, Slack Event Listener).

  4. URL Prefix: Enter a base path segment for the endpoint URL (for example, slack).

  5. Version: Enter a version string (for example, 1.0).

  6. Enable SSL: Enable this option. Slack only delivers events to HTTPS endpoints.

  7. Click Save.

Step 2: Configure the service endpoint

  1. In the API editor, click Add Service.

  2. Method: Select POST.

  3. Path: Enter an endpoint path (for example, /events).

  4. Operation: Select the Studio operation that will run when an event is received. This operation will contain the listener script described in Parts 2 and 3.

  5. Response Type: Select Variable.

  6. Click Save, then click Publish.

After publishing, copy the endpoint URL displayed by API Manager. You will enter this URL in the Slack app settings during the verification step.

Part 2: Handle URL verification

When you enter the endpoint URL in your Slack app's Event Subscriptions settings, Slack immediately sends a POST request to verify that the URL belongs to you. The request body contains a type field set to url_verification and a challenge field with a random token. The endpoint must return that token in the response body.

If the endpoint does not respond correctly, Slack rejects the URL and Event Subscriptions cannot be enabled.

Add the following check to the beginning of the listener script operation:

<trans>
$body = JSONParser($jitterbit.api.request.body);
$type = Get($body, "type");

If($type == "url_verification",
  $challenge_response = Dict();
  $challenge_response["challenge"] = Get($body, "challenge");
  $jitterbit.api.response = JSONStringify($challenge_response);
  $jitterbit.api.response.status_code = 200;
  Return();
);
</trans>

JSONParser parses the raw request body into a dictionary. Get extracts individual fields. When the type is url_verification, Dict creates a response dictionary, JSONStringify serializes it to JSON, and Return exits the script so that no event-processing logic runs for this request.

Warning

Slack signs every event delivery with an X-Slack-Signature HMAC-SHA256 header computed from the request body and your app's signing secret. This guide does not implement signature verification. Without it, the endpoint accepts event requests from any sender, not just Slack. For a production deployment, verify the signature in the listener script before processing any event. See Verifying requests from Slack in the Slack documentation.

Part 3: Receive event messages

After URL verification is complete, Slack sends event payloads for all activity matching the event types you subscribed to. Two additional checks are required before dispatching the event for processing.

Filter out bot messages

If your integration posts messages back to Slack (for example, as part of an AI agent or automated response), those messages generate new events that trigger the operation again. This creates an infinite loop. Filter out bot messages before processing:

<trans>
$botId = Get($body, "event.bot_id");
If(Length($botId) > 0,
  $jitterbit.api.response.status_code = 200;
  $jitterbit.api.response = "";
  Return();
);
</trans>

Slack sets event.bot_id on messages posted by bot users. If the field is present, the script acknowledges the event with HTTP 200 and exits without processing it.

Dispatch processing asynchronously

Slack cancels event delivery and retries if the endpoint does not respond within 3 seconds. Operations that call an LLM, query a database, or perform multiple steps will typically exceed this window.

Run the processing operation asynchronously using RunOperation with runSynchronously set to false, then set the response immediately:

<trans>
RunOperation("<TAG>operation:Process Slack Event</TAG>", false);
$jitterbit.api.response.status_code = 200;
$jitterbit.api.response = "";
</trans>

The false parameter tells Studio not to wait for the processing operation to complete. The listener script sets the 200 response and exits within milliseconds, satisfying Slack's timeout. The processing operation runs independently in the background.

For considerations around race conditions and concurrency limits when using asynchronous operations, see Manage asynchronous operations.

Complete listener script

The following script combines the URL verification check, bot filter, and async dispatch:

<trans>
$body = JSONParser($jitterbit.api.request.body);
$type = Get($body, "type");

// Handle Slack URL verification challenge
If($type == "url_verification",
  $challenge_response = Dict();
  $challenge_response["challenge"] = Get($body, "challenge");
  $jitterbit.api.response = JSONStringify($challenge_response);
  $jitterbit.api.response.status_code = 200;
  Return();
);

// Ignore messages from bots to prevent loops
$botId = Get($body, "event.bot_id");
If(Length($botId) > 0,
  $jitterbit.api.response.status_code = 200;
  $jitterbit.api.response = "";
  Return();
);

// Dispatch event processing asynchronously and respond immediately
RunOperation("<TAG>operation:Process Slack Event</TAG>", false);
$jitterbit.api.response.status_code = 200;
$jitterbit.api.response = "";
</trans>

The raw event payload remains available to downstream operations via $jitterbit.api.request.body. To respond to the user or post a message back to Slack after processing, see Send a Slack notification from a Studio operation.

Verify the integration

  1. Deploy the project and confirm the API endpoint is published in API Manager.

  2. In your Slack app settings, go to Event Subscriptions and paste the endpoint URL in the Request URL field. Slack sends the URL verification request automatically.

  3. Confirm that the Request URL field shows Verified. If verification fails, open the operation logs in Studio to check for errors, and confirm the endpoint URL is correct and the project is deployed.

  4. Under Subscribe to Bot Events, add the event types you want to receive (for example, message.channels or app_mention). Click Save Changes.

  5. Reinstall the app to your workspace if Slack prompts you to do so.

  6. Post a message in a Slack channel the bot is a member of.

  7. Open the operation logs in Studio and confirm that the listener operation ran and that the processing operation was dispatched.