Slack query tutorial
Learn how to send messages and manage channels in Slack.
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
- Classic app
- Workflow or agent
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:
- In the Retool app IDE, open the Code tab, then click + in the page or global scope.
- Select Resource query.
- Choose your Slack resource.
- Select an operation and configure its parameters.
Workflows and agent custom tools use the same Resource query block to query Slack.
- Add a Resource query block to your workflow or custom tool's function canvas.
- Choose your Slack resource.
- Select an operation and configure its parameters.
Custom tools use the same block-based canvas as workflows, so the steps are identical in either context.
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.
{{ 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.
{
"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:
{
"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:
{
"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:
{
"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:
| Field | Value |
|---|---|
| Operation | GET /users.lookupByEmail |
{{ 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_cursorin the response. Pass it as thecursorparameter 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
200status with an"ok": falsefield and anerrorcode 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
okfield and validate response data structure before using it in your app. - Implement retry logic: For transient failures or rate limiting (
ratelimitederrors), 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.