Skip to content

Commit

Permalink
Add support to update messages #75 (#109)
Browse files Browse the repository at this point in the history
* Add support to update messages #75

* fix lint & test

* update README

* update README
  • Loading branch information
kuboon authored Jul 27, 2022
1 parent 05390e6 commit 18a00ad
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 7 deletions.
53 changes: 53 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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).
Expand Down
11 changes: 9 additions & 2 deletions src/slack-send.js
Original file line number Diff line number Diff line change
Expand Up @@ -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.');
Expand Down Expand Up @@ -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);
Expand Down
28 changes: 23 additions & 5 deletions test/slack-send-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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({
Expand Down Expand Up @@ -57,15 +58,31 @@ 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;
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 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');
Expand All @@ -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;
Expand Down

0 comments on commit 18a00ad

Please sign in to comment.