---
belongs_to:
  - "[[⚒️ 铸渊·协作指令｜GitHub ↔ Notion 桥接协议]]"
---
# 🔧 铸渊+舒舒指令｜修复 Pipeline C 飞书广播推送 · 新增 /push-broadcast 路由（2026-03-15·霜砚签发）

<aside>
🚨

**紧急修复 · P0 · 霜砚签发 · 2026-03-15 02:00**

**前置已通**：Pipeline A（Notion 写入）✅ · Pipeline B（人格体唤醒+广播生成）✅

**本次修复**：Pipeline C（飞书广播推送）失败。服务器返回 HTTP 405 Not Allowed，原因是舒舒（gateway-server.js）上没有接收广播推送的路由。

**目标**：新增 `/push-broadcast` POST 路由，Pipeline C 推送广播内容到舒舒 → 舒舒调用飞书 API 发消息给目标用户 → 全链路闭环。

</aside>

---

## 一、错误日志（原文）

```
📢 推送广播到飞书...
  标题: BC-M23-003-AW
  目标: ou_3bd223b67374fd102edd4223244a7542
  HTTP 响应: 405
<html>
<head><title>405 Not Allowed</title></head>
<body>
<center><h1>405 Not Allowed</h1></center>
<hr><center>nginx/1.24.0</center>
</body>
</html>

❌ 推送失败 (HTTP 405)
```

---

## 二、问题分析

Pipeline C 的 `push-broadcast-feishu.sh`（或类似脚本）向服务器发送 POST 请求推送广播，但：

1. **nginx** 没有配置该路由的 proxy_pass，直接返回 405
2. **舒舒（gateway-server.js）** 没有 `/push-broadcast` 路由来接收和处理广播推送
3. 即使有路由，还需要舒舒调用**飞书发消息 API** 把广播内容发给目标用户

---

## 三、修复指令

### 3.1 舒舒：新增 /push-broadcast POST 路由

**文件位置**：`feishu-bot/index.js`（或 `gateway-server.js`，取决于实际结构）

```jsx
// ============ 广播推送路由 ============
// Pipeline C 调用此路由，将广播推送到飞书
app.post('/push-broadcast', async (req, res) => {
  try {
    // 1. 验证 token
    const token = req.headers['x-push-token'] || req.body.token;
    if (token !== process.env.PUSH_BROADCAST_TOKEN) {
      return res.status(401).json({ error: 'Invalid token' });
    }

    // 2. 解析请求体
    const { title, content, target_open_id, chat_id } = req.body;
    
    if (!content) {
      return res.status(400).json({ error: 'Missing content' });
    }

    // 3. 获取飞书 tenant_access_token
    const tokenRes = await fetch('https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        app_id: process.env.FEISHU_APP_ID,
        app_secret: process.env.FEISHU_APP_SECRET
      })
    });
    const tokenData = await tokenRes.json();
    const accessToken = tokenData.tenant_access_token;

    // 4. 发送飞书消息
    // 优先发到群聊（chat_id），否则发给个人（target_open_id）
    const receive_id_type = chat_id ? 'chat_id' : 'open_id';
    const receive_id = chat_id || target_open_id;

    const msgRes = await fetch(`https://open.feishu.cn/open-apis/im/v1/messages?receive_id_type=${receive_id_type}`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${accessToken}`
      },
      body: JSON.stringify({
        receive_id: receive_id,
        msg_type: 'text',
        content: JSON.stringify({ text: `📡 新广播 ${title || ''}\n\n${content}` })
      })
    });
    const msgData = await msgRes.json();

    if (msgData.code === 0) {
      console.log(`✅ 广播推送成功: ${title} → ${receive_id}`);
      res.json({ success: true, message_id: msgData.data?.message_id });
    } else {
      console.error(`❌ 飞书发送失败:`, msgData);
      res.status(500).json({ error: msgData.msg, code: msgData.code });
    }

  } catch (err) {
    console.error('❌ push-broadcast error:', err.message);
    res.status(500).json({ error: err.message });
  }
});
```

### 3.2 nginx：添加 proxy_pass（如果 /push-broadcast 没有被代理）

**文件位置**：`/etc/nginx/conf.d/guanghulab.conf`（或对应的 nginx 配置文件）

在 server block 中确认有如下配置：

```
location /push-broadcast {
    proxy_pass http://127.0.0.1:3080;  # 舒舒端口，按实际修改
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header Content-Type $content_type;
}
```

如果舒舒已经有一个通配 location 代理所有 API 请求（如 `location /api/`），则需要确认 `/push-broadcast` 路径在代理范围内，或者单独加一条。

### 3.3 Pipeline C 脚本：确认请求格式

Pipeline C 的推送脚本应该发送如下格式的 POST 请求：

```bash
curl -X POST https://guanghulab.com/push-broadcast \
  -H "Content-Type: application/json" \
  -H "X-Push-Token: ${PUSH_BROADCAST_TOKEN}" \
  -d '{
    "title": "BC-M23-003-AW",
    "content": "广播正文内容...",
    "target_open_id": "ou_3bd223b67374fd102edd4223244a7542",
    "chat_id": "（可选，群聊 ID）"
  }'
```

---

## 四、环境变量确认

舒舒服务器上需要以下环境变量（`.env` 文件或 PM2 ecosystem）：

| **变量名** | **用途** | **来源** |
| --- | --- | --- |
| `FEISHU_APP_ID` | 飞书应用 App ID | 飞书开放平台 → 应用凭证 |
| `FEISHU_APP_SECRET` | 飞书应用 App Secret | 飞书开放平台 → 应用凭证 |
| `PUSH_BROADCAST_TOKEN` | 推送鉴权 token | 与 GitHub Secret 中的 PUSH_BROADCAST_TOKEN 一致：`guanghu-push-2026` |

**注意**：`FEISHU_APP_ID` 和 `FEISHU_APP_SECRET` 舒舒发消息时就应该已经有了（舒舒接收飞书回调时用的同一个应用）。确认这两个变量在 `.env` 里存在即可。

---

## 五、验收标准

- [ ]  服务器上 `curl -X POST https://guanghulab.com/push-broadcast` 不再返回 405
- [ ]  带正确 token 和 content 的 POST 请求返回 `{"success": true}`
- [ ]  飞书端收到广播消息
- [ ]  完整链路测试：飞书发 SYSLOG → Pipeline A/B/C 全绿 → 飞书收到新广播

---

## 六、执行确认

铸渊完成后，在本页下方追加一行：

```
✅ push-broadcast 路由已部署 · [日期时间] · commit SHA
```