feat: 可在设置接入AI判断动态是否是抽奖动态

This commit is contained in:
shanmite 2026-05-28 11:18:25 +08:00
parent d3cc24c43b
commit 3af17e59ed
7 changed files with 92 additions and 21 deletions

View File

@ -198,6 +198,8 @@ buvid3亦可不填 使用随机生成值
关键词有限 可能会有**漏掉**的或**误报**
可在设置开启AI判断
### 中奖推送
> 填写在env.js内

View File

@ -10,6 +10,7 @@ module.exports = Object.freeze({
* ## 高级功能
* - `ENABLE_CHAT_CAPTCHA_OCR` 开启评论验证码识别 使用方法见README
* - `CHAT_CAPTCHA_OCR_URL` 验证码识别接口 POST `url`->`code`
* - `ENABLE_AI_JUDGE` 是否启用AI判断抽奖
* - `ENABLE_AI_COMMENTS` 是否启用AI评论
*
* ## 调试相关
@ -34,6 +35,7 @@ module.exports = Object.freeze({
ENABLE_CHAT_CAPTCHA_OCR: false,
CHAT_CAPTCHA_OCR_URL: 'http://127.0.0.1:9898/ocr/url/text',
ENABLE_AI_JUDGE: false,
ENABLE_AI_COMMENTS: false,
ENABLE_MULTIPLE_ACCOUNT: false,

View File

@ -384,7 +384,7 @@ class Monitor extends Searcher {
return false;
}
const
let
[m_uid, ori_uid] = uids,
mIsFollowed = !m_uid || (new RegExp(m_uid)).test(attentionList),
oriIsFollowed = !ori_uid || (new RegExp(ori_uid)).test(attentionList),
@ -452,8 +452,28 @@ class Monitor extends Searcher {
}
}
if (!hasOfficialLottery && model[1] === '1' && !has_key_words && description) {
log.warn('筛选动态', `无关键词动态的描述: ${description}\n\n考虑是否修改设置key_words:\n${key_words.join('\n且满足: ')}`);
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,
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;
log.info('ai判断抽奖', msg_json.more);
} catch (_) {
log.error('ai判断抽奖', '未返回JSON格式');
}
}
if (!has_key_words && description) {
log.warn('筛选动态', `无关键词动态的描述: ${description}\n\n考虑是否修改设置key_words或ai提示词`);
}
}
/**若勾选只转已关注 */
@ -717,4 +737,4 @@ class Monitor extends Searcher {
}
module.exports = { Monitor };
module.exports = { Monitor };

View File

@ -86,6 +86,12 @@ const config = {
'[转关评粉]|参与'
],
ai_judge_parm: {
url: '',
body: {},
prompt: ''
},
/**
* - '00' 关闭自动抽奖
* - '10' 只转发官方抽奖
@ -484,4 +490,4 @@ const config = {
};
module.exports = config;
module.exports = config;

View File

@ -514,7 +514,7 @@ const utils = {
});
},
/**
* 获取ai评论
* 获取ai
* @param {string} url
* @param {object} body
* @param {string} prompt
@ -530,10 +530,12 @@ const utils = {
'authorization': 'Bearer ' + process.env.AI_API_KEY,
'content-type': 'application/json'
},
config: {
timeout: 120000
},
contents: {
...body,
'stream': false,
'enable_thinking': true,
'response_format': { 'type': 'text' },
'messages': [
{

View File

@ -90,6 +90,19 @@ module.exports = Object.freeze({
'[转关评粉]|参与'
],
/**
* AI 判断抽奖
* https://learn.microsoft.com/en-us/azure/ai-foundry/openai/reference#chat-completions
*/
ai_judge_parm: {
/**
* /chat/completions
*/
url: '',
body: {},
prompt: ''
},
/**
* - '00' 关闭自动抽奖
* - '10' 只转发官方抽奖
@ -496,23 +509,22 @@ module.exports = Object.freeze({
APIs: [],
/**
* 默认为硅基流动可以修改为其他AI服务
*/
ai_comments_parm: {
url: 'https://api.siliconflow.cn/v1/chat/completions',
ai_judge_parm: {
url: 'https://api.deepseek.com/chat/completions',
body: {
'model': 'Qwen/Qwen3-32B',
'max_tokens': 512,
'thinking_budget': 4096,
'min_p': 0.05,
'temperature': 0.7,
'top_p': 0.7,
'top_k': 50,
'frequency_penalty': 0.5,
'n': 1,
'enable_thinking': true,
},
prompt: '请根据以下内容直接生成一条简短评论,无需说明信息,且不包含任何敏感词汇。'
prompt: '你是一个B站用户需要判断动态内容是否是抽奖动态以及参与条件以json格式输出仅需包含key:has_key_words(bool 是否是抽奖动态),needAt(bool 是否需要@),needTopic(bool 是否需要带话题),more(string 总结参与抽奖的条件).回答不要包含markdown标记文本,输出纯json文本'
},
ai_comments_parm: {
url: 'https://api.deepseek.com/chat/completions',
body: {
'model': 'Qwen/Qwen3-32B',
'enable_thinking': true,
},
prompt: '你是一个B站用户请根据以下内容直接生成一条模拟真实用户的评论不要使用表情无需说明信息且不包含任何敏感词汇。'
},
save_lottery_info_to_file: true,

27
test/ai.test.js Normal file
View File

@ -0,0 +1,27 @@
const util = require('./util');
const utils = require('../lib/utils.js');
const config = require('../lib/data/config');
(async () => {
await util.par_run([], [
// 0
async () => {
let msg = await utils.getAiContent(
config.ai_judge_parm.url,
config.ai_judge_parm.body,
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);
msg = await utils.getAiContent(
config.ai_comments_parm.url,
config.ai_comments_parm.body,
config.ai_comments_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('ai.test ... ok!');
})();