2025年4月28日星期一

小牛电动任务脚本

1.购买服务器阿里云:服务器购买地址https://t.aliyun.com/U/mS108v若失效,可用

1.购买服务器

阿里云:

服务器购买地址

https://t.aliyun.com/U/mS108v

若失效,可用地址

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=201905

2.部署教程

2024年最新青龙面板跑脚本教程(一)持续更新中

3.代码如下

/** * 小牛电动 APP * 账号#密码 * export XNIU_ACCOUNT = '18888888888#123456' * 多账号用 & 或换行 * const $ = new Env('小牛电动') * cron: 19 11 * * * */const initScript = require('init')const {$, notify, sudojia, checkUpdate} = initScript('小牛电动');const xniuList = process.env.XNIU_ACCOUNT ? process.env.XNIU_ACCOUNT.split(/[\n&]/) : [];// 消息推送let message = '';// 接口地址const baseUrl = 'https://www.niu.com/'// 请求头const headers = {    'User-Agent''manager/5.7.4 (android; OPPO R9s 9);lang=zh-CN;clientIdentifier=Domestic;timezone=Asia/Shanghai;model=OPPO_OPPO R9s;deviceName=OPPO R9s;ostype=android',    'Content-Type''application/json',    'Accept-Encoding''gzip',};
!(async () => {    await checkUpdate($.name, xniuList);    for (let i = 0; i < xniuList.length; i++) {        const index = i + 1;        $.isLogin = true;        let [phone, pwd] = xniuList[i].split('#');        console.log(`\n*****第[${index}]个${$.name}账号*****`);        await getToken(phone, sudojia.md5(pwd));        if (!$.isLogin) {            continue;        }        await $.wait(sudojia.getRandomWait(8001200));        await main();        await $.wait(sudojia.getRandomWait(20002500));    }    if (message) {        await notify.sendNotify(`「${$.name}」``${message}`);    }})().catch((e) => $.logErr(e)).finally(() => $.done());
async function main() {    await getUserInfo();    await $.wait(sudojia.getRandomWait(12002000));    await getQuestionList();    await $.wait(sudojia.getRandomWait(20002500));    await readGuide();    await $.wait(sudojia.getRandomWait(20002500));    await getPostIdByCity();    await $.wait(sudojia.getRandomWait(20002500));    await followUser();    await $.wait(sudojia.getRandomWait(30003500));    await followUser();    await $.wait(sudojia.getRandomWait(20002500));    await getPoints();}
/** * 获取 token * * @param phone   手机号 * @param pwd     密码 * @returns {Promise<void>} */async function getToken(phone, pwd) {    try {        const headerCp = JSON.parse(JSON.stringify(headers));        headerCp['Content-Type'] = 'application/x-www-form-urlencoded';        headerCp.token = 'tokenExperienceMode';        const params = `password=${pwd}&grant_type=password&scope=base&app_id=niu_ktdrr960&account=${phone}`        const data = await sudojia.sendRequest(`https://www.niu.com//v3/api/oauth2/token`'post', headerCp, params);        if (0 !== data.status) {            console.log(data.desc);            $.isLogin = false;            return;        }        console.log('登录成功~');        headers.token = data.data.token.access_token;        $.userId = data.data.user.user_id;    } catch (e) {        console.error(`获取 token 时发生异常:` + e);        $.isLogin = false;    }}
/** * 获取用户信息 * * @returns {Promise<void>} */async function getUserInfo() {    try {        const data = await sudojia.sendRequest(`${baseUrl}/community/api/user/profile?user_id=${$.userId}`'get', headers);        if (0 !== data.status) {            console.log(data.desc);            return;        }        console.log(`昵称:${data.data.user_nick_name}`);        message += `昵称:${data.data.user_nick_name}\n`;    } catch (e) {        console.error(`获取用户信息时发生异常:` + e);    }}
/** * 获取问题列表 * type:1 热门 2 最新提问 3 最新回答 * * @returns {Promise<*>} */async function getQuestionList() {    try {        const data = await sudojia.sendRequest(`${baseUrl}/community/api/qa/list?type=2&category_id=&page=1&page_size=30&_=${Date.now()}`'get', headers);        if (0 !== data.status) {            console.log(data.desc);            return;        }        const quest = data.data.items[Math.floor(Math.random() * data.data.items.length)];        console.log(`开始回答[${quest.content}]`);        await $.wait(sudojia.getRandomWait(20002500));        await getAnswer(quest.id);    } catch (e) {        console.error(`获取问题列表时发生异常:` + e);    }}
/** * 获取回答评论 * * @param pid * @returns {Promise<void>} */async function getAnswer(pid) {    try {        const data = await sudojia.sendRequest(`${baseUrl}/community/api/posts/comments/list?parent_id=${pid}&parent_type=1&page=1&page_size=20&hide_hot=1&version=2&_=${Date.now()}`'get', headers);        if (0 !== data.status) {            console.log(data.desc);            return;        }        let answer;        if (!data.data.items || data.data.items.length === 0) {            console.log('这个问题的回答评论为空,将使用默认的回答评论【我也遇到过】');            answer = '我也遇到过';        } else {            answer = data.data.items[Math.floor(Math.random() * data.data.items.length)].content;        }        console.log(`开始回答评论 -> ${answer}`);        await $.wait(sudojia.getRandomWait(20002500));        await postAnswer(pid, answer);    } catch (e) {        console.error(`获取回答评论时发生异常:` + e);    }}
/** * 回答问题 * * @param pid * @param content * @returns {Promise<void>} */async function postAnswer(pid, content) {    try {        const data = await sudojia.sendRequest(`${baseUrl}/community/api/posts/comments`'post', headers, {            "content": content,            "object"2,            "parent_id": pid        });        if (0 !== data.status) {            console.log(data.desc);            return;        }        console.log(`回答成功`);    } catch (e) {        console.error(`回答问题时发生异常:` + e);    }}
/** * 阅读社区指引 * * @returns {Promise<void>} */async function readGuide() {    try {        const data = await sudojia.sendRequest(`${baseUrl}/community/api/posts/detail?id=1940&version=2&_=${Date.now()}`'get', headers);        if (0 !== data.status) {            console.log(data.desc);            return;        }        await $.wait(sudojia.getRandomWait(20002500));        console.log(`阅读社区指引完成`);    } catch (e) {        console.error(`阅读社区指引时发生异常:` + e);    }}
/** * 根据不同的城市获取文章ID * * @returns {Promise<void>} */async function getPostIdByCity() {    try {        for (let i = 0; i < 2; i++) {            const cityCodeList = ['110000''120000''310000''440100''440300''320400''441900''442000''441300''440700''431100''371000'];            const city = cityCodeList[Math.floor(Math.random() * cityCodeList.length)];            const data = await sudojia.sendRequest(`${baseUrl}/community/api/group/city/recommend_list?city_code=${city}&last_score=0&page_size=20&_=${Date.now()}`'get', headers);            if (0 !== data.status) {                console.log(data.desc);                return;            }            const {id, user_id} = data.data.items[Math.floor(Math.random() * data.data.items.length)];            await $.wait(sudojia.getRandomWait(20002500));            await share(id);            await $.wait(sudojia.getRandomWait(8001200));            $.uid = user_id;        }    } catch (e) {        console.error(`获取文章ID时发生异常:` + e);    }}
/** * 分享文章 * * @param postId 文章ID * @returns {Promise<void>} */async function share(postId) {    try {        const data = await sudojia.sendRequest(`${baseUrl}/community/api/posts/shares`'post', headers, {            "id": postId        });        if (0 !== data.status) {            console.log(data.desc);            return;        }        console.log(`分享文章成功`);    } catch (e) {        console.error(`分享文章时发生异常:` + e);    }}
/** * 关注用户 * * @returns {Promise<void>} */async function followUser() {    try {        const data = await sudojia.sendRequest(`${baseUrl}/community/api/user/follow/create`'post', headers, {            "follow_user_id": $.uid        });        if (0 !== data.status) {            console.log(data.desc);            return;        }        if (2 === data.data.followType) {            console.log(`关注用户成功`);        } else {            console.log(`取关用户成功`);        }    } catch (e) {        console.error(`关注用户时发生异常:` + e);    }}

/** * 获取积分 * * @returns {Promise<void>} */async function getPoints() {    try {        const data = await sudojia.sendRequest(`${baseUrl}/v5/points/index`'get', headers);        if (0 !== data.status) {            console.log(data.desc);            return;        }        console.log(`当前积分:${data.data.userPoints}`);        message += `当前积分:${data.data.userPoints}\n\n`;    } catch (e) {        console.error(`获取积分时发生异常:` + e);    }}

解析

这是小牛电动APP脚本。

功能模块
描述
多账号支持
使用环境变量 XNIU_ACCOUNT,格式为 手机号#密码,支持 & 或换行分隔
登录认证
自动获取 token 并注入请求头,失败时输出详细提示
用户信息
显示昵称、用户 ID 等信息
自动答题
随机获取问答并自动选择已有回答或默认回复
阅读社区内容
模拟阅读社区公告,增加活跃度任务
城市文章互动
自动抓取城市文章并分享
关注/取关用户
实现用户关注交互任务
查询当前积分
自动查询并推送积分信息
通知推送
将任务执行结果以文本推送

登录机制

  • 使用 OAuth 接口 

  • 参数包含加密后的密码(MD5)

  • 登录成功返回 access_token,后续所有接口均使用该 token 鉴权

环境变量

export XNIU_ACCOUNT="18888888888#yourpassword1&19999999999#yourpassword2"


核心任务

函数
说明
getQuestionList()
获取随机提问,挑选已有回答或默认回答
getPostIdByCity()
抓取不同城市下的文章 ID 并分享
readGuide()
阅读"社区指引"帖子
followUser()
对抓到的用户进行关注/取关
getPoints()
查询当前积分并追加到推送消息中

推送样例输出

📣====小牛电动账号[1]====📣
昵称:小牛用户123
当前积分:2080




注意

本文部分变量已做脱敏处理,仅用于测试和学习研究,禁止用于商业用途,不能保证其合法性,准确性,完整性和有效性,请根据情况自行判断。技术层面需要提供帮助,可以通过打赏的方式进行探讨。


没有评论:

发表评论

打字也能赚钱?这3个零撸正规赚钱平台,一单一结200,复制粘贴即可!

你是否厌倦了 "死工资" 的循环?看着别人朋友圈里的 "诗和远方",心里满是羡慕却不敢行动? 其实搞副业不是非要做大项目——关键是找到匹配自己时间、能力和风险承受力的事。 有人下班后摆摊卖手工饰品,有人利用专业知识做线上咨询,有人把兴趣...