Skip to main content

Slack query tutorial

After setting up a Slack integration with Retool, your Slack resource is available to use in the query editor. Slack queries are operation-based: you select an operation from Slack's API, rather than writing SQL.

Create a query

Switch to the new app builder

Retool recommends using the new app builder so you can use natural language to build React-based apps using AI.

To create a Slack query in a Retool app:

  1. In the Retool app IDE, open the Code tab, then click + in the page or global scope.
  2. Select Resource query.
  3. Choose your Slack resource.
  4. Select an operation and configure its parameters.

Select an operation

Available operations are derived from Slack's Web API. When you select an operation, the query editor displays the parameters and request body fields for that operation. Refer to Slack's API method reference for the complete list of operations and their parameters.

For example, select POST /chat.postMessage to send a message, or GET /conversations.list to retrieve channels.

Query configuration fields

Operation

The Slack API operation to call, shown as an HTTP method and path (for example, POST /chat.postMessage).

Parameters

Path, header, and query parameters for the selected operation, if any. For example, the GET /conversations.history operation accepts a channel query parameter to specify which channel to read.

Example
{{ channelSelect.value }}

Request body

For operations that accept a request body (typically POST requests), configure each field individually or provide the full body as JSON. Use embedded expressions to reference component values.

Example: send a simple message
{
"channel": {{ channelSelect.value }},
"text": {{ messageInput.value }}
}

Common use cases

The following examples demonstrate typical Slack operations in Retool apps. For complete parameter and request body references, refer to Slack's API method reference.

post a message to a channel

First, add a Select component (channelSelect) listing channel names or IDs, and a Text Input component (messageInput) for the message body.

Next, create a query with the POST /chat.postMessage operation and configure the request body:

Example request body
{
"channel": {{ channelSelect.value }},
"text": {{ messageInput.value }}
}

Then, add an event handler to a button's Click event that runs the query and displays a success notification.

list channels

Create a query with the GET /conversations.list operation to retrieve the workspace's channels.

Next, add a Table component to the app and set its Data property to {{ listChannelsQuery.data.channels }}.

upload a file to a channel

First, add a File Input component (fileInput1) to let a user select a file.

Next, create a query with the POST /files.upload operation and configure the request body:

Example request body
{
"channels": {{ channelSelect.value }},
"content": {{ fileInput1.parsedValue[0] }},
"filename": {{ fileInput1.value[0].name }}
}

Then, add an event handler to a button's Click event that runs the query.

reply in a thread

First, add a Table component displaying messages, so a user can select a message to reply to.

Next, create a query with the POST /chat.postMessage operation and configure the request body, using the selected message's timestamp as the thread_ts value:

Example request body
{
"channel": {{ channelSelect.value }},
"thread_ts": {{ table1.selectedRow.data.ts }},
"text": {{ replyInput.value }}
}

Then, add an event handler to a button's Click event that runs the query and refreshes the message list.

look up a user by email

Create a query with the GET /users.lookupByEmail operation and configure the email parameter:

FieldValue
OperationGET /users.lookupByEmail
email{{ emailInput.value }}

Next, display the returned profile fields, such as {{ lookupUserQuery.data.user.real_name }}, in a Text component.

Best practices

Follow these best practices to keep Slack queries fast, efficient, and safe.

Performance

  • Cache responses: For data that doesn't change frequently, such as a channel list, enable query caching to reduce API calls and improve response times.
  • Use pagination: Slack's list operations (like GET /conversations.list) return a next_cursor in the response. Pass it as the cursor parameter on the next request to page through large workspaces.
  • Batch notifications: Group related updates into a single message instead of sending one message per event to reduce the number of requests.
  • Minimize payload size: Request only the fields you need using the query parameters Slack's API supports for a given operation.
  • Set appropriate timeouts: Configure query timeouts based on expected API response times to prevent hung requests.

Data integrity

  • Validate user input: Sanitize and validate message text and channel identifiers before including them in a request body to prevent malformed requests.
  • Handle errors gracefully: Slack's API returns a 200 status with an "ok": false field and an error code for failed calls. Check this field in addition to the HTTP status code, and configure error notifications for failed queries.
  • Verify responses: Check the response's ok field and validate response data structure before using it in your app.
  • Implement retry logic: For transient failures or rate limiting (ratelimited errors), use Retool's automatic retry settings or implement custom retry logic with exponential backoff.
  • Log query activity: Enable query logging to track requests and responses for debugging and auditing.

Troubleshoot permission errors

If a query fails with a missing_scope error, the connected Slack app doesn't have the bot token scope required for that operation.

  • Missing scopes: Add the required scope to the resource's bot token scopes and reconnect with OAuth so the scope change takes effect.
  • Channel access: For operations on a specific channel, ensure the Slack app is a member of that channel. Use the POST /conversations.join operation, or invite the app manually in Slack.