From 8ac00163985dc7301e0b4c60772d3f638d201e7f Mon Sep 17 00:00:00 2001 From: Gloridust Date: Sat, 13 Jun 2026 00:41:54 +0800 Subject: [PATCH] ci(telegram): render release/issue notes as Telegram HTML (not raw markdown) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GitHub-Flavored Markdown ≠ Telegram MarkdownV2, so the old plain-text send showed literal ## ** | etc. New .github/scripts/tg-notify.mjs converts GFM → Telegram-safe HTML (///
/; headers→bold, tables→· rows,
lists→•, quotes→▎), escapes <>&, and falls back to plain text if Telegram
rejects the HTML. Adds workflow_dispatch to telegram-notify so you can send
the latest release rendered for testing without cutting a new release.

Co-Authored-By: Claude Opus 4.8 
---
 .github/scripts/tg-notify.mjs         | Bin 0 -> 5600 bytes
 .github/workflows/telegram-notify.yml |  53 ++++++++------------------
 2 files changed, 15 insertions(+), 38 deletions(-)
 create mode 100644 .github/scripts/tg-notify.mjs

diff --git a/.github/scripts/tg-notify.mjs b/.github/scripts/tg-notify.mjs
new file mode 100644
index 0000000000000000000000000000000000000000..e86e84149cd9acadf84557fa22f14f4812924f2a
GIT binary patch
literal 5600
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
LGM;^6u+jb>-wK!J

literal 0
HcmV?d00001

diff --git a/.github/workflows/telegram-notify.yml b/.github/workflows/telegram-notify.yml
index 5dc4d7c..8570248 100644
--- a/.github/workflows/telegram-notify.yml
+++ b/.github/workflows/telegram-notify.yml
@@ -1,40 +1,39 @@
 name: telegram-notify
 
-# 通过 Telegram Bot(@WechatOnCloudBot)把「新版本发布 / 新 issue」推送到群组。
-# 跑在 GitHub Actions 上,无需任何服务器。
+# 新版本发布 / 新 issue 时,把内容(GitHub Markdown → Telegram HTML 渲染)推送到 Telegram 群组。
+# 跑在 GitHub Actions 上,无需服务器;未配置 TELEGRAM_CHAT_ID 则自动跳过。
 #
-# 一次性配置(未配置则自动跳过,不影响 fork):
-#   1) 把 @WechatOnCloudBot 拉进目标群组(群里发言需要时设为管理员)。
-#   2) 取群组 chat id:把 bot 拉进群后在群里随便发条消息,浏览器打开
-#      https://api.telegram.org/bot/getUpdates ,找 result[].message.chat.id
-#      (群组通常是形如 -1001234567890 的负数)。
-#   3) 仓库 Settings → Secrets and variables → Actions:
-#        · Variables 选项卡 → 新建 TELEGRAM_CHAT_ID = 上面的 chat id
-#        · Secrets   选项卡 → 新建 TELEGRAM_BOT_TOKEN = @BotFather 给的 bot token
-#      (chat id 放 Variable 是为了能在下面的 if 条件里判断是否已配置;token 必须放 Secret。)
+# 一次性配置(仓库 Settings → Secrets and variables → Actions):
+#   · Variables → TELEGRAM_CHAT_ID  = 群组 chat id(形如 -1001234567890;取法见 doc/发布到GHCR.md)
+#   · Secrets   → TELEGRAM_BOT_TOKEN = @BotFather 的 token
+#   并把机器人拉进群组。
+#
+# 手动测试渲染效果:Actions → telegram-notify → Run workflow(会把「最新 release」渲染后发到群)。
 
 on:
   release:
     types: [published]
   issues:
     types: [opened]
+  workflow_dispatch: {}
 
-# 限制权限:只读元数据,足够本工作流所需。
 permissions:
   contents: read
 
 jobs:
   notify:
     runs-on: ubuntu-latest
-    # 仅当配置了群组 chat id 时才运行(未配置的 fork 会安全跳过)
     if: ${{ vars.TELEGRAM_CHAT_ID != '' }}
     steps:
-      - name: Compose & send Telegram message
+      - uses: actions/checkout@v4
+      - name: Render & send to Telegram
         env:
           TG_TOKEN: ${{ secrets.TELEGRAM_BOT_TOKEN }}
           TG_CHAT: ${{ vars.TELEGRAM_CHAT_ID }}
+          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+          REPO: ${{ github.repository }}
           EVENT: ${{ github.event_name }}
-          # 经 env 传入任意文本,避免把 ${{ }} 直接拼进脚本造成命令注入
+          # 经 env 传任意文本,避免命令注入
           R_TAG: ${{ github.event.release.tag_name }}
           R_NAME: ${{ github.event.release.name }}
           R_URL: ${{ github.event.release.html_url }}
@@ -44,26 +43,4 @@ jobs:
           I_URL: ${{ github.event.issue.html_url }}
           I_USER: ${{ github.event.issue.user.login }}
           I_BODY: ${{ github.event.issue.body }}
-        run: |
-          set -uo pipefail
-          if [ -z "${TG_TOKEN:-}" ]; then
-            echo "::warning::TELEGRAM_BOT_TOKEN 未配置,跳过"
-            exit 0
-          fi
-          if [ "$EVENT" = "release" ]; then
-            title="🚀 云微 WechatOnCloud ${R_TAG} 已发布"
-            if [ -n "${R_NAME:-}" ] && [ "${R_NAME}" != "${R_TAG}" ]; then
-              title="${title} — ${R_NAME}"
-            fi
-            # 发布说明截断到 ~3000 字符(Telegram 单条上限 4096)
-            body="$(printf '%s' "${R_BODY:-}" | head -c 3000)"
-            msg="$(printf '%s\n\n%s\n\n🔗 完整说明:%s\n⬆️ 升级: docker compose pull && docker compose up -d' "$title" "$body" "$R_URL")"
-          else
-            body="$(printf '%s' "${I_BODY:-}" | head -c 600)"
-            msg="$(printf '🐛 新反馈 Issue #%s:%s\n👤 by %s\n\n%s\n\n🔗 %s' "$I_NUM" "$I_TITLE" "$I_USER" "$body" "$I_URL")"
-          fi
-          # --data-urlencode 负责转义,纯文本发送(不用 markdown parse_mode,避免特殊字符破坏解析)
-          curl -sS --fail-with-body -X POST \
-            "https://api.telegram.org/bot${TG_TOKEN}/sendMessage" \
-            --data-urlencode "chat_id=${TG_CHAT}" \
-            --data-urlencode "text=${msg}"
+        run: node .github/scripts/tg-notify.mjs