88 types : [opened, reopened, synchronize, closed]
99 release :
1010 types : [published]
11+ # 👇 Manual trigger from the Actions tab
12+ workflow_dispatch :
13+ inputs :
14+ text :
15+ description : " Message to send to Telegram"
16+ required : true
17+ chat_id :
18+ description : " Optional: override TG_CHAT_ID"
19+ required : false
20+ parse_mode :
21+ description : " Telegram parse mode (plain|MarkdownV2|HTML)"
22+ required : false
23+ default : " plain"
1124
12- # Avoid duplicate spam if multiple events fire at once
1325concurrency :
1426 group : telegram-${{ github.ref }}-${{ github.event_name }}
1527 cancel-in-progress : false
1628
1729jobs :
1830 notify :
1931 runs-on : ubuntu-latest
20- # If you created a GitHub Environment that holds the TG_* secrets, keep this.
21- # Otherwise, remove the next line.
2232 environment : SANDBOX
2333
2434 steps :
@@ -38,43 +48,42 @@ jobs:
3848 EVENT="${{ github.event_name }}"
3949 RUN_URL="${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
4050 REPO_URL="${{ github.server_url }}/${{ github.repository }}"
41- REF_NAME="${{ github.ref_name }}"
4251
4352 msg_header() {
44- echo -e "📣 $1
45- Repo : ${ REPO}
46- By : ${ ACTOR}
47- Ref : ${REF_NAME }
48- Run : ${ RUN_URL} "
53+ echo "📣 $1
54+ Repo : $REPO
55+ By : $ACTOR
56+ Ref : ${{ github.ref_name } }
57+ Run : $RUN_URL"
4958 }
5059
51- MESSAGE=""
60+ if [[ "$EVENT" == "workflow_dispatch" ]]; then
61+ # Manual test: use the provided text as-is
62+ MESSAGE="$(msg_header "Manual notification")"
63+ MESSAGE="$MESSAGE
5264
53- if [[ "$EVENT" == "push" ]]; then
65+ ${{ github.event.inputs.text }}"
66+
67+ elif [[ "$EVENT" == "push" ]]; then
5468 BEFORE="${{ github.event.before }}"
5569 AFTER="${{ github.sha }}"
5670
57- if [[ "${BEFORE}" =~ ^0+$ ]]; then
58- RANGE="${AFTER} -n 10"
71+ if [[ "$BEFORE" =~ ^0+$ ]]; then
72+ RANGE="$AFTER -n 10"
73+ COMMITS="$(git log --pretty=format:'- %s (%h) by %an' $RANGE | head -n 10 || true)"
5974 else
60- RANGE ="${ BEFORE} ..${ AFTER} "
75+ COMMITS ="$(git log --pretty=format:'- %s (%h) by %an' "$ BEFORE..$AFTER" | head -n 10 || true) "
6176 fi
62-
63- COMMITS="$(git log --pretty=format:'- %s (%h) by %an' ${RANGE} | head -n 10 || true)"
64- [[ -z "${COMMITS}" ]] && COMMITS="- (no commit messages found)"
77+ [[ -z "${COMMITS:-}" ]] && COMMITS="- (no commit messages found)"
6578
6679 MESSAGE="$(msg_header "New push detected")"
67- MESSAGE="${ MESSAGE}
80+ MESSAGE="$MESSAGE
6881Last changes :
69- ${ COMMITS}
82+ $COMMITS
7083
71- Repo : ${ REPO_URL} "
84+ Repo : $REPO_URL"
7285
7386 elif [[ "$EVENT" == "pull_request" ]]; then
74- PR_NUM="${{ github.event.pull_request.number }}"
75- PR_TITLE="${{ github.event.pull_request.title }}"
76- PR_URL="${{ github.event.pull_request.html_url }}"
77-
7887 if [[ "${{ github.event.action }}" == "closed" ]]; then
7988 if [[ "${{ github.event.pull_request.merged }}" == "true" ]]; then
8089 STATUS="PR merged ✅"
@@ -84,72 +93,64 @@ Repo: ${REPO_URL}"
8493 else
8594 STATUS="PR updated ✏️"
8695 fi
87-
88- MESSAGE="$(msg_header "${STATUS}")"
89- MESSAGE="${MESSAGE}
90- # ${PR_NUM}: ${PR_TITLE}
91- ${PR_URL}"
96+ MESSAGE="$(msg_header "$STATUS")"
97+ MESSAGE="$MESSAGE
98+ # ${{ github.event.pull_request.number }}: ${{ github.event.pull_request.title }}
99+ ${{ github.event.pull_request.html_url }}"
92100
93101 elif [[ "$EVENT" == "release" ]]; then
94- REL_TAG="${{ github.event.release.tag_name }}"
95- REL_NAME="${{ github.event.release.name }}"
96- REL_URL="${{ github.event.release.html_url }}"
97-
98102 MESSAGE="$(msg_header "Release published 🏷️")"
99- MESSAGE="${ MESSAGE}
100- Tag : ${REL_TAG }
101- Name : ${REL_NAME:-${REL_TAG }}
102- ${REL_URL }"
103+ MESSAGE="$MESSAGE
104+ Tag : ${{ github.event.release.tag_name } }
105+ Name : ${{ github.event.release.name || github.event.release.tag_name }}
106+ ${{ github.event.release.html_url } }"
103107
104108 else
105- MESSAGE="$(msg_header "Event : ${ EVENT} ")"
109+ MESSAGE="$(msg_header "Event : $EVENT")"
106110 fi
107111
108- # Telegram hard limit ~4096 chars → keep some headroom
109- LIMIT=3800
110- if (( ${#MESSAGE} > LIMIT )); then
111- MESSAGE="${MESSAGE:0:LIMIT}
112- …(truncated)"
113- fi
114-
115- # Export message to next step
112+ # Export the (safely) raw text for next step
116113 {
117114 echo "text<<EOF"
118- echo "${ MESSAGE} "
119- echo "EOF"
115+ echo "$MESSAGE"
116+ echo "EOF"
120117 } >> "$GITHUB_OUTPUT"
121118
122119 - name : Send to Telegram
123120 env :
124121 TG_BOT_TOKEN : ${{ secrets.TG_BOT_TOKEN }}
125- TG_CHAT_ID : ${{ secrets.TG_CHAT_ID }}
122+ TG_CHAT_ID_DEFAULT : ${{ secrets.TG_CHAT_ID }}
126123 TEXT : ${{ steps.msg.outputs.text }}
127- shell : bash
124+ OVERRIDE_CHAT_ID : ${{ github.event.inputs.chat_id }}
125+ PARSE_MODE : ${{ github.event.inputs.parse_mode }}
128126 run : |
129127 set -euo pipefail
130128
131- if [[ -z "${TG_BOT_TOKEN:-}" || -z "${TG_CHAT_ID:-}" ]]; then
132- echo "❌ Telegram secrets missing (TG_BOT_TOKEN / TG_CHAT_ID)."
129+ # Choose chat id (manual override if provided)
130+ CHAT_ID="${OVERRIDE_CHAT_ID:-$TG_CHAT_ID_DEFAULT}"
131+ if [[ -z "$TG_BOT_TOKEN" || -z "$CHAT_ID" ]]; then
132+ echo "Telegram secrets missing (TG_BOT_TOKEN or TG_CHAT_ID)." >&2
133133 exit 1
134134 fi
135135
136- echo "Payload to Telegram (debug):"
137- jq -n --arg chat_id "$TG_CHAT_ID" --arg text "$TEXT" \
138- '{chat_id:$chat_id, text:$text, disable_web_page_preview:true}'
139-
140- jq -n --arg chat_id "$TG_CHAT_ID" --arg text "$TEXT" \
141- '{chat_id:$chat_id, text:$text, disable_web_page_preview:true}' \
142- | curl -sS --retry 3 --retry-connrefused --max-time 20 \
143- -X POST "https://api.telegram.org/bot${TG_BOT_TOKEN}/sendMessage" \
144- -H "Content-Type: application/json" \
145- -d @- \
146- | tee /tmp/tg_response.json
147-
148- # Optional: basic success check
149- if ! jq -e '.ok == true' /tmp/tg_response.json > /dev/null 2>&1; then
150- echo "⚠️ Telegram API did not return ok=true:"
151- cat /tmp/tg_response.json
152- exit 1
136+ # Parse mode handling
137+ case "${PARSE_MODE:-plain}" in
138+ MarkdownV2|HTML) PMODE="$PARSE_MODE" ;;
139+ *) PMODE="" ;; # plain text
140+ esac
141+
142+ # Build payload with jq to escape safely
143+ if [[ -n "$PMODE" ]]; then
144+ PAYLOAD="$(jq -n --arg chat_id "$CHAT_ID" --arg text "$TEXT" --arg pm "$PMODE" \
145+ '{chat_id:$chat_id, text:$text, parse_mode:$pm, disable_web_page_preview:true}')"
146+ else
147+ PAYLOAD="$(jq -n --arg chat_id "$CHAT_ID" --arg text "$TEXT" \
148+ '{chat_id:$chat_id, text:$text, disable_web_page_preview:true}')"
153149 fi
154150
151+ curl -sS -X POST "https://api.telegram.org/bot${TG_BOT_TOKEN}/sendMessage" \
152+ -H 'Content-Type: application/json' \
153+ -d "$PAYLOAD" \
154+ | jq -e '.ok == true' >/dev/null
155+
155156 echo "✅ Message sent to Telegram."
0 commit comments