Compare commits

..
6 Commits
Author SHA1 Message Date
shanmite 949d580c65 docs: 更新CHANGELOG
Build and push Docker images / docker (push) Has been cancelled
Mirror and run GitLab CI / build (push) Has been cancelled
Package Node.js project into an executable / node${{ matrix.nodev }}-${{ matrix.platform }}-x64 (18, linux) (push) Has been cancelled
Package Node.js project into an executable / node${{ matrix.nodev }}-${{ matrix.platform }}-x64 (18, macos) (push) Has been cancelled
Package Node.js project into an executable / node${{ matrix.nodev }}-${{ matrix.platform }}-x64 (18, win) (push) Has been cancelled
Package Node.js project into an executable / node18-${{ matrix.platform }}-arm64 (alpine) (push) Has been cancelled
Package Node.js project into an executable / node18-${{ matrix.platform }}-arm64 (linux) (push) Has been cancelled
Package Node.js project into an executable / node18-${{ matrix.platform }}-arm64 (linuxstatic) (push) Has been cancelled
2026-06-05 11:12:48 +08:00
shanmite 51ec0a191f feat: 获取视频动态的简介以参与转发抽奖 2026-06-05 11:12:28 +08:00
shanmite 9bb9268b96 docs: 更新CHANGELOG
Build and push Docker images / docker (push) Has been cancelled
Mirror and run GitLab CI / build (push) Has been cancelled
Package Node.js project into an executable / node${{ matrix.nodev }}-${{ matrix.platform }}-x64 (18, linux) (push) Has been cancelled
Package Node.js project into an executable / node${{ matrix.nodev }}-${{ matrix.platform }}-x64 (18, macos) (push) Has been cancelled
Package Node.js project into an executable / node${{ matrix.nodev }}-${{ matrix.platform }}-x64 (18, win) (push) Has been cancelled
Package Node.js project into an executable / node18-${{ matrix.platform }}-arm64 (alpine) (push) Has been cancelled
Package Node.js project into an executable / node18-${{ matrix.platform }}-arm64 (linux) (push) Has been cancelled
Package Node.js project into an executable / node18-${{ matrix.platform }}-arm64 (linuxstatic) (push) Has been cancelled
2026-06-01 14:36:48 +08:00
shanmite 2294ad9f3f fix: ai返回增加类型检查 2026-06-01 14:07:13 +08:00
shanmite fe0258a84a feat: ai过滤过期抽奖 2026-06-01 11:24:03 +08:00
shanmite a14af8e710 fix: ai模式带话题和错误at好友 2026-06-01 10:03:53 +08:00
10 changed files with 127 additions and 58 deletions
+13
View File
@@ -1,5 +1,18 @@
<!-- markdownlint-disable MD036 MD024-->
# CHANGELOG
## 主要变化(2.11.2)
* 51ec0a1 feat: 获取视频动态的简介以参与转发抽奖
_如果之前版本小于上一版本,请查看[CHANGELOG](https://github.com/shanmiteko/LotteryAutoScript/blob/main/CHANGELOG.md)变更说明_
## 主要变化(2.11.1)
* 2294ad9 fix: ai返回增加类型检查
* fe0258a feat: ai过滤过期抽奖
* a14af8e fix: ai模式带话题和错误at好友
* e0c18b0 chore: 更新action
_如果之前版本小于上一版本,请查看[CHANGELOG](https://github.com/shanmiteko/LotteryAutoScript/blob/main/CHANGELOG.md)变更说明_
## 主要变化(2.11.0)
* 1c36941 fix: origin is null
* 2f4734c chore: 不再推送至npm
+1 -1
View File
@@ -10,7 +10,7 @@ module.exports = Object.freeze({
* ## 高级功能
* - `ENABLE_CHAT_CAPTCHA_OCR` 开启评论验证码识别 使用方法见README
* - `CHAT_CAPTCHA_OCR_URL` 验证码识别接口 POST `url`->`code`
* - `ENABLE_AI_JUDGE` 是否启用AI判断抽奖
* - `ENABLE_AI_JUDGE` 是否启用AI判断抽奖过滤过期抽奖
* - `ENABLE_AI_COMMENTS` 是否启用AI评论
*
* ## 调试相关
+38 -9
View File
@@ -127,6 +127,13 @@ class Monitor extends Searcher {
continue;
}
if (hasEnv('ENABLE_AI_JUDGE') && lottery.drawtime !== -1 && lottery.drawtime < Date.now() / 1000) {
log.info('AI过滤', '已过开奖时间');
d_storage.updateDyid(lottery.dyid);
await delay(filter_wait);
continue;
}
if (lottery.isOfficialLottery) {
let { ts } = await bili.getLotteryNotice(lottery.dyid);
const ts_10 = Date.now() / 1000;
@@ -250,6 +257,7 @@ class Monitor extends Searcher {
* @property {number[]} uid 用户标识
* @property {string} dyid 动态标识
* @property {boolean} isOfficialLottery 是否官方抽奖
* @property {number} drawtime 开奖时间t10
* @property {string} relay_chat 转发词
* @property {string} ctrl 定位@
* @property {string} [rid] 评论标识
@@ -282,7 +290,8 @@ class Monitor extends Searcher {
reserve_lottery_wait, sneaktower, key_words,
model, chatmodel, chat: chats, relay: relays,
block_dynamic_type, max_create_time, is_imitator,
only_followed, at_users, blockword, blacklist, ai_comments_parm
only_followed, at_users, blockword, blacklist, ai_comments_parm,
ai_judge_parm,
} = config,
now_ts = Date.now() / 1000;
@@ -405,6 +414,7 @@ class Monitor extends Searcher {
isSendChat =
(hasOfficialLottery && chatmodel[0] === '1')
|| (!hasOfficialLottery && chatmodel[1] === '1'),
drawtime = -1,
keys = [dyid, m_uid, ori_uid];
log.debug('筛选动态', { real_uid, mIsFollowed, oriIsFollowed, realIsFollowed, needAt, needTopic, type, isRelayDynamic, key_words, has_key_words, blockword, isBlock, isLottery, isSendChat });
@@ -455,20 +465,37 @@ class Monitor extends Searcher {
if (!hasOfficialLottery && model[1] === '1') {
if (hasEnv('ENABLE_AI_JUDGE')) {
let msg = await getAiContent(
config.ai_judge_parm.url,
config.ai_judge_parm.body,
config.ai_judge_parm.prompt,
ai_judge_parm.url,
ai_judge_parm.body,
ai_judge_parm.prompt,
lottery_info.des
);
try {
let msg_json = JSON.parse(msg);
has_key_words = msg_json.has_key_words;
needTopic = msg_json.needTopic;
needAt = msg_json.needAt;
isLottery = has_key_words;
if (typeof msg_json.has_key_words == 'boolean') {
has_key_words = msg_json.has_key_words;
isLottery = has_key_words;
} else {
log.warn('ai判断抽奖', 'no has_key_words');
}
if (typeof msg_json.needAt == 'boolean') {
needAt = msg_json.needAt;
} else {
log.warn('ai判断抽奖', 'no needAt');
}
if (typeof msg_json.needTopic == 'string') {
needTopic = msg_json.needTopic;
} else {
log.warn('ai判断抽奖', 'no needTopic');
}
if (typeof msg_json.drawtime == 'number') {
drawtime = msg_json.drawtime;
} else {
log.warn('ai判断抽奖', 'no drawtime');
}
log.info('ai判断抽奖', msg_json.more);
} catch (_) {
log.error('ai判断抽奖', '未返回JSON格式');
log.error('ai判断抽奖', `未返回JSON格式${msg}`);
}
}
if (!has_key_words && description) {
@@ -489,6 +516,8 @@ class Monitor extends Searcher {
onelotteryinfo.isOfficialLottery = hasOfficialLottery;
onelotteryinfo.drawtime = drawtime;
/**初始化待关注列表 */
onelotteryinfo.uid = [];
+20 -36
View File
@@ -103,43 +103,27 @@ function parseDynamicCard(data) {
/* 是否有官方抽奖 */
obj.hasOfficialLottery = false;
/* 转发描述 */
obj.description = '';
obj.description = ditem?.modules?.module_dynamic?.major?.archive?.desc || '';
let _total_len = 0;
if (Array.isArray(ditem?.modules?.module_dynamic?.desc?.rich_text_nodes)) {
ditem?.modules?.module_dynamic?.desc?.rich_text_nodes.forEach(node => {
if (node.type === 'RICH_TEXT_NODE_TYPE_AT') {
obj.ctrl.push({
data: node.rid,
location: _total_len,
length: node.text.length,
type: 1
});
}
/* 是否有官方抽奖 */
if (node.type === 'RICH_TEXT_NODE_TYPE_LOTTERY') {
obj.hasOfficialLottery = true;
}
obj.description += node.orig_text;
_total_len += node.text.length;
});
} else {
ditem?.modules?.module_dynamic?.major?.opus?.summary?.rich_text_nodes.forEach(node => {
if (node.type === 'RICH_TEXT_NODE_TYPE_AT') {
obj.ctrl.push({
data: node.rid,
location: _total_len,
length: node.text.length,
type: 1
});
}
/* 是否有官方抽奖 */
if (node.type === 'RICH_TEXT_NODE_TYPE_LOTTERY') {
obj.hasOfficialLottery = true;
}
obj.description += node.orig_text;
_total_len += node.text.length;
});
}
let rich_text_nodes = ditem?.modules?.module_dynamic?.desc?.rich_text_nodes
|| ditem?.modules?.module_dynamic?.major?.opus?.summary?.rich_text_nodes
|| [];
rich_text_nodes.forEach(node => {
if (node.type === 'RICH_TEXT_NODE_TYPE_AT') {
obj.ctrl.push({
data: node.rid,
location: _total_len,
length: node.text.length,
type: 1
});
}
/* 是否有官方抽奖 */
if (node.type === 'RICH_TEXT_NODE_TYPE_LOTTERY') {
obj.hasOfficialLottery = true;
}
obj.description += node.orig_text;
_total_len += node.text.length;
});
/* 预约抽奖信息 */
obj.reserve_id = ditem?.modules?.module_dynamic?.additional?.reserve?.rid || 0;
obj.reserve_lottery_text = ditem?.modules?.module_dynamic?.additional?.reserve?.title || '未获取到';
+1 -1
View File
@@ -550,7 +550,7 @@ const utils = {
},
success: res => {
const data = utils.strToJson(res.body);
resolve(data?.choices?.[0]?.message?.content || null);
resolve(utils.log.debug_return(content, data?.choices?.[0]?.message?.content) || null);
},
failure: () => {
resolve(null);
+1 -1
View File
@@ -515,7 +515,7 @@ module.exports = Object.freeze({
'model': 'Qwen/Qwen3-32B',
'enable_thinking': true,
},
prompt: '你是一个B站用户,需要判断动态内容是否是抽奖动态,以及参与条件,以json格式输出,仅需包含key:has_key_words(bool 是否是抽奖动态),needAt(bool 是否需要@),needTopic(bool 是否需要带话题),more(string 总结参与抽奖的条件).回答不要包含markdown标记文本,输出纯json文本'
prompt: '你是一个B站用户,需要判断动态内容是否是抽奖动态,以及参与条件,以json格式输出,仅需包含key:has_key_words(bool 是否是抽奖动态),needAt(bool 参与抽奖是否需要@自己的好友),needTopic(string 参与抽奖需要带话题,返回话题需要用#号括起来),drawtime(number 开奖时间的10位数时间戳未获取到返回-1),more(string 总结参与抽奖的条件).回答不要包含markdown标记文本,输出纯json文本'
},
ai_comments_parm: {
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "lottery-auto-script",
"version": "2.11.0",
"version": "2.11.2",
"description": "自动参与B站动态抽奖",
"main": "main.js",
"scripts": {
+6 -6
View File
@@ -1,13 +1,9 @@
#!/usr/bin/env bash
# version: <major.minor.patch>
level=minor
level=patch
npm version $level \
--no-commit-hooks \
--no-git-tag-version
OLD_VERSION_ARRAY=($(npm view lottery-auto-script version | tr '.' ' '))
OLD_VERSION_ARRAY=($(npm pkg get version | tr -d '"' | tr '.' ' '))
major=${OLD_VERSION_ARRAY[0]}
minor=${OLD_VERSION_ARRAY[1]}
patch=${OLD_VERSION_ARRAY[2]}
@@ -27,6 +23,10 @@ case "${level}" in
;;
esac
npm version $level \
--no-commit-hooks \
--no-git-tag-version
NEW_VERSION="$major.$minor.$patch"
echo "New Version: $NEW_VERSION"
+29 -2
View File
@@ -12,7 +12,7 @@ const config = require('../lib/data/config');
config.ai_judge_parm.prompt,
'#胜利女神新的希望# #nikke# \n【一周年评论盖楼挑战③】拿来吧妮……的表情包!\n\n指挥官的手机里,\n一定存着几张出场率超高的妮姬表情包吧?\n和妮姬们相遇的一周年已至,这些也成了旅途中的一段快乐印记~是时候公开自己的库存了yo!\n\n无论是新收新做的趣味表情,还是珍藏一年的经典老图——\n现在,让它们登场吧!\n\n评论区交出您的表情包库存,看看这一年谁的“收藏”最cool!!\n🎁我们将在6月9日于本条评论区随机抽选:\n▶1位指挥官赠送【周边大礼盒】× 1\n▶10位指挥官赠送【Q版印章小立牌】× 1\n\n💝盖楼目标达成奖励:\n5月20日~22日期间,参与【一周年评论盖楼挑战】系列话题活动! 当全平台评论数累计达成 【2026】 楼时,我们将从本平台参与系列话题活动的用户中额外抽取2位幸运指挥官,每人送出【哈曼卡顿音响】× 1!\n\n————————————\n✦《胜利女神:新的希望》一周年庆典版本「OLD TALES 尘封童话」现已上线!游戏多端互通,前往Bilibili游戏中心搜索《胜利女神:新的希望》即可下载。'
);
console.log(msg);
console.log(JSON.parse(msg));
msg = await utils.getAiContent(
config.ai_comments_parm.url,
config.ai_comments_parm.body,
@@ -20,7 +20,34 @@ const config = require('../lib/data/config');
'#胜利女神新的希望# #nikke# \n【一周年评论盖楼挑战③】拿来吧妮……的表情包!\n\n指挥官的手机里,\n一定存着几张出场率超高的妮姬表情包吧?\n和妮姬们相遇的一周年已至,这些也成了旅途中的一段快乐印记~是时候公开自己的库存了yo!\n\n无论是新收新做的趣味表情,还是珍藏一年的经典老图——\n现在,让它们登场吧!\n\n评论区交出您的表情包库存,看看这一年谁的“收藏”最cool!!\n🎁我们将在6月9日于本条评论区随机抽选:\n▶1位指挥官赠送【周边大礼盒】× 1\n▶10位指挥官赠送【Q版印章小立牌】× 1\n\n💝盖楼目标达成奖励:\n5月20日~22日期间,参与【一周年评论盖楼挑战】系列话题活动! 当全平台评论数累计达成 【2026】 楼时,我们将从本平台参与系列话题活动的用户中额外抽取2位幸运指挥官,每人送出【哈曼卡顿音响】× 1!\n\n————————————\n✦《胜利女神:新的希望》一周年庆典版本「OLD TALES 尘封童话」现已上线!游戏多端互通,前往Bilibili游戏中心搜索《胜利女神:新的希望》即可下载。'
);
console.log(msg);
msg = await utils.getAiContent(
config.ai_judge_parm.url,
config.ai_judge_parm.body,
config.ai_judge_parm.prompt,
'#全民掉线行动#今日启动!参与活动,领GT7、X1心动优惠 2022年助你去线去烦恼,乐享焕新声活!活动规则见下图。 #供电局福利社# #互动抽奖##抽奖# 【关注】@Haylou嘿喽 ,带话题#全民掉线行动#,【转发+评论+赞】本动态,小嘿将随机抽4个欧皇送出以下福利: 一等奖:Haylou X1 双降噪蓝牙耳机 1台 二等奖:Haylou GT7 真无线蓝牙耳机1台 三等奖:50元京东卡*2 并且小嘿特意又申请了意外惊喜,加码福利送上,大家冲鸭: 截至抽奖结束: 【转发超1w】,再抽一位小可爱送50元京东卡*1 【粉丝超1.5w】,再抽一位小可爱送Haylou T17运动蓝牙耳机*1台 开奖时间1月27日,中奖名单将通过第三方抽奖工具选出。冲冲冲! *一定要时刻关注@Haylou嘿喽 哦!开奖后的3天内,未回复小嘿私信领奖的粉丝按照自动弃奖处理哦! '
);
console.log(JSON.parse(msg));
msg = await utils.getAiContent(
config.ai_comments_parm.url,
config.ai_comments_parm.body,
config.ai_comments_parm.prompt,
'#全民掉线行动#今日启动!参与活动,领GT7、X1心动优惠 2022年助你去线去烦恼,乐享焕新声活!活动规则见下图。 #供电局福利社# #互动抽奖##抽奖# 【关注】@Haylou嘿喽 ,带话题#全民掉线行动#,【转发+评论+赞】本动态,小嘿将随机抽4个欧皇送出以下福利: 一等奖:Haylou X1 双降噪蓝牙耳机 1台 二等奖:Haylou GT7 真无线蓝牙耳机1台 三等奖:50元京东卡*2 并且小嘿特意又申请了意外惊喜,加码福利送上,大家冲鸭: 截至抽奖结束: 【转发超1w】,再抽一位小可爱送50元京东卡*1 【粉丝超1.5w】,再抽一位小可爱送Haylou T17运动蓝牙耳机*1台 开奖时间1月27日,中奖名单将通过第三方抽奖工具选出。冲冲冲! *一定要时刻关注@Haylou嘿喽 哦!开奖后的3天内,未回复小嘿私信领奖的粉丝按照自动弃奖处理哦! '
);
console.log(msg);
msg = await utils.getAiContent(
config.ai_judge_parm.url,
config.ai_judge_parm.body,
config.ai_judge_parm.prompt,
'#全民掉线行动#今日启动!参与活动,领GT7、X1心动优惠 2022年助你去线去烦恼,乐享焕新声活!活动规则见下图。 #供电局福利社# #互动抽奖##抽奖# 【关注】@Haylou嘿喽 ,带话题#全民掉线行动#,【转发+评论+赞】本动态,小嘿将随机抽4个欧皇送出以下福利: 一等奖:Haylou X1 双降噪蓝牙耳机 1台 二等奖:Haylou GT7 真无线蓝牙耳机1台 三等奖:50元京东卡*2 并且小嘿特意又申请了意外惊喜,加码福利送上,大家冲鸭: 截至抽奖结束: 【转发超1w】,再抽一位小可爱送50元京东卡*1 【粉丝超1.5w】,再抽一位小可爱送Haylou T17运动蓝牙耳机*1台,中奖名单将通过第三方抽奖工具选出。冲冲冲! *一定要时刻关注@Haylou嘿喽 哦!开奖后的3天内,未回复小嘿私信领奖的粉丝按照自动弃奖处理哦! '
);
console.log(JSON.parse(msg));
msg = await utils.getAiContent(
config.ai_comments_parm.url,
config.ai_comments_parm.body,
config.ai_comments_parm.prompt,
'#全民掉线行动#今日启动!参与活动,领GT7、X1心动优惠 2022年助你去线去烦恼,乐享焕新声活!活动规则见下图。 #供电局福利社# #互动抽奖##抽奖# 【关注】@Haylou嘿喽 ,带话题#全民掉线行动#,【转发+评论+赞】本动态,小嘿将随机抽4个欧皇送出以下福利: 一等奖:Haylou X1 双降噪蓝牙耳机 1台 二等奖:Haylou GT7 真无线蓝牙耳机1台 三等奖:50元京东卡*2 并且小嘿特意又申请了意外惊喜,加码福利送上,大家冲鸭: 截至抽奖结束: 【转发超1w】,再抽一位小可爱送50元京东卡*1 【粉丝超1.5w】,再抽一位小可爱送Haylou T17运动蓝牙耳机*1台 开奖时间1月27日,中奖名单将通过第三方抽奖工具选出。冲冲冲! *一定要时刻关注@Haylou嘿喽 哦!开奖后的3天内,未回复小嘿私信领奖的粉丝按照自动弃奖处理哦! '
);
console.log(msg);
},
]);
console.log('ai.test ... ok!');
+17 -1
View File
@@ -4,13 +4,29 @@ const searcher = require('../lib/core/searcher');
const util = require('./util');
(async () => {
await util.par_run([0], [
await util.par_run([0, 1, 2, 3], [
// 0
async () => {
let info = await bili_client.getOneDynamicByDyid('1206954551173709840');
let card = searcher.parseDynamicCard(info);
console.log(JSON.stringify(card, null, 4));
},
async () => {
let info = await bili_client.getOneDynamicByDyid('1207028214165143570');
let card = searcher.parseDynamicCard(info);
console.log(JSON.stringify(card, null, 4));
},
async () => {
let info = await bili_client.getOneDynamicByDyid('1209643548566093825');
let card = searcher.parseDynamicCard(info);
console.log(JSON.stringify(card, null, 4));
},
async () => {
let info = await bili_client.getOneDynamicByDyid('1210278611064455168');
let card = searcher.parseDynamicCard(info);
console.log(JSON.stringify(card, null, 4));
},
]);
console.log('dynamic_card.test ... ok!');