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:
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:
:memo: 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:
SLACK_WEBHOOK_URL
.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/slack-github-action@v2.0.0
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/slack-github-action@v2.0.0
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/slack-github-action@v2.0.0
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:
SLACK_BOT_TOKEN
or something similar and memorable.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 to a Slack channel
uses: slackapi/slack-github-action@v2.0.0
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 to a Slack channel
uses: slackapi/slack-github-action@v2.0.0
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: slack
uses: slackapi/slack-github-action@v2.0.0
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/slack-github-action@v2.0.0
with:
method: chat.update
token: ${{ secrets.SLACK_BOT_TOKEN }}
payload: |
channel: ${{ secrets.SLACK_CHANNEL_ID }}
ts: "${{ steps.slack.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/slack-github-action@v2.0.0
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/slack-github-action@v2.0.0
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/slack-github-action@v2.0.0
with:
method: files.uploadV2
token: ${{ secrets.SLACK_BOT_TOKEN }}
payload: |
channel: ${{ secrets.SLACK_CHANNEL_ID }}
initial_comment: "the results are in!"
file: "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:
incoming-webhook
bot scope under OAuth
& Permissions page on app settings.SLACK_WEBHOOK_URL
.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/slack-github-action@v2.0.0
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: Send GitHub Action data to a Slack workflow
uses: slackapi/slack-github-action@v2.0.0
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: Send GitHub Action data to a Slack workflow
uses: slackapi/slack-github-action@v2.0.0
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
id: slack
uses: slackapi/slack-github-action@v2.0.0
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/slack-github-action@v2.0.0
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/slack-github-action@v2.0.0
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/slack-github-action@v2.0.0
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/slack-github-action@v2.0.0
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.