Files
proxycast/docs/prd/proxycast-connect.md
T
coso 5827087780 fix: Connect API Key 保存到 API Key Provider 系统而非 Provider Pool
- 修改 save_relay_api_key 命令使用 ApiKeyProviderService
- 自动创建自定义 Provider(使用 connect- 前缀 + 中转商 ID)
- 更新前端 useDeepLink hook 适配新的返回类型 SaveApiKeyResult
- 修复 API Key 显示在错误的凭证池标签页问题
2026-01-05 23:14:47 +08:00

52 KiB
Raw Blame History

ProxyCast Connect - 中转商生态合作方案

版本: 1.0.0 日期: 2026-01-05 状态: Draft


一、背景与目标

1.1 背景

AI API 中转市场蓬勃发展,涌现出大量中转服务商:

  • 基于 new-api、one-api 搭建的中转站
  • ccr、claude-relay-service 等专用中转
  • 各类 Token 分销平台

这些中转商面临的痛点:

  1. 用户配置复杂 - 用户需要手动配置 base_url、协议等
  2. 接入门槛高 - 不同客户端(Cursor、Claude Code)配置方式不同
  3. 缺乏差异化 - 各家中转体验雷同

1.2 目标

ProxyCast Connect 是一套中转商生态合作方案:

  1. 一键配置 - 用户点击链接即可完成 ProxyCast + Key 配置
  2. 品牌展示 - 中转商在 ProxyCast 内有专属展示位
  3. 双向引流 - 中转商推广 ProxyCast,ProxyCast 为中转商导流
  4. 生态共赢 - 降低用户门槛,提升转化率

1.3 核心价值

角色 价值
中转商 用户转化率提升、品牌曝光、差异化竞争
用户 一键配置、开箱即用、统一管理多个中转
ProxyCast 用户增长、生态繁荣、市场占有率

二、产品方案

2.1 一键配置流程

┌─────────────────────────────────────────────────────────────────────────┐
│                     ProxyCast Connect 流程                               │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                          │
│  ┌─────────────────────────────────────────────────────────────────┐    │
│  │                    中转商用户后台                                 │    │
│  │                                                                   │    │
│  │  我的 API Key: sk-xxxxxxxxxxxxxxxx              [复制]           │    │
│  │                                                                   │    │
│  │  ┌─────────────────────────────────────────────────────────┐     │    │
│  │  │  🚀 快速接入                                             │     │    │
│  │  │                                                          │     │    │
│  │  │  ┌────────────┐ ┌────────────┐ ┌────────────┐           │     │    │
│  │  │  │ ProxyCast  │ │  Cursor    │ │Claude Code │           │     │    │
│  │  │  │ [一键配置] │ │ [查看教程] │ │ [查看教程] │           │     │    │
│  │  │  └────────────┘ └────────────┘ └────────────┘           │     │    │
│  │  └─────────────────────────────────────────────────────────┘     │    │
│  └─────────────────────────────────────────────────────────────────┘    │
│       │                                                                  │
│       │ 用户点击 [一键配置]                                              │
│       ▼                                                                  │
│  ┌─────────────────────────────────────────────────────────────────┐    │
│  │  浏览器打开 proxycast:// 协议                                    │    │
│  │                                                                   │    │
│  │  proxycast://connect?                                            │    │
│  │    relay=xxx-relay&                                              │    │
│  │    key=sk-xxxxxxxx&                                              │    │
│  │    name=我的Key                                                  │    │
│  └─────────────────────────────────────────────────────────────────┘    │
│       │                                                                  │
│       ├─── 已安装 ProxyCast ───────────────────────────────────────┐    │
│       │                                                             │    │
│       │    ProxyCast 打开,显示确认弹窗                             │    │
│       │    ┌─────────────────────────────────────────────────┐     │    │
│       │    │                                                  │     │    │
│       │    │  🔗 添加 API Key                                 │     │    │
│       │    │                                                  │     │    │
│       │    │  来源: XXX中转站                                 │     │    │
│       │    │  Key:  sk-xxxx...xxxx                           │     │    │
│       │    │  名称: 我的Key                                   │     │    │
│       │    │                                                  │     │    │
│       │    │  [取消]                    [确认添加]            │     │    │
│       │    │                                                  │     │    │
│       │    └─────────────────────────────────────────────────┘     │    │
│       │         │                                                   │    │
│       │         ▼                                                   │    │
│       │    配置完成,可以使用 ✓                                     │    │
│       │                                                             │    │
│       └─── 未安装 ProxyCast ───────────────────────────────────────┐    │
│                                                                     │    │
│            跳转 proxycast.dev/download?connect=...                  │    │
│                 │                                                   │    │
│                 ▼                                                   │    │
│            下载并安装 ProxyCast                                     │    │
│                 │                                                   │    │
│                 ▼                                                   │    │
│            首次启动,自动读取参数并配置                              │    │
│                                                                          │
└─────────────────────────────────────────────────────────────────────────┘

2.2.1 协议格式

proxycast://connect?relay={relay_id}&key={api_key}&name={key_name}
参数 必填 说明
relay ✅ 中转商 ID(需在 ProxyCast 注册)
key ✅ API Key
name ❌ Key 名称(默认使用中转商名称)
ref ❌ 推广码(用于统计)

2.2.2 示例

# 基础用法
proxycast://connect?relay=openrouter&key=sk-or-v1-xxxx

# 带名称
proxycast://connect?relay=siliconflow&key=sk-xxxx&name=硅基流动-主账号

# 带推广码
proxycast://connect?relay=myrelay&key=sk-xxxx&ref=promo2024

2.2.3 Web 中转页面

对于不支持自定义协议的场景,提供 Web 中转:

https://proxycast.dev/connect?relay=xxx&key=sk-xxxx

页面逻辑:

  1. 尝试唤起 proxycast:// 协议
  2. 如果 3 秒内未成功,显示下载引导
  3. 下载链接带上 connect 参数,安装后首次启动自动配置

2.3 中转商注册(开源方式)

ProxyCast 是开源软件,中转商通过 GitHub PR 方式注册,无需网站注册。

2.3.1 注册仓库

中转商注册信息统一管理在独立仓库:

https://github.com/aiclientproxy/connect

2.3.2 注册流程

┌─────────────────────────────────────────────────────────────────────────┐
│                     中转商注册流程(GitHub PR)                          │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                          │
│  Step 1: Fork 仓库                                                       │
│  ─────────────────                                                       │
│  Fork https://github.com/aiclientproxy/connect         │
│       │                                                                  │
│       ▼                                                                  │
│  Step 2: 创建配置文件                                                    │
│  ─────────────────                                                       │
│  在 providers/ 目录下创建 {your-id}.json                                │
│  参考 providers/_example.json 模板                                       │
│       │                                                                  │
│       ▼                                                                  │
│  Step 3: 提交 PR                                                         │
│  ─────────────────                                                       │
│  提交 Pull Request 到主仓库                                              │
│       │                                                                  │
│       ▼                                                                  │
│  Step 4: 自动化检查                                                      │
│  ─────────────────                                                       │
│  GitHub Actions 自动验证:                                               │
│  ├── JSON Schema 验证                                                   │
│  ├── Logo 图片可访问性                                                  │
│  └── API 地址可访问性                                                   │
│       │                                                                  │
│       ▼                                                                  │
│  Step 5: 社区审核                                                        │
│  ─────────────────                                                       │
│  维护者审核并合并 PR                                                     │
│       │                                                                  │
│       ▼                                                                  │
│  Step 6: 自动发布                                                        │
│  ─────────────────                                                       │
│  合并后自动构建 registry.json                                            │
│  ProxyCast 客户端定期同步更新                                            │
│                                                                          │
└─────────────────────────────────────────────────────────────────────────┘

2.3.3 配置文件格式

在 providers/ 目录下创建 {your-id}.json:

{
  "id": "myrelay",
  "name": "我的中转站",
  "description": "稳定、便宜、快速的 AI API 中转服务",
  
  "branding": {
    "logo": "https://myrelay.com/logo.png",
    "color": "#6366f1"
  },
  
  "links": {
    "homepage": "https://myrelay.com",
    "register": "https://myrelay.com/register",
    "recharge": "https://myrelay.com/recharge",
    "docs": "https://docs.myrelay.com",
    "status": "https://status.myrelay.com"
  },
  
  "api": {
    "base_url": "https://api.myrelay.com/v1",
    "protocol": "openai",
    "auth_header": "Authorization",
    "auth_prefix": "Bearer "
  },
  
  "contact": {
    "email": "support@myrelay.com",
    "telegram": "@myrelay"
  },
  
  "features": {
    "streaming": true,
    "models_endpoint": true
  }
}

2.3.4 字段说明

字段 必填 说明
id ✅ 唯一标识,小写字母、数字、连字符
name ✅ 显示名称
description ✅ 简短描述,≤100 字
branding.logo ✅ Logo URL,256x256 PNG
branding.color ❌ 主题色,默认 #6366f1
links.homepage ✅ 官网地址
links.register ❌ 注册页面
links.recharge ❌ 充值页面
links.docs ❌ 文档地址
links.status ❌ 状态页面
api.base_url ✅ API 地址(必须 HTTPS)
api.protocol ✅ 协议:openai 或 anthropic
contact.email ✅ 联系邮箱

2.3.5 审核标准

PR 合并前需满足:

  • JSON Schema 验证通过
  • 文件名与 id 字段一致
  • Logo 图片可访问(256x256 PNG)
  • API 地址使用 HTTPS
  • 官网可访问
  • 联系方式有效

2.3.6 仓库结构

transit-service-provider/
├── README.md                    # 注册指南
├── providers/                   # 中转商配置目录
│   ├── _example.json           # 示例配置(不会被加载)
│   ├── openrouter.json         # OpenRouter
│   ├── siliconflow.json        # 硅基流动
│   └── ...                     # 其他中转商
├── schema/
│   └── provider.schema.json    # JSON Schema
├── scripts/
│   ├── validate.js             # 验证脚本
│   ├── check-api.js            # API 检查脚本
│   └── build-registry.js       # 构建注册表
├── dist/
│   └── registry.json           # 构建产物(自动生成)
└── .github/
    ├── workflows/
    │   └── validate.yml        # PR 自动验证
    └── PULL_REQUEST_TEMPLATE.md

2.3.7 注册表同步

ProxyCast 客户端通过以下方式获取中转商列表:

https://raw.githubusercontent.com/aiclientproxy/connect/main/dist/registry.json

客户端定期(每 24 小时)同步更新,也可手动刷新

2.4 中转商品牌展示

2.4.1 扩展市场展示

┌─────────────────────────────────────────────────────────────────────────┐
│  扩展市场 > 中转服务                                                     │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                          │
│  ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐   │
│  │   [Logo]     │ │   [Logo]     │ │   [Logo]     │ │   [Logo]     │   │
│  │  OpenRouter  │ │   硅基流动   │ │   XXX中转    │ │   YYY中转    │   │
│  │  ✓ 官方认证  │ │  ✓ 官方认证  │ │              │ │              │   │
│  │  ⭐ 4.9      │ │  ⭐ 4.8      │ │  ⭐ 4.5      │ │  ⭐ 4.3      │   │
│  │  [安装]      │ │  [安装]      │ │  [安装]      │ │  [安装]      │   │
│  └──────────────┘ └──────────────┘ └──────────────┘ └──────────────┘   │
│                                                                          │
└─────────────────────────────────────────────────────────────────────────┘

2.4.2 已安装中转商页面

┌─────────────────────────────────────────────────────────────────────────┐
│  XXX中转站                                                    [设置] [×]│
├─────────────────────────────────────────────────────────────────────────┤
│                                                                          │
│  ┌─────────────────────────────────────────────────────────────────┐    │
│  │  [Logo]  XXX中转站                                              │    │
│  │          稳定、便宜、快速的 AI API 中转服务                      │    │
│  │                                                                   │    │
│  │  [官网]  [充值]  [文档]  [状态]                                  │    │
│  └─────────────────────────────────────────────────────────────────┘    │
│                                                                          │
│  ┌─────────────────────────────────────────────────────────────────┐    │
│  │  我的 API Keys                                                   │    │
│  ├─────────────────────────────────────────────────────────────────┤    │
│  │                                                                   │    │
│  │  ┌─────────────────────────────────────────────────────────┐     │    │
│  │  │ 主账号                              sk-xxxx...xxxx       │     │    │
│  │  │ ● 正常                              [设为默认] [删除]    │     │    │
│  │  └─────────────────────────────────────────────────────────┘     │    │
│  │                                                                   │    │
│  │  ┌─────────────────────────────────────────────────────────┐     │    │
│  │  │ 备用账号                            sk-yyyy...yyyy       │     │    │
│  │  │ ● 正常                              [设为默认] [删除]    │     │    │
│  │  └─────────────────────────────────────────────────────────┘     │    │
│  │                                                                   │    │
│  │  [+ 添加 Key]                                                    │    │
│  │                                                                   │    │
│  └─────────────────────────────────────────────────────────────────┘    │
│                                                                          │
│  ┌─────────────────────────────────────────────────────────────────┐    │
│  │  📢 公告                                                         │    │
│  ├─────────────────────────────────────────────────────────────────┤    │
│  │                                                                   │    │
│  │  🎉 新用户注册送 $5 额度!                                       │    │
│  │  📅 2026-01-01 ~ 2026-01-31                                      │    │
│  │  [立即注册]                                                      │    │
│  │                                                                   │    │
│  └─────────────────────────────────────────────────────────────────┘    │
│                                                                          │
└─────────────────────────────────────────────────────────────────────────┘

三、技术实现

// src-tauri/src/main.rs

fn main() {
    tauri::Builder::default()
        // 注册自定义协议
        .register_uri_scheme_protocol("proxycast", |app, request| {
            handle_deep_link(app, request)
        })
        // ...
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}

fn handle_deep_link(app: &AppHandle, request: &HttpRequest) -> Result<Response> {
    let url = request.uri();
    
    // 解析 proxycast://connect?relay=xxx&key=xxx
    if url.path() == "connect" {
        let params = parse_query_params(url.query());
        
        // 发送事件到前端
        app.emit_all("deep-link-connect", ConnectPayload {
            relay: params.get("relay"),
            key: params.get("key"),
            name: params.get("name"),
            ref_code: params.get("ref"),
        })?;
    }
    
    Ok(Response::default())
}

3.2 前端处理

// src/hooks/useDeepLink.ts

import { listen } from '@tauri-apps/api/event';
import { useEffect } from 'react';

interface ConnectPayload {
  relay: string;
  key: string;
  name?: string;
  ref?: string;
}

export function useDeepLink() {
  useEffect(() => {
    const unlisten = listen<ConnectPayload>('deep-link-connect', (event) => {
      const { relay, key, name, ref } = event.payload;
      
      // 显示确认弹窗
      showConnectConfirmDialog({
        relay,
        key,
        name,
        ref,
        onConfirm: () => addApiKey(relay, key, name),
        onCancel: () => {},
      });
    });
    
    return () => { unlisten.then(fn => fn()); };
  }, []);
}

3.3 确认弹窗组件

// src/components/ConnectConfirmDialog.tsx

interface Props {
  relay: RelayInfo;
  key: string;
  name?: string;
  onConfirm: () => void;
  onCancel: () => void;
}

export function ConnectConfirmDialog({ relay, key, name, onConfirm, onCancel }: Props) {
  const maskedKey = maskApiKey(key); // sk-xxxx...xxxx
  
  return (
    <Dialog open onOpenChange={onCancel}>
      <DialogContent>
        <DialogHeader>
          <DialogTitle className="flex items-center gap-2">
            <LinkIcon className="w-5 h-5" />
            添加 API Key
          </DialogTitle>
        </DialogHeader>
        
        <div className="space-y-4">
          <div className="flex items-center gap-3">
            <img src={relay.logo} className="w-10 h-10 rounded" />
            <div>
              <div className="font-medium">{relay.name}</div>
              <div className="text-sm text-muted-foreground">
                {relay.description}
              </div>
            </div>
          </div>
          
          <div className="bg-muted p-3 rounded-lg space-y-2">
            <div className="flex justify-between">
              <span className="text-muted-foreground">Key</span>
              <span className="font-mono">{maskedKey}</span>
            </div>
            {name && (
              <div className="flex justify-between">
                <span className="text-muted-foreground">名称</span>
                <span>{name}</span>
              </div>
            )}
          </div>
          
          <p className="text-sm text-muted-foreground">
            确认后,此 Key 将被添加到 ProxyCast,您可以立即开始使用。
          </p>
        </div>
        
        <DialogFooter>
          <Button variant="outline" onClick={onCancel}>取消</Button>
          <Button onClick={onConfirm}>确认添加</Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}

3.4 中转商注册表(从 GitHub 加载)

// src-tauri/src/relay/registry.rs

use std::collections::HashMap;
use serde::{Deserialize, Serialize};

/// 注册表数据结构(对应 registry.json)
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct RelayRegistry {
    pub version: String,
    pub updated_at: String,
    pub providers: Vec<RelayInfo>,
    
    #[serde(skip)]
    index: HashMap<String, usize>,
}

#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct RelayInfo {
    pub id: String,
    pub name: String,
    pub description: String,
    pub branding: RelayBranding,
    pub links: RelayLinks,
    pub api: RelayApi,
    pub contact: RelayContact,
    #[serde(default)]
    pub features: RelayFeatures,
}

#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct RelayBranding {
    pub logo: String,
    #[serde(default = "default_color")]
    pub color: String,
}

fn default_color() -> String { "#6366f1".to_string() }

#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct RelayLinks {
    pub homepage: String,
    pub register: Option<String>,
    pub recharge: Option<String>,
    pub docs: Option<String>,
    pub status: Option<String>,
}

#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct RelayApi {
    pub base_url: String,
    pub protocol: String,
    #[serde(default = "default_auth_header")]
    pub auth_header: String,
    #[serde(default = "default_auth_prefix")]
    pub auth_prefix: String,
}

fn default_auth_header() -> String { "Authorization".to_string() }
fn default_auth_prefix() -> String { "Bearer ".to_string() }

#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct RelayContact {
    pub email: String,
    pub telegram: Option<String>,
    pub discord: Option<String>,
}

#[derive(Clone, Debug, Default, Serialize, Deserialize)]
pub struct RelayFeatures {
    #[serde(default = "default_true")]
    pub streaming: bool,
    #[serde(default)]
    pub models_endpoint: bool,
}

fn default_true() -> bool { true }

impl RelayRegistry {
    /// 注册表 URL(从 GitHub 加载)
    const REGISTRY_URL: &'static str = 
        "https://raw.githubusercontent.com/aiclientproxy/connect/main/dist/registry.json";
    
    /// 从 GitHub 加载中转商列表
    pub async fn load_from_github(&mut self) -> Result<()> {
        let response = reqwest::get(Self::REGISTRY_URL).await?;
        let mut registry: RelayRegistry = response.json().await?;
        
        // 构建索引
        for (i, provider) in registry.providers.iter().enumerate() {
            registry.index.insert(provider.id.clone(), i);
        }
        
        *self = registry;
        Ok(())
    }
    
    /// 获取中转商信息
    pub fn get(&self, id: &str) -> Option<&RelayInfo> {
        self.index.get(id).map(|&i| &self.providers[i])
    }
    
    /// 验证 relay_id 是否有效
    pub fn is_valid(&self, id: &str) -> bool {
        self.index.contains_key(id)
    }
    
    /// 获取所有中转商
    pub fn list(&self) -> &[RelayInfo] {
        &self.providers
    }
}

四、中转商接入指南

4.1 接入流程

┌─────────────────────────────────────────────────────────────────────────┐
│                     中转商接入流程(GitHub PR)                          │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                          │
│  Step 1: Fork 仓库                                                       │
│  ─────────────────                                                       │
│  Fork https://github.com/aiclientproxy/connect         │
│       │                                                                  │
│       ▼                                                                  │
│  Step 2: 创建配置文件                                                    │
│  ─────────────────                                                       │
│  在 providers/ 目录下创建 {your-id}.json                                │
│  参考 providers/_example.json 模板                                       │
│       │                                                                  │
│       ▼                                                                  │
│  Step 3: 提交 PR                                                         │
│  ─────────────────                                                       │
│  提交 Pull Request,填写 PR 模板                                         │
│       │                                                                  │
│       ▼                                                                  │
│  Step 4: 等待审核                                                        │
│  ─────────────────                                                       │
│  GitHub Actions 自动验证 + 维护者审核                                    │
│  通常 1-3 个工作日                                                       │
│       │                                                                  │
│       ▼                                                                  │
│  Step 5: 合并上线                                                        │
│  ─────────────────                                                       │
│  PR 合并后自动构建 registry.json                                         │
│  ProxyCast 客户端自动同步                                                │
│       │                                                                  │
│       ▼                                                                  │
│  Step 6: 集成使用                                                        │
│  ─────────────────                                                       │
│  在用户后台添加"一键配置"按钮                                            │
│  用户可以一键配置 ProxyCast                                              │
│                                                                          │
└─────────────────────────────────────────────────────────────────────────┘

4.2 集成方式

方式一:直接链接

最简单的方式,直接在页面放置链接:

<a href="proxycast://connect?relay=myrelay&key=USER_API_KEY">
  一键配置 ProxyCast
</a>

方式二:JavaScript SDK

提供更好的用户体验:

<script src="https://proxycast.dev/sdk/connect.js"></script>

<button onclick="ProxyCast.connect({ relay: 'myrelay', key: userApiKey })">
  一键配置 ProxyCast
</button>

SDK 功能:

  • 自动检测 ProxyCast 是否安装
  • 未安装时显示下载引导
  • 支持回调函数
ProxyCast.connect({
  relay: 'myrelay',
  key: userApiKey,
  name: '我的Key',
  onSuccess: () => {
    showToast('配置成功!');
  },
  onNotInstalled: () => {
    // 显示自定义的下载引导
    showDownloadModal();
  }
});

方式三:配置文件下载

生成 .proxycast 配置文件供用户下载:

function downloadConfig(apiKey) {
  const config = {
    relay: 'myrelay',
    key: apiKey,
    name: '我的Key'
  };
  
  const blob = new Blob([JSON.stringify(config)], { type: 'application/json' });
  const url = URL.createObjectURL(blob);
  
  const a = document.createElement('a');
  a.href = url;
  a.download = 'myrelay.proxycast';
  a.click();
}

用户双击 .proxycast 文件,ProxyCast 自动打开并导入配置。

4.3 品牌素材要求

素材 规格 说明
Logo 256x256 PNG 透明背景,正方形
主题色 HEX 色值 用于 UI 强调色
简介 ≤50 字 一句话描述
详细描述 ≤200 字 详细介绍

4.4 API 要求

中转商的 API 需要满足:

要求 说明
协议兼容 OpenAI 或 Anthropic 协议
HTTPS 必须使用 HTTPS
模型列表 提供 /models 端点(可选)
稳定性 99% 以上可用性

五、安全设计

风险 防护措施
恶意链接 relay_id 必须在注册表中存在
Key 泄露 确认弹窗显示脱敏 Key,用户确认后才添加
钓鱼攻击 显示中转商完整信息,用户可核实

5.2 确认弹窗

所有通过 Deep Link 添加的 Key 必须经过用户确认:

┌─────────────────────────────────────────────────────────────────────────┐
│                                                                          │
│  ⚠️ 安全提示                                                             │
│                                                                          │
│  您正在添加来自 [XXX中转站] 的 API Key                                   │
│                                                                          │
│  请确认:                                                                │
│  1. 您确实在 XXX中转站 申请了此 Key                                      │
│  2. 您信任 XXX中转站 的服务                                              │
│                                                                          │
│  Key: sk-xxxx...xxxx                                                    │
│                                                                          │
│  [取消]                                        [我确认,添加此 Key]      │
│                                                                          │
└─────────────────────────────────────────────────────────────────────────┘

5.3 统计回调(Webhook)

为了让中转商追踪推广效果,ProxyCast 提供统计回调机制。

5.3.1 回调流程

┌─────────────────────────────────────────────────────────────────────────┐
│                     统计回调流程                                         │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                          │
│  用户点击一键配置                                                        │
│       │                                                                  │
│       ▼                                                                  │
│  ProxyCast 打开,显示确认弹窗                                            │
│       │                                                                  │
│       ├─── 用户取消 ─────────────────────────────────────────────────┐  │
│       │                                                               │  │
│       │    发送回调: status=cancelled                                 │  │
│       │                                                               │  │
│       └─── 用户确认 ─────────────────────────────────────────────────┐  │
│                                                                       │  │
│            Key 添加成功                                               │  │
│                 │                                                     │  │
│                 ▼                                                     │  │
│            发送回调: status=success                                   │  │
│                 │                                                     │  │
│                 ▼                                                     │  │
│            中转商收到回调,更新统计                                    │  │
│                                                                          │
└─────────────────────────────────────────────────────────────────────────┘

5.3.2 回调配置

中转商在 providers/{id}.json 中配置回调地址:

{
  "id": "myrelay",
  "name": "我的中转站",
  // ... 其他字段 ...
  
  "webhook": {
    "callback_url": "https://api.myrelay.com/proxycast/callback",
    "secret": "whsec_xxxxxxxxxxxxxxxx"
  }
}
字段 必填 说明
webhook.callback_url ❌ 回调地址(HTTPS)
webhook.secret ❌ 签名密钥,用于验证请求来源

5.3.3 回调请求格式

ProxyCast 向中转商发送 POST 请求:

POST https://api.myrelay.com/proxycast/callback
Content-Type: application/json
X-ProxyCast-Signature: sha256=xxxxxxxxxxxxxxxx
X-ProxyCast-Timestamp: 1704067200

{
  "event": "connect",
  "status": "success",
  "relay_id": "myrelay",
  "ref": "promo2024",
  "key_prefix": "sk-xxxx",
  "timestamp": "2026-01-05T12:00:00Z",
  "client": {
    "version": "1.2.0",
    "platform": "macos"
  }
}

5.3.4 回调字段说明

字段 说明
event 事件类型:connect
status 状态:success(成功)、cancelled(用户取消)、error(失败)
relay_id 中转商 ID
ref 推广码(如果有)
key_prefix Key 前缀(脱敏,仅前 7 位)
timestamp 事件时间
client.version ProxyCast 版本
client.platform 平台:macos、windows、linux
error_code 错误码(仅 status=error 时)
error_message 错误信息(仅 status=error 时)

5.3.5 签名验证

中转商应验证请求签名,防止伪造:

const crypto = require('crypto');

function verifySignature(payload, signature, secret, timestamp) {
  // 检查时间戳,防止重放攻击(5分钟内有效)
  const now = Math.floor(Date.now() / 1000);
  if (Math.abs(now - parseInt(timestamp)) > 300) {
    return false;
  }
  
  // 计算签名
  const signedPayload = `${timestamp}.${JSON.stringify(payload)}`;
  const expectedSignature = crypto
    .createHmac('sha256', secret)
    .update(signedPayload)
    .digest('hex');
  
  return `sha256=${expectedSignature}` === signature;
}

// Express 示例
app.post('/proxycast/callback', (req, res) => {
  const signature = req.headers['x-proxycast-signature'];
  const timestamp = req.headers['x-proxycast-timestamp'];
  
  if (!verifySignature(req.body, signature, WEBHOOK_SECRET, timestamp)) {
    return res.status(401).json({ error: 'Invalid signature' });
  }
  
  // 处理回调
  const { event, status, ref, key_prefix } = req.body;
  
  if (status === 'success') {
    // 记录成功安装
    await db.stats.increment({
      relay_id: req.body.relay_id,
      ref: ref,
      date: new Date().toISOString().split('T')[0]
    });
  }
  
  res.json({ received: true });
});

5.3.6 回调重试机制

重试次数 间隔 说明
第 1 次 立即 首次发送
第 2 次 1 分钟 首次失败后
第 3 次 5 分钟 第二次失败后
第 4 次 30 分钟 第三次失败后
放弃 - 超过 4 次不再重试

成功响应:HTTP 2xx 状态码

5.3.7 统计数据示例

中转商可以基于回调数据构建统计面板:

┌─────────────────────────────────────────────────────────────────────────┐
│  ProxyCast Connect 统计                                    2026-01-05   │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                          │
│  今日概览                                                                │
│  ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐   │
│  │     128      │ │     115      │ │     13       │ │    89.8%     │   │
│  │   点击次数   │ │   成功配置   │ │   用户取消   │ │    转化率    │   │
│  └──────────────┘ └──────────────┘ └──────────────┘ └──────────────┘   │
│                                                                          │
│  推广码效果                                                              │
│  ┌─────────────────────────────────────────────────────────────────┐    │
│  │ 推广码        点击    成功    取消    转化率                     │    │
│  ├─────────────────────────────────────────────────────────────────┤    │
│  │ promo2024     56      52      4       92.9%                     │    │
│  │ twitter       38      33      5       86.8%                     │    │
│  │ (无推广码)    34      30      4       88.2%                     │    │
│  └─────────────────────────────────────────────────────────────────┘    │
│                                                                          │
│  平台分布                                                                │
│  ┌─────────────────────────────────────────────────────────────────┐    │
│  │ macOS   ████████████████████████████████████  72%               │    │
│  │ Windows ████████████████                      23%               │    │
│  │ Linux   ████                                   5%               │    │
│  └─────────────────────────────────────────────────────────────────┘    │
│                                                                          │
└─────────────────────────────────────────────────────────────────────────┘

5.3.8 隐私保护

回调数据遵循最小化原则:

数据 是否发送 说明
完整 API Key ❌ 仅发送前 7 位前缀
用户 ID ❌ 不发送任何用户标识
设备 ID ❌ 不发送设备标识
IP 地址 ❌ 不发送用户 IP
推广码 ✅ 用于统计推广效果
平台信息 ✅ 仅操作系统类型

5.4 中转商审核

审核项 说明
身份核实 验证中转商运营者身份
API 测试 测试 API 可用性和兼容性
安全检查 检查是否有恶意行为历史
持续监控 定期检查服务状态

七、商业模式

7.1 免费服务

基础功能对中转商免费:

  • 注册和审核
  • Deep Link 功能
  • 扩展市场展示
  • 基础统计

7.2 增值服务(可选)

服务 说明 定价
官方认证 显示认证徽章,优先展示 待定
推荐位 扩展市场首页推荐 待定
高级统计 详细用户行为分析 待定
定制 UI 自定义品牌页面 待定

7.3 合作模式

┌─────────────────────────────────────────────────────────────────────────┐
│                     合作共赢                                             │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                          │
│  中转商                          ProxyCast                               │
│  ──────                          ─────────                               │
│                                                                          │
│  推广 ProxyCast    ──────────▶   用户增长                               │
│                                                                          │
│  用户转化率提升    ◀──────────   一键配置功能                           │
│                                                                          │
│  品牌曝光          ◀──────────   扩展市场展示                           │
│                                                                          │
│  用户粘性          ◀──────────   统一管理体验                           │
│                                                                          │
└─────────────────────────────────────────────────────────────────────────┘

六、实施计划

6.1 Phase 1: MVP (2 周)

任务 说明
Deep Link 协议 实现 proxycast://connect
确认弹窗 安全确认 UI
注册表加载 从 GitHub 加载 registry.json
transit-service-provider 仓库 初始化仓库结构和 CI

6.2 Phase 2: 完善 (2 周)

任务 说明
Web 中转页 proxycast.dev/connect
JS SDK 前端集成 SDK
扩展市场展示 中转商品牌页
.proxycast 文件支持 配置文件导入

6.3 Phase 3: 生态 (持续)

任务 说明
中转商招募 邀请主流中转商提交 PR
文档完善 接入指南、最佳实践
社区运营 GitHub Discussions

七、总结

7.1 核心价值

ProxyCast Connect 通过一键配置功能,实现:

  1. 用户 - 零配置接入,开箱即用
  2. 中转商 - 用户转化率提升,品牌曝光
  3. ProxyCast - 用户增长,生态繁荣

7.2 开源优势

优势 说明
透明 所有中转商信息公开可查
去中心化 无需依赖 ProxyCast 官方服务器
社区驱动 任何人都可以贡献和审核
低成本 无需维护注册后台

7.3 关键指标

指标 目标
接入中转商数量 20+
GitHub Stars 1,000+
一键配置转化率 80%+

7.4 相关仓库

仓库 说明
proxycast ProxyCast 主项目
transit-service-provider 中转商注册仓库