Ingesting slack message history

Issue: Slack Event Subscriptions cannot verify Retool Workflow webhook URLs

We're trying to use a Retool Workflow as a receiver for Slack's Events API so that incoming Slack messages can trigger a Retool Agent. The blocker is at the verification step.

When you paste a Retool Workflow webhook URL into Slack's Event Subscriptions Request URL field, Slack sends a challenge parameter that the endpoint must echo back to confirm ownership. Retool Workflow webhooks fail this check because:

  1. The default webhook URL requires an API key in the header, which Slack cannot send during verification

  2. The "Public" checkbox that would generate a keyless URL cannot be enabled — it appears greyed out even after publishing the workflow

  3. The workflow code itself is correctly written to handle the challenge response, but Retool doesn't appear to return it synchronously in a way Slack accepts

What we need: Either a way to make a Retool Workflow webhook URL publicly accessible without API key authentication, or a way for the webhook trigger to respond synchronously to Slack's challenge verification request.

Workaround we're currently exploring: Using a third-party relay (Pipedream or Hookdeck) to sit between Slack and Retool, which adds unnecessary complexity to what should be a straightforward integration.

Hi @Tess_Moran

RE:
1. The default webhook URL requires an API key in the header, which Slack cannot send during verification
Are you able to put the API Key in a query string parameter instead? You can use the “workflowApiKey” query string parameter to provide the key instead of a header.

Does that solve 1. ?

Also, for:
3. The workflow code itself is correctly written to handle the challenge response, but Retool doesn't appear to return it synchronously in a way Slack accepts
Slack expects a response in under 3 seconds when it makes a Challenge request. In the form:
{ "type": "url_verification", "challenge": "abc123…", "token": "…" }

You must echo back this challenge in the Body of the Response using a Synchronous Workflow with a Response block. This must only be done if the Workflow Trigger has “url_verification” in the type property. So you would need a Branch block at the beginning to respond quickly to the Challenge.

Check for:
{{ startTrigger.data.type === "url_verification" }}

For the non-Challenge execution path you could consider Queueing another Workflow to perform the actual event processing, so as not to breach the Synchronous Workflow timeout limit, then return a 200 in a Response Block (with no body).

Let me know if this makes sense - I can help further if required.

Thanks

2 Likes

Solid answer above from @Jon_Steele.

On the greyed-out Public checkbox that you mentioned in the second time — you can just ignore it. Authenticating with workflowApiKey in the URL means you don't need Public at all. Only catch is the key sits in the URL, so it can show up in logs.

Before anything else though, check Slack can actually reach your endpoint. If your instance is behind a VPN or private network, it won't connect however you set the workflow up. Quick test: grab the cURL, add ?workflowApiKey=..., and run it from a machine off your network with {"type":"url_verification","challenge":"test123"}. If test123 comes back, you're good. If not, it's not public and you'll need something in front of it — which is exactly what a relay is for.

Cheers,
Jordan

@Tess_Moran hi, did any of these posts help with your issue at hand? Please kindly get back and let us know!

Cheers!

Hi @Tess_Moran as it’s been 2 weeks since your last response I will mark the above as a solution, thanks.