1.购买服务器阿里云:服务器购买地址https://t.aliyun.com/U/DT4XYh若失效,可用地址
阿里云:
服务器购买地址
https://t.aliyun.com/U/DT4XYh若失效,可用地址
https://www.aliyun.com/activity/wuying/dj?source=5176.29345612&userCode=49hts92d腾讯云:
https://curl.qcloud.com/wJpWmSfU若失效,可用地址
https://cloud.tencent.com/act/cps/redirect?redirect=2446&cps_key=ad201ee2ef3b771157f72ee5464b1fea&from=console华为云
https://activity.huaweicloud.com/cps.html?fromacct=64b5cf7cc11b4840bb4ed2ea0b2f4468&utm_source=V1g3MDY4NTY=&utm_medium=cps&utm_campaign=2019052.部署教程
3.代码如下
// 喜马拉雅自动签到脚本// 支持自动签到和Cookie更新const KEY_COOKIE = 'ximalaya_cookie'const KEY_TOKEN = 'ximalaya_token'const KEY_USERID = 'ximalaya_userid'const KEY_LAST_SIGN = 'ximalaya_last_sign'const KEY_DEVICE_ID = 'ximalaya_device_id'// 主函数async function main() {// 获取存储的Cookie和Tokenconst cookie = $persistentStore.read(KEY_COOKIE)const token = $persistentStore.read(KEY_TOKEN)const userId = $persistentStore.read(KEY_USERID)const deviceId = $persistentStore.read(KEY_DEVICE_ID) || generateDeviceId()if (!cookie || !token || !userId) {$notification.post('喜马拉雅签到', '失败', '未找到认证信息,请打开喜马拉雅小程序')return}// 检查今日是否已签到const lastSignDate = $persistentStore.read(KEY_LAST_SIGN)const today = new Date().toDateString()if (lastSignDate === today) {$notification.post('喜马拉雅签到', '跳过', '今日已签到过')return}try {// 执行签到const signResult = await performSignIn(cookie, token, userId, deviceId)if (signResult.code === 0) {// 签到成功$persistentStore.write(today, KEY_LAST_SIGN)$notification.post('喜马拉雅签到', '成功', `获得奖励: ${signResult.data.award.award_received_text}`)// 获取积分信息const integralResult = await getIntegral(cookie, token, userId, deviceId)if (integralResult.code === 10000) {$notification.post('喜马拉雅积分', `当前积分: ${integralResult.result.integral}`, '')}} else {$notification.post('喜马拉雅签到', '失败', `错误: ${signResult.msg}`)}} catch (error) {$notification.post('喜马拉雅签到', '错误', error.message || '未知错误')}}// 执行签到async function performSignIn(cookie, token, userId, deviceId) {const timestamp = Date.now()const nonce = generateNonce()// 构建签名参数(需要根据实际算法调整)const signParams = {device_id: deviceId,sn: '11480_00_100480',version: '2.1',app_key: 'e23df0e3d21c4379bf2a5b302a843a25',device_id_type: 'UUID',version_code: '9094',product_type: 'child_watches_okii',client_os_type: '2',nonce: nonce,timestamp: timestamp,user_id: userId}// 生成签名(需要根据实际算法实现)const sig = generateSignature(signParams)signParams.sig = sig// 构建请求参数const formBody = Object.keys(signParams).map(key =>encodeURIComponent(key) + '=' + encodeURIComponent(signParams[key])).join('&')return new Promise((resolve, reject) => {$httpClient.post({url: 'https://api.ximalaya.com/ximalayaos-smart-wear/api/parent_sign_in/sign_in',headers: {'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8','Cookie': cookie,'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 18_3_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 MicroMessenger/8.0.63(0x18003f28) NetType/WIFI Language/zh_CN','Referer': 'https://m.ximalaya.com/','Origin': 'https://m.ximalaya.com'},body: formBody}, (error, response, data) => {if (error) {reject(error)} else {try {resolve(JSON.parse(data))} catch (e) {reject(e)}}})})}// 获取积分信息async function getIntegral(cookie, token, userId, deviceId) {const timestamp = Date.now()const nonce = generateNonce()// 构建签名参数const signParams = {device_id: deviceId,sn: '11480_00_100480',version: '2.2',app_key: 'e23df0e3d21c4379bf2a5b302a843a25',device_id_type: 'UUID',version_code: '9093',product_type: 'child_watches_okii',client_os_type: '3',nonce: nonce,timestamp: timestamp,userId: userId}// 生成签名const sig = generateSignature(signParams)const url = `https://api.ximalaya.com/ximalayaos-smart-wear/api/integral/getUserIntegral?${Object.keys(signParams).map(key =>encodeURIComponent(key) + '=' + encodeURIComponent(signParams[key])).join('&')}&sig=${encodeURIComponent(sig)}`return new Promise((resolve, reject) => {$httpClient.get({url: url,headers: {'Cookie': cookie,'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 18_3_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 MicroMessenger/8.0.63(0x18003f28) NetType/WIFI Language/zh_CN','Referer': 'https://m.ximalaya.com/'}}, (error, response, data) => {if (error) {reject(error)} else {try {resolve(JSON.parse(data))} catch (e) {reject(e)}}})})}// HTTP请求处理(用于抓取Cookie和Token)function handleHTTPRequest(request) {// 只处理喜马拉雅API请求if (request.url.includes('api.ximalaya.com')) {// 获取请求头中的Cookieconst cookie = request.headers['Cookie'] || request.headers['cookie']if (cookie && cookie.includes('_token')) {// 提取Tokenconst tokenMatch = cookie.match(/_token=([^&;]+)/)if (tokenMatch && tokenMatch[1]) {$persistentStore.write(tokenMatch[1], KEY_TOKEN)// 尝试从Token中提取用户IDconst userIdMatch = tokenMatch[1].match(/(\d+)/)if (userIdMatch && userIdMatch[1]) {$persistentStore.write(userIdMatch[1], KEY_USERID)}}// 保存完整Cookie$persistentStore.write(cookie, KEY_COOKIE)// 生成设备ID并保存const deviceId = generateDeviceId()$persistentStore.write(deviceId, KEY_DEVICE_ID)}}// 继续原始请求return request}// HTTP响应处理function handleHTTPResponse(response) {// 可以在这里处理响应,例如检查是否认证过期if (response.status === 401 || response.status === 403) {// 认证过期,清除保存的认证信息$persistentStore.write('', KEY_COOKIE)$persistentStore.write('', KEY_TOKEN)$notification.post('喜马拉雅认证', '过期', '请重新打开喜马拉雅小程序以更新认证信息')}return response}// 生成随机设备IDfunction generateDeviceId() {const randomStr = Math.random().toString(36).substring(2, 12)return `h5_${randomStr}_2.4.25`}// 生成随机Noncefunction generateNonce() {const chars = 'abcdefghijklmnopqrstuvwxyz0123456789'let nonce = ''for (let i = 0; i < 32; i++) {nonce += chars.charAt(Math.floor(Math.random() * chars.length))}return nonce}// 生成签名(需要根据实际算法实现)function generateSignature(params) {// 这里是签名算法的伪实现// 实际签名算法需要根据喜马拉雅的实际算法进行调整// 可能需要使用MD5、SHA1或其他哈希算法// 示例:将参数按key排序后拼接成字符串,然后进行MD5哈希const sortedKeys = Object.keys(params).sort()let signStr = ''for (const key of sortedKeys) {signStr += key + params[key]}// 添加密钥(如果有)signStr += 'your_secret_key'// 返回模拟签名(实际需要实现正确的哈希算法)return md5(signStr)}// MD5哈希函数(示例实现)function md5(str) {// 这是一个简单的MD5实现示例// 在实际使用中,可能需要使用更完整的MD5实现let hash = 0if (str.length === 0) return hash.toString()for (let i = 0; i < str.length; i++) {const char = str.charCodeAt(i)hash = (hash << 5) - hash + charhash = hash & hash // Convert to 32bit integer}return hash.toString()}// 模块导出if (typeof $argument !== 'undefined') {// 脚本被调用时执行main()}if (typeof $request !== 'undefined') {// HTTP请求处理const modifiedRequest = handleHTTPRequest($request)$done(modifiedRequest)}if (typeof $response !== 'undefined') {// HTTP响应处理const modifiedResponse = handleHTTPResponse($response)$done(modifiedResponse)}
解析
该脚本为喜马拉雅自动签到脚本,其主要作用如下:
在网络脚本环境中,自动完成喜马拉雅小程序的每日签到,并查询积分。
通过重写规则拦截请求,自动抓取并持久化 Cookie/Token/用户ID/设备ID,后续定时任务即可静默签到。
记录"今日是否已签",避免重复提交。
关键存储键
ximalaya_cookie:完整 Cookieximalaya_token:从 Cookie 提取的 token(或单独保存)ximalaya_userid:用户 IDximalaya_last_sign:上次签到日期(用于去重)ximalaya_device_id:设备 ID(无则生成)
主流程入口
main()读 Cookie/Token/UserId/DeviceId → 校验。
判断是否已签到(比对
ximalaya_last_sign与今天)。调用
performSignIn()执行签到;成功后写入今天日期。调用
getIntegral()查询当前积分。通过系统通知展示结果。
HTTP 拦截与认证信息更新
handleHTTPRequest(request)抓取请求头里的 Cookie;从中提取
_token并保存到ximalaya_token;尝试从 token 中提取用户 ID 保存到
ximalaya_userid;保存完整 Cookie 到
ximalaya_cookie;若无设备 ID,生成并保存。
当 URL 命中
api.ximalaya.com:返回(可能被修改的)请求,继续原始访问。
handleHTTPResponse(response)若状态为 401/403,则清空已保存的认证信息并发出"认证过期"提示。
返回响应。
以上两者依赖你在 配置 rewrite/script 规则与 MITM,脚本才能"看到"请求/响应并写入持久化数据。
具体业务请求
performSignIn(cookie, token, userId, deviceId)组装签到所需参数
(device_id/sn/version/app_key/.../nonce/timestamp/user_id)通过
generateSignature()生成sig;POST到签到接口。返回接口 JSON。
getIntegral(cookie, token, userId, deviceId)同样组装参数并生成
sig;GET查询积分。返回接口 JSON。
签名与标识辅助
generateSignature(params)签名生成函数:当前为示例/占位实现(把排序后的参数拼接并"md5"),实际需按喜马拉雅真实算法调整。
md5(str)示例/占位哈希函数:并非真正 MD5,仅作演示。
generateDeviceId()生成随机设备 ID(形如
h5_xxxxx_2.4.25),并在首次抓取时保存。generateNonce()生成 32 位的随机 nonce。
其他逻辑
通过
$persistentStore.read/write持久化数据;通过
$notification.post发送结果通知;通过
$httpClient.get/post发起请求;入口控制:
存在
$argument时执行main()(定时任务/手动触发);存在
$request时走handleHTTPRequest();存在
$response时走handleHTTPResponse()。
使用要点(简述)
需要在配置相应的 rewrite + MITM,使脚本能拦截喜马拉雅请求以自动更新 Cookie/Token。
generateSignature()与md5()仅为占位,需要按实际抓包或逆向的算法替换为真实签名,否则签到/查询很可能失败。ximalaya_last_sign用于当日去重,避免多次请求。
注意:
本文部分变量已做脱敏处理,仅用于测试和学习研究,禁止用于商业用途,不能保证其合法性,准确性,完整性和有效性,请根据情况自行判断。技术层面需要提供帮助,可以通过打赏的方式进行探讨。
没有评论:
发表评论