# WB(WorkBuddy)与 Trae 每日签到核心请求 > 本文档整理自仓库现有实现(源码为准): > - `app/src/main/java/com/rainy/token/data/repository/TraeRepository.kt` > - `app/src/main/java/com/rainy/token/data/repository/WorkBuddyRepository.kt` > > 其中 **WB = 腾讯 WorkBuddy**(非微博)。所有请求均为 `POST`,body 默认为 `{}`。 ## 一、端点汇总 | 服务 | 用途 | URL | Body | | --- | --- | --- | --- | | Trae(CN) | 查询签到状态 | `https://api.trae.cn/trae/api/v2/ug/checkin_credits/status` | `{}` | | Trae(CN) | 执行签到 | `https://api.trae.cn/trae/api/v2/ug/checkin_credits/claim` | `{}`(9074 时换 `{"req_source":2}` → `{"req_source":1}`) | | WorkBuddy | 查询签到状态(优先) | `https://www.codebuddy.cn/v2/billing/meter/checkin-activity-status` | `{}` | | WorkBuddy | 查询签到状态(兜底) | `https://www.codebuddy.cn/v2/billing/meter/checkin-status` | `{}` | | WorkBuddy | 执行签到 | `https://www.codebuddy.cn/v2/billing/meter/daily-checkin` | `{}` | | WorkBuddy | accessToken 刷新 | `https://copilot.tencent.com/v2/plugin/auth/token/refresh` | 头 `X-Refresh-Token` | ## 二、Trae 核心请求源码 认证头:`Authorization: Cloud-IDE-JWT `,`x-device-id` 必须是账号绑定的官方客户端设备 ID。 ```kotlin // 官方签到接口路径 const val CHECKIN_STATUS_PATH = "/trae/api/v2/ug/checkin_credits/status" const val CHECKIN_CLAIM_PATH = "/trae/api/v2/ug/checkin_credits/claim" private fun checkinRequest( jwt: String, deviceId: String, deviceSrc: String, path: String, bodyJson: String = "{}" ): Result { val requestId = java.util.UUID.randomUUID().toString() val request = Request.Builder() .url("https://api.trae.cn" + path) .addHeader("Content-Type", "application/json") .addHeader("Accept", "*/*") .addHeader("User-Agent", "VSCode 1.107.1 (TRAE SOLO CN)") .addHeader("Authorization", "Cloud-IDE-JWT " + jwt) .addHeader("X-User-Region", "CN") .addHeader("Accept-Language", "zh-CN") .addHeader("Package-Type", "stable_cn") .addHeader("X-Lgw-Req-Sdk-Type", "3") .addHeader("X-Market-Client-Id", "VSCode 1.107.1") .addHeader("X-Device-Brand", "83DG") .addHeader("X-Device-Type", "windows") .addHeader("X-OS-Version", "Windows 11 Pro") .addHeader("App-Version", "0.1.61") .addHeader("X-Request-Id", requestId) .addHeader("X-TT-Trace-Id", ttTraceId(requestId)) .addHeader("X-Device-Id", deviceId) .addHeader("Sec-Fetch-Dest", "empty") .addHeader("Sec-Fetch-Mode", "no-cors") .addHeader("Sec-Fetch-Site", "none") .post(bodyJson.toRequestBody("application/json".toMediaType())) .build() // ... } ``` ### Trae 签到结果判定 - `code = 0 / 200` → **SUCCESS**(成功) - `code = 1001 / 10001`,或文案含 `已签到 / 已经签到 / 明日再来 / 今日已完成 / 已领取 / already / checked / claimed` → **ALREADY**(今日已签) - 文案含 `设备 / device / machine` → **DEVICE_BLOCKED**(设备级拦截) - 文案含 `参与 / 稍后重试 / 火爆 / 繁忙 / 限流 / 排队 / too many / retry / busy / popular / later` → **RETRYABLE**(临时限流) - 其余 → **FAILED** ### Trae 注意事项 - UA 必须是 `VSCode 1.107.1 (TRAE SOLO CN)`,这是签到走的 VSCode 插件进程身份;与 IDE 主进程 / Web 混用会触发风控。 - `X-Device-Id` 不可用固定 ClientID `en1oxy7wnw8j9n`(所有用户相同),会按设备风控拒绝。 - 仓库内置默认设备 ID:`ACCOUNT_BOUND_DEVICE_ID = "895482260673817"`,账号级,换设备需更新。 - INTL 区签到接口未实测,仓库实现直接不支持。 ## 三、WorkBuddy(WB)核心请求源码 认证头:`Authorization: Bearer `。签到域名是 `www.codebuddy.cn`(余额主查询才是 `www.workbuddy.cn`)。 ```kotlin // 查询今日签到状态(两条路径依次 fallback,共享 token 轮换状态) suspend fun fetchCheckinStatus(accountId: String? = null): Result { val body = authedPostFirstSuccessful( credential, accountId, "/v2/billing/meter/checkin-activity-status", "/v2/billing/meter/checkin-status" ) ?: return Result.failure(RepositoryError.Unknown()) return runCatching { parseCheckin(body) }... } // 执行签到 suspend fun checkIn(accountId: String? = null): Result { val body = when (val r = authedPost(credential, "/v2/billing/meter/daily-checkin")) { is AuthedPostResult.Ok -> r.body is AuthedPostResult.Failed -> r.body // ... } // code=0 成功;code=10001 或文案含「已签/今日/already」→ 已签 } // 带自动 refresh 一次的 POST 核心 private fun authedPost(credential: Credential.WorkBuddyCredential, path: String): AuthedPostResult { var access = credential.accessToken var refresh = credential.refreshToken repeat(2) { attempt -> val request = Request.Builder() .url("https://www.codebuddy.cn" + path) .addHeader("Authorization", "Bearer " + access) .addHeader("Accept", "application/json") .addHeader("Content-Type", "application/json") .post("{}".toRequestBody(jsonMedia)) .build() // 2xx → Ok // 401/403 且第一次尝试 → tryRefesh(refresh) 换新 token 后重试 // refresh 请求头携带 X-Refresh-Token // 轮换出的新凭据必须先落库再用,否则旧 refreshToken 单次消费后失效 } } ``` ### WorkBuddy 签到结果判定 - `code = 0` → **SUCCESS** - `code = 10001`,或文案含 `已签 / 已经签到 / 今日 / already / checked / claimed` → **ALREADY**(今日已签) - 其余 → **FAILED**(HTTP 400 body 也可能携带签到业务语义,需透传解析,不能直接当网络错误丢弃) ## 四、通用约定 1. Trae 用 `Cloud-IDE-JWT`,WorkBuddy 用 `Bearer`,两者凭据类型不同,不能混用。 2. 两者签到都幂等:今日已签时服务端返回已签语义,客户端本地也会记录 `lastCheckinDate` 短路,避免重复请求。 3. 401/403:Trae 直接视为凭据失效;WorkBuddy 会尝试用 refreshToken 轮换一次。 4. 不要随机生成设备 ID(Trae)或篡改客户端头,否则会被风控(Trae 9074「参与用户太多」)。