mirror of
https://github.com/aiclientproxy/proxycast.git
synced 2026-09-24 23:10:56 +08:00
feat: release v0.80.0 with gateway tunnel system and agent improvements
Major Features: - Gateway tunnel system with Discord/Feishu/Telegram support - Agent request tool policy management - Aster session recovery mechanism - Channel log viewer UI with filtering Improvements: - Refactor MCP database migration and config hot-reload - Optimize request tool policy service - Add comprehensive tests for new features Fixes: - Fix test compilation errors (Config gateway field, type inference) - Fix doctest import paths - Fix flaky antigravity token validation test - Fix CI build issues Dependencies: - Update pnpm-lock.yaml and Cargo.lock Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,173 @@
|
||||
---
|
||||
title: Gateway 公共隧道与飞书 Webhook
|
||||
description: 在桌面端通过 Gateway 公共隧道配置 Cloudflare Tunnel,并完成飞书事件回调接入
|
||||
navigation:
|
||||
icon: i-heroicons-globe-alt
|
||||
---
|
||||
|
||||
# Gateway 公共隧道与飞书 Webhook
|
||||
|
||||
本文用于桌面端场景:本机没有公网 IP,通过 Gateway 公共隧道暴露 webhook 地址,给飞书事件订阅使用。
|
||||
|
||||
## 适用版本
|
||||
|
||||
- ProxyCast 已支持“渠道管理 > Gateway 公共隧道”配置卡片
|
||||
- 飞书渠道支持 `webhook` 模式
|
||||
|
||||
## 前置条件
|
||||
|
||||
1. 已安装 `cloudflared`,并确保命令可执行:
|
||||
|
||||
```bash
|
||||
cloudflared --version
|
||||
```
|
||||
|
||||
2. 已准备 Cloudflare 账号和域名(若使用固定域名)
|
||||
3. 飞书应用已创建,拿到 `App ID` 与 `App Secret`
|
||||
|
||||
> 桌面端已支持在「渠道管理 > Gateway 公共隧道」中直接点击:
|
||||
> `检测 cloudflared`、`一键安装 cloudflared`(支持 macOS / Windows / Ubuntu 等常见 Linux 发行版)。
|
||||
|
||||
## 步骤 1:配置 Gateway 公共隧道
|
||||
|
||||
进入:`设置 > 渠道管理`,在顶部找到 `Gateway 公共隧道` 卡片。
|
||||
|
||||
推荐配置:
|
||||
|
||||
- `启用隧道`: 开启
|
||||
- `Provider`: `cloudflare`
|
||||
- `模式`: `managed`
|
||||
- `本地 Host`: `127.0.0.1`(或 `0.0.0.0`)
|
||||
- `本地 Port`: `3000`
|
||||
|
||||
Cloudflare 相关字段(二选一):
|
||||
|
||||
1. `Run Token`(推荐)
|
||||
2. `Tunnel ID + Credentials File`
|
||||
|
||||
如果你希望应用内创建隧道,可填写:
|
||||
|
||||
- `Tunnel Name`
|
||||
- `DNS Name`(例如 `bot.example.com`)
|
||||
|
||||
然后点击 `创建隧道`。
|
||||
|
||||
## 步骤 2:同步飞书回调地址
|
||||
|
||||
在同一个卡片中:
|
||||
|
||||
1. 填 `同步回调账号 ID(Feishu)`,单账号一般为 `default`
|
||||
2. 点击 `同步飞书回调 URL`
|
||||
|
||||
该动作会自动:
|
||||
|
||||
- 计算并返回完整 webhook URL
|
||||
- 将飞书渠道切换为 `webhook` 模式
|
||||
- 回填飞书 `webhook_host/webhook_port/webhook_path`
|
||||
|
||||
## 步骤 3:启动隧道并验证状态
|
||||
|
||||
在 Gateway 公共隧道卡片依次点击:
|
||||
|
||||
1. `探测`
|
||||
2. `启动`
|
||||
3. `查询状态`
|
||||
|
||||
正常时状态里应看到:
|
||||
|
||||
- `running: true`
|
||||
- `public_base_url` 不为空
|
||||
- `last_error` 为空
|
||||
|
||||
## 步骤 4:配置飞书后台事件订阅
|
||||
|
||||
进入飞书开发者后台,事件订阅选择“发送至开发者服务器”。
|
||||
|
||||
将上一步返回的 `webhook_url` 填入请求地址,并保存。
|
||||
|
||||
如果你启用了飞书验证或加密,请确保以下字段一致:
|
||||
|
||||
- `Verification Token`
|
||||
- `Encrypt Key`
|
||||
|
||||
## 步骤 5:启动飞书 Gateway 并联调
|
||||
|
||||
在 `渠道管理 > 飞书` 中:
|
||||
|
||||
1. 确认 `连接模式 = webhook`
|
||||
2. 点击飞书调试工具中的 `重启` 或 `启动`
|
||||
3. 在飞书给机器人发消息,观察是否收到回复
|
||||
|
||||
## 常见问题
|
||||
|
||||
### 1) 飞书后台提示“未检测到应用连接信息”
|
||||
|
||||
常见原因:
|
||||
|
||||
- 隧道未启动
|
||||
- `public_base_url` 为空或不可访问
|
||||
- 飞书仍在 `websocket` 模式(当前版本不建议)
|
||||
|
||||
处理:
|
||||
|
||||
1. 在 Gateway 卡片点击 `查询状态`
|
||||
2. 确认 `running: true`
|
||||
3. 重新执行 `同步飞书回调 URL`
|
||||
|
||||
### 2) 启动隧道失败
|
||||
|
||||
常见原因:
|
||||
|
||||
- `cloudflared` 不在 PATH
|
||||
- `Run Token` / `Tunnel ID` / `Credentials File` 缺失或无效
|
||||
|
||||
处理:
|
||||
|
||||
1. 先点 `探测` 看具体错误
|
||||
2. 优先改为使用 `Run Token`
|
||||
3. 如果提示未安装 cloudflared,可先点 `检测 cloudflared`,再点 `一键安装 cloudflared`
|
||||
|
||||
### 3) 飞书保存回调 URL 失败
|
||||
|
||||
常见原因:
|
||||
|
||||
- URL 不可公网访问
|
||||
- Token/加密配置不一致
|
||||
|
||||
处理:
|
||||
|
||||
1. 确认 URL 为 `https://` 且可访问
|
||||
2. 对齐飞书后台与 ProxyCast 的 Token/Encrypt Key
|
||||
|
||||
## 运维建议
|
||||
|
||||
1. 生产场景优先使用固定域名,不建议临时域名
|
||||
2. 将 `Run Token` 存储在受控环境,避免明文传播
|
||||
3. 隧道可用后再启动渠道 Gateway,减少“启动成功但回调不可达”的误判
|
||||
|
||||
## 进程常驻策略(Tauri + Cloudflared)
|
||||
|
||||
桌面端建议按环境选择:
|
||||
|
||||
1. `managed`(应用内托管,默认)
|
||||
由 ProxyCast 在启动后自动拉起 tunnel,并定时检查进程状态;异常退出会自动重拉。
|
||||
2. `external`(系统级常驻,生产更稳)
|
||||
由系统服务管理 `cloudflared`,ProxyCast 仅做状态诊断与 webhook 同步。
|
||||
|
||||
### 何时用 external
|
||||
|
||||
- 需要长期稳定在线(飞书后台持续探活)
|
||||
- 本机网络波动较大,应用重启不希望影响 tunnel
|
||||
- 需要把 tunnel 运维与桌面应用生命周期解耦
|
||||
|
||||
### 常见连通性检查
|
||||
|
||||
```bash
|
||||
curl -i "https://<你的域名>/feishu/default"
|
||||
cloudflared tunnel info "<tunnel-id>"
|
||||
```
|
||||
|
||||
期望结果:
|
||||
|
||||
- `curl` 返回 2xx/4xx(只要不是 Cloudflare 1033/530,说明已到达你的应用入口)
|
||||
- `tunnel info` 显示有 active connectors
|
||||
@@ -265,10 +265,22 @@ pub enum OutputProtocol {
|
||||
|
||||
```rust
|
||||
/// OAuth 2.0 配置(Google)
|
||||
pub const OAUTH_CLIENT_ID: &str =
|
||||
"1071006060591-tmhssin2h21lcre235vtolojh4g403ep.apps.googleusercontent.com";
|
||||
pub const OAUTH_CLIENT_SECRET: &str =
|
||||
"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";
|
||||
/// 必须通过环境变量配置:
|
||||
/// - ANTIGRAVITY_OAUTH_CLIENT_ID
|
||||
/// - ANTIGRAVITY_OAUTH_CLIENT_SECRET
|
||||
///
|
||||
/// 获取方式:
|
||||
/// 1. 使用 Antigravity CLI 的默认凭据
|
||||
/// 2. 从 Google Cloud Console 创建 OAuth 2.0 客户端
|
||||
fn oauth_client_id() -> String {
|
||||
std::env::var("ANTIGRAVITY_OAUTH_CLIENT_ID")
|
||||
.expect("ANTIGRAVITY_OAUTH_CLIENT_ID environment variable must be set")
|
||||
}
|
||||
|
||||
fn oauth_client_secret() -> String {
|
||||
std::env::var("ANTIGRAVITY_OAUTH_CLIENT_SECRET")
|
||||
.expect("ANTIGRAVITY_OAUTH_CLIENT_SECRET environment variable must be set")
|
||||
}
|
||||
|
||||
pub const OAUTH_SCOPES: &[&str] = &[
|
||||
"https://www.googleapis.com/auth/cloud-platform",
|
||||
@@ -321,11 +333,13 @@ impl AntigravityProvider {
|
||||
let refresh_token = credential.refresh_token.as_ref()
|
||||
.ok_or(Error::MissingRefreshToken)?;
|
||||
|
||||
let client_id = oauth_client_id();
|
||||
let client_secret = oauth_client_secret();
|
||||
let response = self.http_client
|
||||
.post(OAUTH_TOKEN_URL)
|
||||
.form(&[
|
||||
("client_id", OAUTH_CLIENT_ID),
|
||||
("client_secret", OAUTH_CLIENT_SECRET),
|
||||
("client_id", client_id.as_str()),
|
||||
("client_secret", client_secret.as_str()),
|
||||
("refresh_token", refresh_token.as_str()),
|
||||
("grant_type", "refresh_token"),
|
||||
])
|
||||
@@ -1217,6 +1231,10 @@ pnpm test
|
||||
| `ANTIGRAVITY_ENVIRONMENT` | API 环境 | `daily` |
|
||||
| `ANTIGRAVITY_DEBUG` | 调试模式 | `false` |
|
||||
| `ANTIGRAVITY_TIMEOUT_MS` | 请求超时 | `120000` |
|
||||
| `ANTIGRAVITY_OAUTH_CLIENT_ID` | OAuth Client ID(必需) | 无,必须设置 |
|
||||
| `ANTIGRAVITY_OAUTH_CLIENT_SECRET` | OAuth Client Secret(必需) | 无,必须设置 |
|
||||
|
||||
**注意**:OAuth 凭据可以从 Antigravity CLI 获取或从 Google Cloud Console 创建。
|
||||
|
||||
### B. 参考链接
|
||||
|
||||
|
||||
Reference in New Issue
Block a user