package activity import "douyu_go/internal/constants" // Activity 描述一个斗鱼手册活动的全部接口参数。 // // 不同活动(精英手册 / 电竞手册)的 manualID、roomID、actAlias 以及接口路径段都不同, // 集中在这里可以让调度核心逻辑保持活动无关,新增活动只需在 registry 中加一项。 // // 注意:peacematch 的 exchange / preExchange / batchExchangeLimit / storedetail 端点 // 没有出现在抓包里,这里按 peace 的 1:1 路径映射推断(storehome、exchangeList 已验证 // 确实落在 peacematch 路径下)。若实际抢购报错,优先核对这几个端点。 type Activity struct { ID string // 注册表 key,例如 "peace" / "peacematch" DisplayName string // 前端展示名 ManualID string RoomID string ActAlias string BaseURL string ShopReferer string StoreHomeURL string CSRFURL string BatchLimitURL string PreExchangeURL string ExchangeURL string ExchangeListURL string BindInfoURL string ScoreURL string ScoreMethod string // "POST" 或 "GET" // UseCTN 为 true 时(电竞手册),兑换接口用 ctn(acf_ccn) 鉴权而非 csrfToken: // - 表单发 ctn 字段(值=acf_ccn),不发 csrfToken // - cvl_csrf_token 只放 Cookie 头 // - 跳过 batchExchangeLimit / preExchange(Python 实现直接调 exchange) // - Content-Type 用 application/x-www-form-urlencoded UseCTN bool CTNURL string // 获取 acf_ccn 的接口(UseCTN=true 时必填) } const douyuBase = constants.BaseURL // peace 精英手册(旧活动,ActAlias=20260120QYOOB)。 var peace = &Activity{ ID: "peace", DisplayName: "精英手册", ManualID: "G4KA4Qnz4LDp7", RoomID: "9263298", ActAlias: "20260120QYOOB", BaseURL: douyuBase, ShopReferer: douyuBase + "/pages/live-peace-handbook/web/shop?ditchname=pass0&roomId=9263298", StoreHomeURL: douyuBase + "/wgapi/ordnc/activity/peace/storehome?manualID=G4KA4Qnz4LDp7&rid=9263298", CSRFURL: douyuBase + "/japi/carnival/nc/common/generateCsrf", BatchLimitURL: douyuBase + "/wgapi/ordnc/activity/peace/batchExchangeLimit", PreExchangeURL: douyuBase + "/wgapi/ordnc/activity/peace/preExchange", ExchangeURL: douyuBase + "/wgapi/ordnc/activity/peace/exchange", ExchangeListURL: douyuBase + "/wgapi/ordnc/activity/peace/exchangeList?manualID=G4KA4Qnz4LDp7&limit=100&offset=0", BindInfoURL: douyuBase + "/japi/carnivalApi/v2/tencent/bindInfo?actAlias=20260120QYOOB", ScoreURL: douyuBase + "/japi/oms/web/peace/credit/balance", ScoreMethod: "POST", UseCTN: false, } // peacematch 电竞手册(新活动,ActAlias=20260226ZMGDG)。 // 数据来源:/Users/yml/Desktop/抓包/douyu/7.29/电竞手册-基础信息.har 及 7.28 系列抓包。 var peacematch = &Activity{ ID: "peacematch", DisplayName: "电竞手册", ManualID: "1W0yGkOdDbAXb", RoomID: "9263298", ActAlias: "20260226ZMGDG", BaseURL: douyuBase, ShopReferer: douyuBase + "/pages/live-peace-pel/web/shop?roomId=9263298&isAnchorSide=0", StoreHomeURL: douyuBase + "/wgapi/ordnc/activity/peacematch/storehome?manualID=1W0yGkOdDbAXb&rid=9263298", // generateCsrf 为嘉年华平台级接口,抓包未单独出现,沿用 peace 同款端点。 CSRFURL: douyuBase + "/japi/carnival/nc/common/generateCsrf", // 以下 4 个兑换类端点未在抓包中捕获,按 peace 的 1:1 路径映射推断,待实跑验证。 BatchLimitURL: douyuBase + "/wgapi/ordnc/activity/peacematch/batchExchangeLimit", PreExchangeURL: douyuBase + "/wgapi/ordnc/activity/peacematch/preExchange", ExchangeURL: douyuBase + "/wgapi/ordnc/activity/peacematch/exchange", ExchangeListURL: douyuBase + "/wgapi/ordnc/activity/peacematch/exchangeList?manualID=1W0yGkOdDbAXb&limit=100&offset=0", BindInfoURL: douyuBase + "/wgapi/ordnc/live/memberthird/tencent/bindInfo?actAlias=20260226ZMGDG", ScoreURL: douyuBase + "/wgapi/ordnc/activity/peacematch/score/balance", ScoreMethod: "GET", UseCTN: true, CTNURL: douyuBase + "/curl/csrfNlApi/getCsrfCookie", } var registry = map[string]*Activity{ peace.ID: peace, peacematch.ID: peacematch, } // DefaultActivityID 默认活动,新分支默认启用「电竞手册」。 const DefaultActivityID = "peacematch" // List 返回所有注册活动,按注册顺序(精英手册在前)。 func List() []*Activity { return []*Activity{peace, peacematch} } // Get 按 ID 获取活动;不存在时返回 nil。 func Get(id string) *Activity { if id == "" { return nil } return registry[id] } // Default 返回默认活动。 func Default() *Activity { if a := registry[DefaultActivityID]; a != nil { return a } return peace }