name: 铸渊 · Push Broadcast · Notion → 飞书文档B # 链路2:新广播推送 # Notion 新广播页面 → 追加到飞书文档B顶部 # # 依赖 Secrets: # NOTION_TOKEN Notion API token # FEISHU_APP_ID 飞书应用 App ID # FEISHU_APP_SECRET 飞书应用 App Secret # FEISHU_DOC_B_ID 飞书文档B的 document_id # # dispatch payload: # broadcast_page_id Notion 广播页面 ID on: repository_dispatch: types: [push-broadcast] workflow_dispatch: inputs: broadcast_page_id: description: 'Notion 广播页面 ID' required: true jobs: push-broadcast: name: 📡 推送广播到飞书 runs-on: ubuntu-latest permissions: contents: read steps: - name: Checkout uses: actions/checkout@v4 - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: '20' - name: 📡 推送广播 → 飞书文档B env: NOTION_TOKEN: ${{ secrets.NOTION_TOKEN }} BROADCAST_PAGE_ID: ${{ github.event.client_payload.broadcast_page_id || github.event.inputs.broadcast_page_id }} FEISHU_APP_ID: ${{ secrets.FEISHU_APP_ID }} FEISHU_APP_SECRET: ${{ secrets.FEISHU_APP_SECRET }} FEISHU_DOC_B_ID: ${{ secrets.FEISHU_DOC_B_ID }} run: node scripts/push-broadcast.js - name: 📢 通知飞书群有新广播 if: success() env: FEISHU_APP_ID: ${{ secrets.FEISHU_APP_ID }} FEISHU_APP_SECRET: ${{ secrets.FEISHU_APP_SECRET }} ALERT_CHAT_ID: ${{ secrets.FEISHU_ALERT_CHAT_ID }} run: | if [ -z "$ALERT_CHAT_ID" ]; then echo "⚠️ 未配置 FEISHU_ALERT_CHAT_ID,跳过群通知" exit 0 fi node -e " const https = require('https'); function post(url, body) { return new Promise((resolve, reject) => { const payload = JSON.stringify(body); const u = new URL(url); const req = https.request({ hostname: u.hostname, port: 443, path: u.pathname, method: 'POST', headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(payload) } }, res => { let d=''; res.on('data', c => d+=c); res.on('end', () => resolve(d)); }); req.on('error', reject); req.write(payload); req.end(); }); } (async () => { const tokenRes = JSON.parse(await post('https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal', { app_id: process.env.FEISHU_APP_ID, app_secret: process.env.FEISHU_APP_SECRET })); const token = tokenRes.tenant_access_token; const payload = JSON.stringify({ text: '📡 新广播已推送到飞书文档B\n\n时间: ' + new Date().toISOString() + '\n请查看飞书广播收件箱。' }); await post('https://open.feishu.cn/open-apis/im/v1/messages?receive_id_type=chat_id', JSON.stringify({ receive_id: process.env.ALERT_CHAT_ID, msg_type: 'text', content: payload })); })().catch(e => console.error(e.message)); " - name: 🔴 失败告警 → 飞书通知 if: failure() env: FEISHU_APP_ID: ${{ secrets.FEISHU_APP_ID }} FEISHU_APP_SECRET: ${{ secrets.FEISHU_APP_SECRET }} ALERT_CHAT_ID: ${{ secrets.FEISHU_ALERT_CHAT_ID }} run: | if [ -z "$ALERT_CHAT_ID" ]; then echo "⚠️ 未配置 FEISHU_ALERT_CHAT_ID,跳过告警" exit 0 fi node -e " const https = require('https'); function post(url, body) { return new Promise((resolve, reject) => { const payload = JSON.stringify(body); const u = new URL(url); const req = https.request({ hostname: u.hostname, port: 443, path: u.pathname, method: 'POST', headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(payload) } }, res => { let d=''; res.on('data', c => d+=c); res.on('end', () => resolve(d)); }); req.on('error', reject); req.write(payload); req.end(); }); } (async () => { const tokenRes = JSON.parse(await post('https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal', { app_id: process.env.FEISHU_APP_ID, app_secret: process.env.FEISHU_APP_SECRET })); const token = tokenRes.tenant_access_token; const payload = JSON.stringify({ text: '🔴 GitHub Action 失败告警\n\n工作流: push-broadcast\n时间: ' + new Date().toISOString() + '\n请检查 GitHub Actions 日志。' }); await post('https://open.feishu.cn/open-apis/im/v1/messages?receive_id_type=chat_id', JSON.stringify({ receive_id: process.env.ALERT_CHAT_ID, msg_type: 'text', content: payload })); })().catch(e => console.error(e.message)); "