diff --git a/README.md b/README.md index 1bf94c6..79b9c5e 100644 --- a/README.md +++ b/README.md @@ -64,6 +64,7 @@ or env: SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} ``` + or > If the `payload` is provided it will take preference over `payload-file-path` @@ -211,6 +212,37 @@ Please note that **the message update step does not accept a channel name.** Set SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} ``` +#### Reply to a message + +If you want to post a message as a reply, you can populate the `payload` with a `"thread_ts"` field. The steps after the first message posting can have `"thread_ts": "${{ steps.slack.outputs.ts }}"` in their payload. In order to reply to an existing message. + +Please note that **that reply to a message does not accept a channel name.** Set a channel ID for the actions that reply to messages in thread. + +```yaml +- id: slack + uses: slackapi/slack-github-action@v1.26.0 + with: + channel-id: "CHANNEL_ID" + payload: | + { + "text": "Deployment started (In Progress)" + } + env: + SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} +- uses: slackapi/slack-github-action@v1.26.0 + with: + # Unlike the step posting a new message, this step does not accept a channel name. + # Please use a channel ID, not a name here. + channel-id: "CHANNEL_ID" + payload: | + { + "thread_ts": "${{ steps.slack.outputs.ts }}" + "text": "Deployment finished (Completed)", + } + env: + SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} +``` + ### Technique 3: Slack Incoming Webhook This approach allows your GitHub Actions job to post a message to a Slack channel or direct message by utilizing [Incoming Webhooks](https://api.slack.com/messaging/webhooks). diff --git a/test/slack-send-test.js b/test/slack-send-test.js index 2b9cefa..b05b6a3 100644 --- a/test/slack-send-test.js +++ b/test/slack-send-test.js @@ -143,6 +143,53 @@ describe('slack-send', () => { assert.equal(firstChatArgs.text, 'who let the dogs out?', 'Correct message provided to postMessage with first comma-separated channel'); assert.equal(secondChatArgs.text, 'who let the dogs out?', 'Correct message provided to postMessage with second comma-separated channel'); }); + + it("should send a reply-message using the postMessage API if thread_ts payload field is used'", async () => { + fakeCore.getInput + .withArgs('payload') + .returns('{"thread_ts":"123456","text":"who let the dogs out?"}'); + fakeCore.getInput.withArgs('channel-id').returns('C123456'); + await slackSend(fakeCore); + assert.equal( + fakeCore.setOutput.firstCall.firstArg, + 'ts', + 'Output name set to ts', + ); + assert.equal( + fakeCore.setOutput.secondCall.firstArg, + 'thread_ts', + 'Output name set to thread_ts', + ); + assert( + fakeCore.setOutput.secondCall.lastArg.length > 0, + 'Time output a non-zero-length string', + ); + assert.equal( + fakeCore.setOutput.lastCall.firstArg, + 'time', + 'Output name set to time', + ); + assert( + fakeCore.setOutput.lastCall.lastArg.length > 0, + 'Time output a non-zero-length string', + ); + const chatArgs = ChatStub.postMessage.lastCall.firstArg; + assert.equal( + chatArgs.channel, + 'C123456', + 'Correct channel provided to postMessage', + ); + assert.equal( + chatArgs.thread_ts, + '123456', + 'Correct thread_ts provided to postMessage', + ); + assert.equal( + chatArgs.text, + 'who let the dogs out?', + 'Correct message provided to postMessage', + ); + }); }); describe('sad path', () => { it('should set an error if payload cannot be JSON parsed', async () => {