From 4b520a7b06d5941723c07dca7d640f553e9a2132 Mon Sep 17 00:00:00 2001 From: Christophe Taylor Date: Sat, 29 Mar 2025 22:39:51 -0700 Subject: [PATCH 1/7] adding update_notification param to the notify command --- src/commands/notify.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/commands/notify.yml b/src/commands/notify.yml index 1c77161f..b684d9f8 100644 --- a/src/commands/notify.yml +++ b/src/commands/notify.yml @@ -91,6 +91,10 @@ parameters: default: 0 description: | When set, the notification is a scheduled message. + update_notification: + type: boolean + default: false + description: When set, the parent notification of the thread is updated retries: type: integer default: 0 @@ -142,6 +146,7 @@ steps: SLACK_PARAM_THREAD: "<>" SLACK_PARAM_OFFSET: "<>" SLACK_SCRIPT_NOTIFY: "<>" + SLACK_PARAM_UPDATE: "<>" SLACK_SCRIPT_UTILS: "<>" # import pre-built templates using the orb-pack local script include. basic_fail_1: "<>" From 208f6cc6295912d9c95f89597d61f2e62e03bf6a Mon Sep 17 00:00:00 2001 From: Christophe Taylor Date: Sat, 29 Mar 2025 22:44:28 -0700 Subject: [PATCH 2/7] update notify scripts to call slack's chat.updateMessage instead of chat.postMessage. instead of providing ts_thread to refer to a thread in the body, ts is used to reference the specific top level message in the thread that will be updated. --- src/scripts/notify.sh | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/scripts/notify.sh b/src/scripts/notify.sh index 430296ed..81e403ca 100644 --- a/src/scripts/notify.sh +++ b/src/scripts/notify.sh @@ -101,8 +101,17 @@ PostToSlack() { # get the value of the specified thread from the environment # SLACK_THREAD_TS=12345.12345 SLACK_THREAD_TS=$(eval "echo \"\$$SLACK_PARAM_THREAD\"") - # append the thread_ts to the body for posting the message in the correct thread - SLACK_MSG_BODY=$(echo "$SLACK_MSG_BODY" | jq --arg thread_ts "$SLACK_THREAD_TS" '.thread_ts = $thread_ts') + if [ $SLACK_PARAM_UPDATE ]; then + # when updating, the key ts is used to reference the message to be updated + TS=$(eval "echo \"\$$SLACK_PARAM_THREAD\"") + SLACK_MSG_BODY=$(echo "$SLACK_MSG_BODY" | jq --arg ts "$TS" '.ts = $ts') + else + # append the thread_ts to the body for posting the message in the correct thread + SLACK_MSG_BODY=$(echo "$SLACK_MSG_BODY" | jq --arg thread_ts "$SLACK_THREAD_TS" '.thread_ts = $thread_ts') + fi + else + # if there isn't any thread info for an update, then revert to posting a new notification + SLACK_PARAM_UPDATE=false fi echo "Sending to Slack Channel: $i" @@ -127,7 +136,10 @@ PostToSlack() { SLACK_MSG_BODY=$(echo "$SLACK_MSG_BODY" | jq --arg post_at "$POST_AT" '.post_at = ($post_at|tonumber)') # text is required for scheduled messages SLACK_MSG_BODY=$(echo "$SLACK_MSG_BODY" | jq '.text = "Dummy fallback text"') + NotifyWithRetries https://slack.com/api/chat.scheduleMessage + elif [ $SLACK_PARAM_UPDATE ]; then + NotifyWithRetries https://slack.com/api/chat.updateMessage else NotifyWithRetries https://slack.com/api/chat.postMessage fi From 0f0c45e8ff5425b7b63b3f430c582abeb6aa939c Mon Sep 17 00:00:00 2001 From: Christophe Taylor Date: Sat, 29 Mar 2025 22:45:53 -0700 Subject: [PATCH 3/7] example config for updating a message in place instead of appending messages to a thread --- src/examples/update_notification.yml | 102 +++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 src/examples/update_notification.yml diff --git a/src/examples/update_notification.yml b/src/examples/update_notification.yml new file mode 100644 index 00000000..6943bafc --- /dev/null +++ b/src/examples/update_notification.yml @@ -0,0 +1,102 @@ +description: | + Send a Slack notification to a channel and use the same message to post replies in a thread. + `thread_id` parameter holds a thread identifier in case there are multiple notifications in the pipeline +usage: + version: 2.1 + orbs: + slack: circleci/slack@5.0 + node: circleci/node:4.1 + jobs: + test: + executor: + name: node/default + steps: + - slack/notify: + event: always + channel: engineering + thread_id: testing + custom: | + { + "blocks": [ + { + "type": "section", + "fields": [ + { + "type": "plain_text", + "text": "*Tests started.*", + "emoji": true + } + ] + } + ] + } + - slack/notify: + event: always + channel: engineering + thread_id: testing + update_notification: true + custom: | + { + "blocks": [ + { + "type": "section", + "fields": [ + { + "type": "plain_text", + "text": "*Tests finished.*", + "emoji": true + } + ] + } + ] + } + deploy: + executor: + name: node/default + steps: + - slack/notify: + event: always + channel: engineering + thread_id: deployment + custom: | + { + "blocks": [ + { + "type": "section", + "fields": [ + { + "type": "plain_text", + "text": "*Deployment started.*", + "emoji": true + } + ] + } + ] + } + - slack/notify: + event: always + channel: engineering + thread_id: deployment + update_notification: true + custom: | + { + "blocks": [ + { + "type": "section", + "fields": [ + { + "type": "plain_text", + "text": "*Deployment finished.*", + "emoji": true + } + ] + } + ] + } + workflows: + deploy_and_notify: + jobs: + - deploy + - test: + requires: + - deploy From d29b59b98821797b0433a9aa748ce747b096264e Mon Sep 17 00:00:00 2001 From: Christophe Taylor Date: Sat, 29 Mar 2025 22:46:48 -0700 Subject: [PATCH 4/7] Updated readme with documentation and an example snippet for updating a top level message --- README.md | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/README.md b/README.md index eef2b2e5..3fda9877 100644 --- a/README.md +++ b/README.md @@ -106,6 +106,31 @@ Post replies in threads with a special parameter `thread_id`. Including this par } ``` +## Update Top Level Messages + +Update a top level message using the `thread_id` parameter. Can update the top of a threaded message or a standalone message. include the parameter `update_notification: true` to specify that this will be an update of an existing message. If the `thread_id` is missing or not found, the message will be posted as a new message instead. + + ```yaml +- slack/notify: + event: always + update_notification: true + custom: | + { + "blocks": [ + { + "type": "section", + "fields": [ + { + "type": "plain_text", + "text": "*This is a text notification*", + "emoji": true + } + ] + } + ] + } + ``` + ## Scheduled Message Set the `scheduled_offset_seconds` special parameter to a number of seconds if you want to post a scheduled message. Example: From 9570e2619c6cc164713d0306f527b8ce80566cce Mon Sep 17 00:00:00 2001 From: Christophe Taylor Date: Tue, 8 Apr 2025 08:43:40 -0700 Subject: [PATCH 5/7] added charset to slack api call, fixed slack update message call --- src/scripts/notify.sh | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/scripts/notify.sh b/src/scripts/notify.sh index 81e403ca..81ceb5f8 100644 --- a/src/scripts/notify.sh +++ b/src/scripts/notify.sh @@ -59,7 +59,7 @@ NotifyWithRetries() { local success_request=false local retry_count=0 while [ "$retry_count" -le "$SLACK_PARAM_RETRIES" ]; do - if SLACK_SENT_RESPONSE=$(curl -s -f -X POST -H 'Content-type: application/json' -H "Authorization: Bearer $SLACK_ACCESS_TOKEN" --data "$SLACK_MSG_BODY" "$1"); then + if SLACK_SENT_RESPONSE=$(curl -s -f -X POST -H 'Content-type: application/json; charset=utf-8' -H "Authorization: Bearer $SLACK_ACCESS_TOKEN" --data "$SLACK_MSG_BODY" "$1"); then echo "Notification sent" success_request=true break @@ -105,13 +105,11 @@ PostToSlack() { # when updating, the key ts is used to reference the message to be updated TS=$(eval "echo \"\$$SLACK_PARAM_THREAD\"") SLACK_MSG_BODY=$(echo "$SLACK_MSG_BODY" | jq --arg ts "$TS" '.ts = $ts') + SLACK_UPDATE=true else # append the thread_ts to the body for posting the message in the correct thread SLACK_MSG_BODY=$(echo "$SLACK_MSG_BODY" | jq --arg thread_ts "$SLACK_THREAD_TS" '.thread_ts = $thread_ts') fi - else - # if there isn't any thread info for an update, then revert to posting a new notification - SLACK_PARAM_UPDATE=false fi echo "Sending to Slack Channel: $i" @@ -138,8 +136,8 @@ PostToSlack() { SLACK_MSG_BODY=$(echo "$SLACK_MSG_BODY" | jq '.text = "Dummy fallback text"') NotifyWithRetries https://slack.com/api/chat.scheduleMessage - elif [ $SLACK_PARAM_UPDATE ]; then - NotifyWithRetries https://slack.com/api/chat.updateMessage + elif [ $SLACK_UPDATE ]; then + NotifyWithRetries https://slack.com/api/chat.update else NotifyWithRetries https://slack.com/api/chat.postMessage fi From 65870a23556bb8517c21f904109875add899cc16 Mon Sep 17 00:00:00 2001 From: Mateo Arboleda Date: Thu, 10 Apr 2025 14:41:07 -0500 Subject: [PATCH 6/7] Add tests --- .circleci/test-deploy.yml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/.circleci/test-deploy.yml b/.circleci/test-deploy.yml index 6c924056..cfbc40b1 100644 --- a/.circleci/test-deploy.yml +++ b/.circleci/test-deploy.yml @@ -28,6 +28,24 @@ jobs: template: basic_success_1 event: always thread_id: orb-testing-thread-<${CIRCLE_SHA1}> + - slack/notify: + debug: true + step_name: "Message with thread updated" + event: always + update_notification: true + thread_id: orb-testing-thread-<${CIRCLE_SHA1}> + custom: | + { + "blocks": [ + { + "type": "section", + "text": { + "type": "mrkdwn", + "text": "This message should be on thread and updating thread" + } + } + ] + } - slack/notify: debug: true step_name: "Custom template with group mention" From d5d0c4c222b5040000e386c27bf44aab1c6e9872 Mon Sep 17 00:00:00 2001 From: Mateo Arboleda Date: Fri, 11 Apr 2025 14:47:17 -0500 Subject: [PATCH 7/7] Fix shellcheck --- src/scripts/notify.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/scripts/notify.sh b/src/scripts/notify.sh index 81ceb5f8..2f187813 100644 --- a/src/scripts/notify.sh +++ b/src/scripts/notify.sh @@ -101,7 +101,7 @@ PostToSlack() { # get the value of the specified thread from the environment # SLACK_THREAD_TS=12345.12345 SLACK_THREAD_TS=$(eval "echo \"\$$SLACK_PARAM_THREAD\"") - if [ $SLACK_PARAM_UPDATE ]; then + if [ "$SLACK_PARAM_UPDATE" ]; then # when updating, the key ts is used to reference the message to be updated TS=$(eval "echo \"\$$SLACK_PARAM_THREAD\"") SLACK_MSG_BODY=$(echo "$SLACK_MSG_BODY" | jq --arg ts "$TS" '.ts = $ts')