Workflows
QueryDesk workflows are a way to automate processes using queries, API calls, slack messages, and more.
Overview
Workflows allow you to create automated processes that can:
- Execute database queries
- Make API calls to external services
- Send Slack notifications
- Require human approvals
- Make conditional decisions
- Reply to previous Slack messages
Each workflow consists of a series of steps that execute in order, with the ability to use outputs from previous steps as inputs to subsequent steps.
Triggers
Workflows can be triggered in several ways:
- Manual execution: Run workflows on-demand
- API: Trigger workflows via the API
- Cron schedule: Automatically run on a schedule using cron expressions
- Linear label: Trigger when a Linear issue gets a specific label
API
Workflows can be triggered via the API by calling this endpoint with inputs passed as a JSON body:
curl -X POST https://xxx.devhub.cloud/api/v1/workflows/wf_xxx/run \
-H "x-api-key: dh_xxx" \
-H "Content-Type: application/json" \
-d '{"user_id": "1234567890"}'
Cron Schedule
Use standard cron syntax to schedule workflow execution:
# Run every day at 2 AM UTC
0 2 * * *
# Run every Monday at 9 AM UTC
0 9 * * 1
# Run every hour
0 * * * *
Linear Label
Workflows can be triggered when a Linear issue gets a specific label. This requires setting up the Linear integration.
To pass inputs from the Linear issue each input must be added to the issue description in this format (this is the same format Linear templates use):
#### name
value
Inputs
Workflows can accept inputs that are provided when the workflow is triggered. These inputs can be used throughout the workflow execution.
Input Types
Workflows support the following input types:
- string: Text values
- integer: Whole numbers
- float: Decimal numbers
- boolean: True/false values
Using Inputs
Inputs are referenced using the ${input_name} syntax in:
- Step conditions
- Query strings
- API request bodies
- Slack messages
- Condition expressions
Example:
{
"user_id": "12345",
"email": "user@example.com",
"is_active": true
}
These can be used in workflow steps like:
- Query:
SELECT * FROM users WHERE id = '${user_id}' - Condition:
${is_active} == true - API Body:
{"user_id": "${user_id}", "email": "${email}"}
Step Conditions
Each step can have an optional condition that determines whether it should run. If the condition evaluates to false, the step is skipped.
Condition Syntax:
- Use input variables:
${input_name} - Use outputs from previous steps:
${step.step_name.output.field_name} - Basic operators:
==,!=,>,<,>=,<=,&&,||,not
Examples:
"${user_id}" == "12345"
"${step.query_step.output.rows[0][0]}" != ""
${is_active} && ${step.api_step.output.status_code} == 200
Using Outputs from Previous Steps
You can reference outputs from any previous step using this syntax:
${step.step_name.output.field_name}
When using outputs where a string is required, such as a query, make sure to wrap the output in quotes (e.g. "${step.query_step.output.rows[0][0]}").
Examples:
-
Accessing query results:
${step.user_lookup.output.rows[0][0]} // First row, first column -
Checking API responses:
${step.create_user.output.status_code} == 201 ${step.create_user.output.body.id} // User ID from a json response -
Using Slack message details:
${step.notification.output.channel} // Channel ID ${step.notification.output.timestamp} // Message timestamp -
Complex conditions:
${step.query_step.output.num_rows} > 0 && ${step.api_step.output.status_code} == 200
Query Action
Executes a database query using a specified credential.
Configuration:
- Database user: Select the credential to use for the query
- Query to run: SQL query (can use variables)
- Timeout (seconds): Maximum execution time
Output Shape:
{
"rows": [
["value1", "value2"],
["value3", "value4"]
],
"columns": ["column1", "column2"],
"command": "select",
"messages": [],
"num_rows": 2
}
Using Query Outputs:
- Access specific row/column:
${step.query_step.output.rows[0][0]} - Check row count:
${step.query_step.output.num_rows} > 0 - Access column names:
${step.query_step.output.columns[0]}
API Action
Makes HTTP requests to external APIs.
Configuration:
- Endpoint: Full URL for the API request
- Method: HTTP method (GET, POST, PUT, PATCH, DELETE)
- Headers: Key-value pairs for request headers, the value is stored encrypted in the database
- Body: Request body (can use variables)
- Expected status code: Status code that indicates success, if the status code is not the expected one, the workflow will fail.
- Include JWT: Whether to include a JWT that can be verified by external services.
Output Shape:
{
"status_code": 200,
"body": {
"id": "12345",
"name": "John Doe",
"email": "john@example.com"
}
}
Using API Outputs:
- Check status:
${step.api_step.output.status_code} == 200 - Access json response data:
${step.api_step.output.body.name} - Nested json access:
${step.api_step.output.body.user.profile.email}
Validating JWT:
If the option is enabled, the API call will include the x-devhub-jwt header in the request which will contain the following claims:
aud: The endpoint of the API callsub: The workflow run IDworkflow_id: The workflow ID
Slack Action
Sends a message to a Slack channel.
Configuration:
- Slack channel: Channel name (e.g., "#general")
- Message: Message content (can use variables)
- Link text: Text for the workflow link
Output Shape:
{
"channel": "C1234567890",
"timestamp": "1234567890.123456"
}
Using Slack Outputs:
- Channel ID:
${step.slack_step.output.channel} - Message timestamp:
${step.slack_step.output.timestamp}
Slack Reply Action
Replies to a previous Slack message in the same thread.
Configuration:
- Reply to step: Name of the step that sent the original message
- Message: Reply message content (can use variables)
Output Shape:
{
"channel": "C1234567890",
"timestamp": "1234567890.123457"
}
Approval Action
Requires human approval before the workflow can continue.
Configuration:
- Reviews required: Number of approvals needed
- Approvers: Users or roles that can approve
Condition Action
Evaluates an expression that only allows the workflow to continue if true.
Configuration:
- Expression: Boolean expression to evaluate
- When false, mark workflow as: What to do if condition is false (succeeded/failed)