From 18b891d0da69b3343a016224b41067aeda86bcd9 Mon Sep 17 00:00:00 2001 From: L0RD-ZER0 <68327382+L0RD-ZER0@users.noreply.github.com> Date: Wed, 13 Mar 2024 17:19:07 +0530 Subject: [PATCH] Add support for slack application tokens --- README.md | 1 + entrypoint.sh | 11 ++++++++++- main.go | 39 ++++++++++++++++++++++++++++++++++----- main.sh | 4 ++++ 4 files changed, 49 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 27bb863..b8a91f1 100644 --- a/README.md +++ b/README.md @@ -56,6 +56,7 @@ SLACK_FOOTER | Powered By rtCamp's GitHub Actions Library | S MSG_MINIMAL | - | If set to `true`, removes: `Ref`, `Event`, `Actions URL` and `Commit` from the message. You can optionally whitelist any of these 4 removed values by passing it comma separated to the variable instead of `true`. (ex: `MSG_MINIMAL: event` or `MSG_MINIMAL: ref,actions url`, etc.) SLACKIFY_MARKDOWN | - | If set to `true`, it will convert markdown to slack format. (ex: `*bold*` to `bold`) Note: This only works for custom messages and not for the default message generated by the action. Credits: [slackify-markdown-action](https://github.com/marketplace/actions/slack-markdown-converter) SLACK_THREAD_TS | - | If you want to send message in a thread, you can pass the timestamp of the parent message to this variable. You can get the timestamp of the parent message from the message URL in Slack. (ex: `SLACK_THREAD_TS: 1586130833.000100`) +SLACK_TOKEN | - | If you want to send message to a channel using a slack token. You will need to pass a channel in order to send messages using token, requiring a value for ``SLACK_CHANNEL``. Note that in case both webhook url and token are provided, webhook url will be prioritized. SLACK_ON_SUCCESS | - | If set, will send the provided message instead of the default message when the passed status (through ``SLACK_COLOR``) is `success`. SLACK_ON_FAILURE | - | If set, will send the provided message instead of the default message when the passed status (through ``SLACK_COLOR``) is `failure`. SLACK_ON_CANCEL | - | If set, will send the provided message instead of the default message when the passed status (through ``SLACK_COLOR``) is `cancelled`. diff --git a/entrypoint.sh b/entrypoint.sh index bbea49b..db190bc 100755 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -2,6 +2,7 @@ # Check required env variables flag=0 +mode="WEBHOOK" if [[ -z "$SLACK_WEBHOOK" ]]; then flag=1 missing_secret="SLACK_WEBHOOK" @@ -13,11 +14,19 @@ if [[ -z "$SLACK_WEBHOOK" ]]; then fi fi +if [[ "$flag" -eq 1 ]] && [[ -n "$SLACK_TOKEN" || -n "$SLACK_CHANNEL" ]] ; then + # Basically, if both SLACK_TOKEN and SLACK_CHANNEL are provided, then it's a token mode + flag=0 + mode="TOKEN" +fi + if [[ "$flag" -eq 1 ]]; then - printf "[\e[0;31mERROR\e[0m] Secret \`$missing_secret\` is missing. Please add it to this action for proper execution.\nRefer https://github.com/rtCamp/action-slack-notify for more information.\n" + echo -e "[\e[0;31mERROR\e[0m] Secret \`$missing_secret\` is missing. Alternatively, a pair of \`SLACK_TOKEN\` and \`SLACK_CHANNEL\` can be provided. Please add it to this action for proper execution.\nRefer https://github.com/rtCamp/action-slack-notify for more information.\n" exit 1 fi +export MSG_MODE="$mode" + # custom path for files to override default files custom_path="$GITHUB_WORKSPACE/.github/slack" main_script="/main.sh" diff --git a/main.go b/main.go index 6ef8843..6772bbd 100644 --- a/main.go +++ b/main.go @@ -30,6 +30,7 @@ const ( EnvMinimal = "MSG_MINIMAL" EnvSlackLinkNames = "SLACK_LINK_NAMES" EnvThreadTs = "SLACK_THREAD_TS" + EnvMessageMode = "MSG_MODE" ) type Webhook struct { @@ -64,16 +65,24 @@ type Field struct { func main() { endpoint := os.Getenv(EnvSlackWebhook) custom_payload := envOr(EnvSlackCustom, "") + if endpoint == "" { + if os.Getenv(EnvSlackChannel) == "" { + fmt.Fprintln(os.Stderr, "Channel is required for sending message using a token") + os.Exit(1) + } + if os.Getenv(EnvMessageMode) == "TOKEN" { + endpoint = "https://slack.com/api/chat.postMessage" + } else { + fmt.Fprintln(os.Stderr, "URL is required") + os.Exit(2) + } + } if custom_payload != "" { if err := send_raw(endpoint, []byte(custom_payload)); err != nil { fmt.Fprintf(os.Stderr, "Error sending message: %s\n", err) os.Exit(2) } } else { - if endpoint == "" { - fmt.Fprintln(os.Stderr, "URL is required") - os.Exit(2) - } text := os.Getenv(EnvSlackMessage) if text == "" { fmt.Fprintln(os.Stderr, "Message is required") @@ -262,7 +271,27 @@ func send(endpoint string, msg Webhook) error { func send_raw(endpoint string, payload []byte) error { b := bytes.NewBuffer(payload) - res, err := http.Post(endpoint, "application/json", b) + + var res *http.Response + var err error + + switch os.Getenv(EnvMessageMode) { + case "WEBHOOK": + res, err = http.Post(endpoint, "application/json", b) + case "TOKEN": + req, err := http.NewRequest("POST", endpoint, b) + if err != nil { + return fmt.Errorf("Error creating request: %s\n", err) + } + req.Header.Set("Content-Type", "application/json") + req.Header.Set("Authorization", "Bearer "+os.Getenv("SLACK_TOKEN")) + client := &http.Client{} + res, err = client.Do(req) + default: + fmt.Fprintf(os.Stderr, "Invalid message mode: %s\n", os.Getenv(EnvMessageMode)) + os.Exit(6) + } + if err != nil { return err } diff --git a/main.sh b/main.sh index caa30e2..e8ed3f8 100644 --- a/main.sh +++ b/main.sh @@ -37,6 +37,10 @@ if [[ -z "$SLACK_WEBHOOK" ]]; then fi fi +if [[ -z "$SLACK_WEBHOOK" ]]; then + printf "[\e[0;31mERROR\e[0m] Secret \`SLACK_WEBHOOK\` is missing. Falling back to using \`SLACK_TOKEN\` and \`SLACK_CHANNEL\`.\n" +fi + if [[ -f "$hosts_file" ]]; then hostname=$(cat "$hosts_file" | shyaml get-value "$GITHUB_BRANCH.hostname") user=$(cat "$hosts_file" | shyaml get-value "$GITHUB_BRANCH.user")