From 18a00ad4b3af3ebddb1643a887416468c908eb42 Mon Sep 17 00:00:00 2001 From: Ohkubo KOHEI Date: Thu, 28 Jul 2022 03:08:31 +0900 Subject: [PATCH] Add support to update messages #75 (#109) * Add support to update messages #75 * fix lint & test * update README * update README --- README.md | 53 +++++++++++++++++++++++++++++++++++++++++ src/slack-send.js | 11 +++++++-- test/slack-send-test.js | 28 ++++++++++++++++++---- 3 files changed, 85 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index c290e03..640e007 100644 --- a/README.md +++ b/README.md @@ -124,6 +124,59 @@ Using JSON payload for constructing a message is also available: SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} ``` +#### Update the message + +If you would like to notify the real-time updates on a build status, you can modify the message your build job posted in the subsequent steps. In order to do this, the steps after the first message posting can have `update-ts: ${{ steps.slack.outputs.ts }}` in their settings. With this, the step updates the already posted channel message instead of posting a new one. + +```yaml +- id: slack + uses: slackapi/slack-github-action@v1.20.0 + with: + channel-id: "CHANNEL_ID" + payload: | + { + "text": "Deployment started (In Progress)", + "attachments": [ + { + "pretext": "Deployment started", + "color": "dbab09", + "fields": [ + { + "title": "Status", + "short": true, + "value": "In Progress" + } + ] + } + ] + } + env: + SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN}} +- uses: slackapi/slack-github-action@v1.20.0 + with: + channel-id: "CHANNEL_ID" + update-ts: ${{ steps.slack.outputs.ts }} + payload: | + { + "text": "Deployment finished (Completed)", + "attachments": [ + { + "pretext": "Deployment finished", + "color": "28a745", + "fields": [ + { + "title": "Status", + "short": true, + "value": "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/src/slack-send.js b/src/slack-send.js index 6719320..98dbf56 100644 --- a/src/slack-send.js +++ b/src/slack-send.js @@ -69,8 +69,14 @@ module.exports = async function slackSend(core) { } if (message.length > 0 || payload) { - // post message - webResponse = await web.chat.postMessage({ channel: channelId, text: message, ...(payload || {}) }); + const ts = core.getInput('update-ts'); + if (ts) { + // update message + webResponse = await web.chat.update({ ts, channel: channelId, text: message, ...(payload || {}) }); + } else { + // post message + webResponse = await web.chat.postMessage({ channel: channelId, text: message, ...(payload || {}) }); + } } else { console.log('Missing slack-message or payload! Did not send a message via chat.postMessage with botToken', { channel: channelId, text: message, ...(payload) }); throw new Error('Missing message content, please input a valid payload or message to send. No Message has been send.'); @@ -115,6 +121,7 @@ module.exports = async function slackSend(core) { } if (webResponse && webResponse.ok) { + core.setOutput('ts', webResponse.ts); // return the thread_ts if it exists, if not return the ts const thread_ts = webResponse.thread_ts ? webResponse.thread_ts : webResponse.ts; core.setOutput('thread_ts', thread_ts); diff --git a/test/slack-send-test.js b/test/slack-send-test.js index c9396e0..98c6b3b 100644 --- a/test/slack-send-test.js +++ b/test/slack-send-test.js @@ -5,7 +5,8 @@ const github = require('@actions/github'); const rewiremock = require('rewiremock/node'); const ChatStub = { - postMessage: sinon.fake.resolves({ ok: true, thread_ts: '1503435956.000247' }), + postMessage: sinon.fake.resolves({ ok: true, ts: '1503435957.111111', thread_ts: '1503435956.000247' }), + update: sinon.fake.resolves({ ok: true, thread_ts: '1503435956.000247' }), }; /* eslint-disable-next-line global-require */ rewiremock(() => require('@slack/web-api')).with({ @@ -57,8 +58,9 @@ describe('slack-send', () => { fakeCore.getInput.withArgs('slack-message').returns('who let the dogs out?'); fakeCore.getInput.withArgs('channel-id').returns('C123456'); await slackSend(fakeCore); - assert.equal(fakeCore.setOutput.firstCall.firstArg, 'thread_ts', 'Output name set to thread_ts'); - assert(fakeCore.setOutput.firstCall.lastArg.length > 0, 'Time output a non-zero-length string'); + 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; @@ -66,6 +68,21 @@ describe('slack-send', () => { assert.equal(chatArgs.text, 'who let the dogs out?', 'Correct message provided to postMessage'); }); + it('should send a message using the update API', async () => { + fakeCore.getInput.withArgs('slack-message').returns('who let the dogs out?'); + fakeCore.getInput.withArgs('channel-id').returns('C123456'); + fakeCore.getInput.withArgs('update-ts').returns('123456'); + 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.update.lastCall.firstArg; + assert.equal(chatArgs.channel, 'C123456', 'Correct channel provided to postMessage'); + assert.equal(chatArgs.text, 'who let the dogs out?', 'Correct message provided to postMessage'); + }); + it('should accept a payload-file-path and use it\'s content in the message', async () => { // Prepare fakeCore.getInput.withArgs('channel-id').returns('C123456'); @@ -76,8 +93,9 @@ describe('slack-send', () => { await slackSend(fakeCore); // Assert - assert.equal(fakeCore.setOutput.firstCall.firstArg, 'thread_ts', 'Output name set to thread_ts'); - assert(fakeCore.setOutput.firstCall.lastArg.length > 0, 'Time output a non-zero-length string'); + 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;