GitHub Action
Slack: Send to Slack
the GitHub Action for sending data to Slack
For examples on how to leverage this Action in workflows, check out example workflows we have available.
There are different techniques to send data into Slack and whichever one is chosen will require a certain set of customized inputs, as described later.
You can provide data to send to Slack from this GitHub Action and either source:
- The default event context with a payload matching the GitHub event.
- A custom payload with optional variables provided in the GitHub Action step.
These input options are valid for all techniques, but some techniques require specific constraints with certain requirements for valid inputs.
Additional configurations and other details are also available for more customizations to the provided payload.
This Action offers three different techniques to send data to Slack:
- Technique 1: Send data with a webhook to start a workflow in Workflow Builder.
- Technique 2: Send data using a Slack API method and a secret token with required scopes.
- Technique 3: Send data as a message with a Slack incoming webhook URL.
📝 This technique requires a Slack paid plan to use Workflow Builder.
This technique sends data to Slack using a webhook to start a workflow created using Slack Workflow Builder.
Start in Slack to create a Slack workflow:
- Create a Slack workflow that starts from a webhook.
- Copy the webhook URL and add it as a repository secret called
SLACK_WEBHOOK_URL
. - Add this Action as a step to your GitHub workflow and provide an input payload to send to the webhook.
- Configure your Slack workflow to use the payload variables sent from the GitHub Action. You can then update the steps of the Slack workflow to use these values in creative and clever ways.
The webhook URL will resemble something like so:
https://hooks.slack.com/triggers/T0123456789/3141592653589/c6e6c0d868b3054ca0f4611a5dbadaf
Update the input payloads sent from this GitHub Action to your Slack workflow using the following options:
In the example below, the default GitHub event context and event payload associated with the job that started the GitHub workflow are sent to the provided webhook URL:
- name: Send GitHub Action data to a Slack workflow
uses: slackapi/[email protected]
with:
payload-delimiter: "_"
webhook: ${{ secrets.SLACK_WEBHOOK_URL }}
webhook-type: webhook-trigger
Accessing variables sent to Workflow Builder with a webhook require that
the payload variables are flattened with stringified values. Nested variables in
the provided payload can be both flattened and also stringified with the
payload-delimiter
option or changed with other
configurations to match this format expected from
Workflow Builder.
Provided input values for payload information are sent to the webhook URL after the job is started:
- name: Send custom event details to a Slack workflow
uses: slackapi/[email protected]
with:
webhook: ${{ secrets.SLACK_WEBHOOK_URL }}
webhook-type: webhook-trigger
payload: |
status: "${{ job.status }}"
option: "false"
Input values for the payload to be sent can also be provided in a file, either in JSON or YAML format:
- name: Send a saved artifact to a Slack workflow
uses: slackapi/[email protected]
with:
payload-file-path: "./artifacts.json"
webhook: ${{ secrets.SLACK_WEBHOOK_URL }}
webhook-type: webhook-trigger
A bot token or user token or token of some other kind must be used to call one of the Slack API methods with this technique.
Different Slack API methods require different scopes, but setup should be similar for all methods:
- Create a Slack app for your workspace or use an existing app.
- Depending on the Slack API method you wish to call, add the required scopes to your app under the OAuth & Permissions page on app settings.
- Install the app to your workspace using the Install App page.
- Once your app is installed to a workspace, a new token with your app's specified scopes will be minted for that workspace. It is worth noting that tokens are only valid for a single workspace! Find the token on the OAuth & Permissions page.
- Add the token as a repository secret called
SLACK_BOT_TOKEN
or something similar and memorable. - Add this Action as a step to your GitHub workflow and provide an input payload to send to the method.
Methods that require an app configuration token should gather this token from the app configuration token settings instead of from a specific app since this token is associated with the workspace.
Choosing inputs for these steps is left as an exercise for the actioneer since each of the Slack API methods requires certain values and specific parameters, but these snippets might be helpful when starting.
Posting a message with the chat.postMessage
method can be
achieved by adding this step to a job in your GitHub workflow and inviting the
bot associated with your app to the channel for posting:
- name: Post text to a Slack channel
uses: slackapi/[email protected]
with:
method: chat.postMessage
token: ${{ secrets.SLACK_BOT_TOKEN }}
payload: |
channel: ${{ secrets.SLACK_CHANNEL_ID }}
text: "howdy <@channel>!"
More complex message layouts, such as messages made with Block Kit blocks, can also be sent with one of the Slack API methods:
- name: Post blocks to a Slack channel
uses: slackapi/[email protected]
with:
method: chat.postMessage
token: ${{ secrets.SLACK_BOT_TOKEN }}
payload: |
channel: ${{ secrets.SLACK_CHANNEL_ID }}
text: "GitHub Action build result: ${{ job.status }}\n${{ github.event.pull_request.html_url || github.event.head_commit.url }}"
blocks:
- type: "section"
text:
type: "mrkdwn"
text: "GitHub Action build result: ${{ job.status }}\n${{ github.event.pull_request.html_url || github.event.head_commit.url }}"
Updating a message after it's posted can be done with the
chat.update
method and chaining multiple steps together using
outputs from past steps as inputs to current ones:
- name: Initiate the deployment launch sequence
id: launch_sequence
uses: slackapi/[email protected]
with:
method: chat.postMessage
token: ${{ secrets.SLACK_BOT_TOKEN }}
payload: |
channel: ${{ secrets.SLACK_CHANNEL_ID }}
text: "Deployment started :eyes:"
attachments:
- color: "dbab09"
fields:
- title: "Status"
short: true
value: "In Progress"
- name: Countdown until launch
run: sleep 10
- name: Update the original message with success
uses: slackapi/[email protected]
with:
method: chat.update
token: ${{ secrets.SLACK_BOT_TOKEN }}
payload: |
channel: ${{ secrets.SLACK_CHANNEL_ID }}
ts: "${{ steps.launch_sequence.outputs.ts }}"
text: "Deployment finished! :rocket:"
attachments:
- color: "28a745"
fields:
- title: "Status"
short: true
value: "Completed"
Posting threaded replies to a message from a past job can
be done by including the thread_ts
attribute of the parent message in the
payload
:
- name: Initiate a deployment
uses: slackapi/[email protected]
id: deployment_message
with:
method: chat.postMessage
token: ${{ secrets.SLACK_BOT_TOKEN }}
payload: |
channel: ${{ secrets.SLACK_CHANNEL_ID }}
text: "Deployment started :eyes:"
- name: Conclude the deployment
uses: slackapi/[email protected]
with:
method: chat.postMessage
token: ${{ secrets.SLACK_BOT_TOKEN }}
payload: |
channel: ${{ secrets.SLACK_CHANNEL_ID }}
thread_ts: "${{ steps.deployment_message.outputs.ts }}"
text: "Deployment finished! :rocket:"
Calling a Slack API method with @slack/web-api
makes uploading a file just another API call with all of the
convenience of the files.uploadV2
method:
- name: Share a file to that channel
uses: slackapi/[email protected]
with:
method: files.uploadV2
token: ${{ secrets.SLACK_BOT_TOKEN }}
payload: |
channel_id: ${{ secrets.SLACK_CHANNEL_ID }}
initial_comment: "the results are in!"
file: "./path/to/results.out"
filename: "results-${{ github.sha }}.out"
This technique uses this Action to post a message to a channel or direct message with incoming webhooks and a Slack app.
Incoming webhooks follow the same formatting patterns as other Slack messaging APIs. Posted messages can be as short as a single line of text, include additional interactivity with interactive components, or be formatted with Block Kit to build visual components.
Gather a Slack incoming webhook URL:
- Create a Slack app for your workspace or use an existing app.
- Add the
incoming-webhook
bot scope under OAuth & Permissions page on app settings. - Install the app to your workspace and select a channel to notify from the Install App page.
- Create additional webhooks from the Incoming Webhooks page.
- Add the generated incoming webhook URL as a repository secret
called
SLACK_WEBHOOK_URL
. - Add this Action as a step to your GitHub workflow and provide an input payload to send as a message.
The webhook URL will resemble something like so:
https://hooks.slack.com/services/T0123456789/B1001010101/7IsoQTrixdUtE971O1xQTm4T
Add the collected webhook from above to a GitHub workflow and configure the step
using mrkdwn
formatting values for a message or
Block Kit blocks:
- name: Post a message in a channel
uses: slackapi/[email protected]
with:
webhook: ${{ secrets.SLACK_WEBHOOK_URL }}
webhook-type: incoming-webhook
payload: |
text: "*GitHub Action build result*: ${{ job.status }}\n${{ github.event.pull_request.html_url || github.event.head_commit.url }}"
blocks:
- type: "section"
text:
type: "mrkdwn"
text: "GitHub Action build result: ${{ job.status }}\n${{ github.event.pull_request.html_url || github.event.head_commit.url }}"
Not all of the above settings serve every customization of a workflow, so these options might be useful.
Invalid API requests or unexpected webhook payloads cause a failing response
that can be used to fail the GitHub Actions step with the errors
option.
The errors
option defaults to false
so failed requests do not cause the step
to fail. This result can still be gathered from the ok
output.
- name: Attempt to call an unknown method
uses: slackapi/[email protected]
with:
errors: true
method: chat.reverse
token: ${{ secrets.SLACK_BOT_TOKEN }}
payload: |
text: "palindrome"
Invalid inputs to the Action, such as not including a payload, will always cause the GitHub step to fail.
Variables and data provided in the payload might contain nested fields that need to be flattened before being sent with a webhook trigger to match the expected input format of Workflow Builder.
The payload-delimiter
option will flatten the input payload using the provided
delimiter and will also make values stringified:
- name: Flatten the default GitHub payload
uses: slackapi/[email protected]
with:
payload-delimiter: "_"
webhook: ${{ secrets.SLACK_WEBHOOK_URL }}
webhook-type: webhook-trigger
Reference to the flattening implementation is available for exploration from
within the flat
package.
Additional variables provided in the Github event context and
event payload can be used to replace templated variables in the
input payload with the payload-templated
option:
- name: Send custom JSON data to Slack workflow
uses: slackapi/[email protected]
with:
payload-file-path: "./payload-slack-content.json"
payload-templated: true
webhook: ${{ secrets.SLACK_WEBHOOK_URL }}
webhook-type: webhook-trigger
This replaces variables templated as ${{ github.payload.repository.html_url }}
with the values found in the GitHub Action event payload.
If you need to use a proxy to connect to Slack, you can use the proxy
option.
In this example we use the technique that calls a Slack API method, but
configuring a proxy is the same for all techniques:
- name: Post to a Slack channel via a proxy
uses: slackapi/[email protected]
with:
method: chat.postMessage
proxy: "http://proxy.example.org:8080" # Change this to a custom value
token: ${{ secrets.SLACK_BOT_TOKEN }}
payload: |
channel: ${{ secrets.SLACK_CHANNEL_ID }}
text: "This message was sent through a proxy"
The proxy
option can also be provided with the HTTPS_PROXY
or https_proxy
environment variable from within the GitHub Actions step.
Sometimes outgoing requests fail due to rate limits or similar HTTP responses and can be retried later.
The retries
option can be configured to the needs of your workflow with one of
these values:
0
: No retries, just hope that things go alright.5
: Five retries in five minutes. Default.10
: Ten retries in about thirty minutes.RAPID
: A burst of retries to keep things running fast.
- name: Attempt a burst of requests
uses: slackapi/[email protected]
with:
method: chat.postMessage
retries: RAPID
token: ${{ secrets.SLACK_BOT_TOKEN }}
payload: |
channel: ${{ secrets.SLACK_CHANNEL_ID }}
text: "status: all things are going good"
Behind the scenes, automatic retries are handled with the
@slack/web-api
package for Slack API methods, and
axios-retry
when sending with a webhook.
Each technique above outputs values that can be used as inputs in following steps of a GitHub workflow.
The following outputs are returned with each of the techniques:
time
:number
. The Unix epoch time that the step completed.ok
:boolean
. If the request completed with success.response
:string
. The response from the request as stringified JSON.
While these outputs are returned with certain Slack API methods:
channel_id
:string
. The channel ID included in the response.ts
:string
. The timestamp of the Slack event or message.thread_ts
:string
. The timestamp of a parent Slack message with threaded replies.
The following snippet shows how multiple steps can be chained together to create a Slack channel before posting a message:
- name: Create a new Slack channel for recent changes
id: conversation
uses: slackapi/[email protected]
with:
method: conversations.create
token: ${{ secrets.SLACK_BOT_TOKEN }}
payload: |
name: pull-request-review-${{ github.sha }}
- name: Send the pull request link into the Slack channel
if: ${{ steps.conversation.outputs.ok }}
uses: slackapi/[email protected]
with:
method: chat.postMessage
token: ${{ secrets.SLACK_BOT_TOKEN }}
payload: |
channel: ${{ steps.conversation.outputs.channel_id }}
text: "A PR was created <!date^${{ steps.conversation.outputs.time }}^{date_num} at {time_secs}|just now>: ${{ github.event.pull_request.html_url }}"
This project is licensed under the MIT license.
All contributions are encouraged! Check out the contributor's guide to learn more.