mirror of
https://github.com/shanmiteko/LotteryAutoScript.git
synced 2026-07-22 21:13:47 +08:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
078cfcf821 |
@@ -1,18 +0,0 @@
|
||||
name: "Publishing to NPM"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- "package.json"
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
publish:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- uses: JS-DevTools/npm-publish@v1
|
||||
with:
|
||||
token: ${{ secrets.NPM_TOKEN }}
|
||||
@@ -29,21 +29,11 @@ jobs:
|
||||
run: |
|
||||
npm install
|
||||
npm run pkg_x64
|
||||
- name: "Upload to artifact(win)"
|
||||
- name: "Upload to artifact"
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: nlts-win-x64
|
||||
path: dist/nlts-win-x64/
|
||||
- name: "Upload to artifact(linux)"
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: nlts-linux-x64
|
||||
path: dist/nlts-linux-x64/
|
||||
- name: "Upload to artifact(macos)"
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: nlts-macos-x64
|
||||
path: dist/nlts-macos-x64/
|
||||
name: dist_x64
|
||||
path: dist/
|
||||
pkg_arm64:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
|
||||
@@ -17,8 +17,7 @@
|
||||
[Github仓库链接](https://github.com/shanmiteko/LotteryAutoScript)
|
||||
|
||||
[](https://github.com/shanmiteko/LotteryAutoScript/actions/workflows/pkg.yml)<br>
|
||||
[](https://github.com/shanmiteko/LotteryAutoScript/actions/workflows/docker.yml)<br>
|
||||
[](https://github.com/shanmiteko/LotteryAutoScript/actions/workflows/npmp.yml)
|
||||
[](https://github.com/shanmiteko/LotteryAutoScript/actions/workflows/docker.yml)
|
||||
|
||||
已实现功能:
|
||||
- 监控用户转发
|
||||
@@ -87,6 +86,8 @@ Chrome浏览器:
|
||||
~/nlts-linux-x64
|
||||
=> tree
|
||||
.
|
||||
├── dyids (自动生成的dyid存储)
|
||||
│ └── dyid.txt
|
||||
├── env.js (便捷设置环境变量和多账号参数)
|
||||
├── lottery (可执行文件)
|
||||
├── my_config.js (自定义设置文件) (!使用前必读)
|
||||
@@ -213,12 +214,7 @@ rm -rf lottery/
|
||||
----------------------------------------
|
||||
|
||||
## 防重复转发
|
||||
~~存储在专栏草稿~~
|
||||
|
||||
~~脚本将转发过的动态和被过滤的动态都写入`dyids/dyid*.txt`文件中~~
|
||||
|
||||
是否点赞
|
||||
|
||||
脚本将转发过的动态和被过滤的动态都写入`dyids/dyid*.txt`文件中
|
||||
|
||||
----------------------------------------
|
||||
|
||||
|
||||
+82
-63
@@ -1,70 +1,89 @@
|
||||
module.exports = Object.freeze({
|
||||
/**
|
||||
* ## 账号相关
|
||||
* - `COOKIE` 是必填项
|
||||
* - `NUMBER` 表示是第几个账号
|
||||
* - `CLEAR` 是否启用清理功能
|
||||
* - `ENABLE_MULTIPLE_ACCOUNT` 是否启用多账号
|
||||
* - `MULTIPLE_ACCOUNT_PARM` 多账号参数(JSON格式)
|
||||
* ## 调试相关
|
||||
* - `LOTTERY_LOG_LEVEL` 输出日志等级 Error<Warn<Info<Debug 1<2<3<4
|
||||
* - `NOT_GO_LOTTERY` 关闭抽奖行为
|
||||
* ## 多账号
|
||||
* 1. 将 ENABLE_MULTIPLE_ACCOUNT 的值改为true
|
||||
* 2. 将账号信息依次填写于 multiple_account_parm 中, 参考例子类推
|
||||
* - `WAIT` 表示下一个账号运行等待时间(毫秒)
|
||||
*
|
||||
* **按顺序依次执行, 防止访问频繁封禁IP**
|
||||
*/
|
||||
account_parm: {
|
||||
/**
|
||||
* ## 账号相关
|
||||
* - `COOKIE` 是必填项
|
||||
* - `NUMBER` 表示是第几个账号
|
||||
* - `CLEAR` 是否启用清理功能
|
||||
* - `ENABLE_MULTIPLE_ACCOUNT` 是否启用多账号
|
||||
* - `MULTIPLE_ACCOUNT_PARM` 多账号参数(JSON格式)
|
||||
* ## 调试相关
|
||||
* - `LOTTERY_LOG_LEVEL` 输出日志等级 Error<Warn<Info<Debug 1<2<3<4
|
||||
* - `NOT_GO_LOTTERY` 关闭抽奖行为
|
||||
* ## 多账号
|
||||
* 1. 将 ENABLE_MULTIPLE_ACCOUNT 的值改为true
|
||||
* 2. 将账号信息依次填写于 multiple_account_parm 中, 参考例子类推
|
||||
* - `WAIT` 表示下一个账号运行等待时间(毫秒)
|
||||
*
|
||||
* **按顺序依次执行, 防止访问频繁封禁IP**
|
||||
*/
|
||||
const account_parm = {
|
||||
COOKIE: "",
|
||||
NUMBER: 1,
|
||||
CLEAR: true,
|
||||
ENABLE_MULTIPLE_ACCOUNT: false,
|
||||
MULTIPLE_ACCOUNT_PARM: "",
|
||||
LOTTERY_LOG_LEVEL: 3,
|
||||
NOT_GO_LOTTERY: ""
|
||||
}
|
||||
|
||||
/**
|
||||
* 为防止环境变量过长, 请将多账号填在此处
|
||||
* @example
|
||||
* ```js
|
||||
* {
|
||||
* COOKIE: "",
|
||||
* NUMBER: 2,
|
||||
* CLEAR: true,
|
||||
* WAIT: 60 * 1000,
|
||||
* },
|
||||
* ```
|
||||
* 请按照以上格式将参数依次填写在下方
|
||||
*/
|
||||
const multiple_account_parm = [
|
||||
{
|
||||
COOKIE: "",
|
||||
NUMBER: 1,
|
||||
CLEAR: true,
|
||||
|
||||
ENABLE_MULTIPLE_ACCOUNT: false,
|
||||
|
||||
MULTIPLE_ACCOUNT_PARM: "",
|
||||
LOTTERY_LOG_LEVEL: 3,
|
||||
NOT_GO_LOTTERY: ""
|
||||
WAIT: 60 * 1000,
|
||||
},
|
||||
]
|
||||
|
||||
/**
|
||||
* 为防止环境变量过长, 请将多账号填在此处
|
||||
* 以大括号内容为模板依次复制(包含大括号),逗号分割
|
||||
*/
|
||||
multiple_account_parm: [
|
||||
{
|
||||
COOKIE: "",
|
||||
NUMBER: 1,
|
||||
CLEAR: true,
|
||||
WAIT: 60 * 1000
|
||||
}
|
||||
],
|
||||
/**
|
||||
* 推送相关参数
|
||||
*/
|
||||
const push_parm = {
|
||||
SCKEY: "",
|
||||
SENDKEY: "",
|
||||
QQ_SKEY: "",
|
||||
QQ_MODE: "",
|
||||
BARK_PUSH: "",
|
||||
BARK_SOUND: "",
|
||||
TG_BOT_TOKEN: "",
|
||||
TG_USER_ID: "",
|
||||
TG_PROXY_HOST: "",
|
||||
TG_PROXY_PORT: "",
|
||||
DD_BOT_TOKEN: "",
|
||||
DD_BOT_SECRET: "",
|
||||
QYWX_KEY: "",
|
||||
IGOT_PUSH_KEY: "",
|
||||
PUSH_PLUS_TOKEN: "",
|
||||
PUSH_PLUS_USER: "",
|
||||
SMTP_HOST: "",
|
||||
SMTP_PORT: "",
|
||||
SMTP_USER: "",
|
||||
SMTP_PASS: "",
|
||||
SMTP_TO_USER: ""
|
||||
}
|
||||
|
||||
/**
|
||||
* 推送相关参数
|
||||
*/
|
||||
push_parm: {
|
||||
SCKEY: "",
|
||||
SENDKEY: "",
|
||||
QQ_SKEY: "",
|
||||
QQ_MODE: "",
|
||||
BARK_PUSH: "",
|
||||
BARK_SOUND: "",
|
||||
TG_BOT_TOKEN: "",
|
||||
TG_USER_ID: "",
|
||||
TG_PROXY_HOST: "",
|
||||
TG_PROXY_PORT: "",
|
||||
DD_BOT_TOKEN: "",
|
||||
DD_BOT_SECRET: "",
|
||||
QYWX_KEY: "",
|
||||
IGOT_PUSH_KEY: "",
|
||||
PUSH_PLUS_TOKEN: "",
|
||||
PUSH_PLUS_USER: "",
|
||||
SMTP_HOST: "",
|
||||
SMTP_PORT: "",
|
||||
SMTP_USER: "",
|
||||
SMTP_PASS: "",
|
||||
SMTP_TO_USER: ""
|
||||
/**
|
||||
* 初始化环境变量
|
||||
*/
|
||||
function initEnv() {
|
||||
process.env = {
|
||||
...process.env,
|
||||
...account_parm,
|
||||
...push_parm
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
module.exports = { initEnv, multiple_account_parm };
|
||||
+20
-21
@@ -2,10 +2,10 @@ const utils = require('../utils');
|
||||
const bili = require('../net/bili');
|
||||
const { sendNotify } = require('../helper/notify');
|
||||
const event_bus = require('../helper/event_bus');
|
||||
const { randomDynamic } = require('../helper/randomDynamic')
|
||||
const { Searcher } = require('./searcher');
|
||||
const global_var = require("../data/global_var");
|
||||
const config = require("../data/config");
|
||||
const d_storage = require('../helper/d_storage');
|
||||
const { log, hasEnv } = utils;
|
||||
|
||||
/**
|
||||
@@ -82,16 +82,14 @@ class Monitor extends Searcher {
|
||||
*/
|
||||
async startLottery() {
|
||||
const allLottery = await this.filterLotteryInfo()
|
||||
, len = allLottery.length
|
||||
, { dy_contents, create_dy, create_dy_mode, wait } = config;
|
||||
, len = allLottery.length;
|
||||
|
||||
log.info('筛选动态', `筛选完毕(${len})`);
|
||||
|
||||
if (len) {
|
||||
let is_exception = false;
|
||||
for (const [index, Lottery] of utils.shuffle(allLottery).entries()) {
|
||||
for (const Lottery of utils.shuffle(allLottery)) {
|
||||
let status = 0;
|
||||
|
||||
if (Lottery.isOfficialLottery) {
|
||||
let { ts } = await bili.getLotteryNotice(Lottery.dyid);
|
||||
const ts_10 = Date.now() / 1000;
|
||||
@@ -100,10 +98,12 @@ class Monitor extends Searcher {
|
||||
}
|
||||
if (ts < ts_10) {
|
||||
log.info('过滤', '已过开奖时间')
|
||||
d_storage.updateDyid(Lottery.dyid)
|
||||
continue
|
||||
}
|
||||
if (ts > ts_10 + config.maxday * 86400) {
|
||||
log.info('过滤', '超过指定开奖时间')
|
||||
d_storage.updateDyid(Lottery.dyid)
|
||||
continue
|
||||
}
|
||||
} else if (Lottery.uid[0]) {
|
||||
@@ -113,19 +113,10 @@ class Monitor extends Searcher {
|
||||
}
|
||||
if (followerNum < config.minfollower) {
|
||||
log.info('过滤', `粉丝数(${followerNum})小于指定数量`)
|
||||
d_storage.updateDyid(Lottery.dyid)
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
if (create_dy
|
||||
&& create_dy_mode instanceof Array
|
||||
&& index > 0
|
||||
&& index % utils.getRandomOne(create_dy_mode[0]) === 0
|
||||
) {
|
||||
const number = utils.getRandomOne(create_dy_mode[1]) || 0;
|
||||
randomDynamic(number)
|
||||
}
|
||||
|
||||
status = await this.go(Lottery)
|
||||
switch (status) {
|
||||
case 0:
|
||||
@@ -136,8 +127,8 @@ class Monitor extends Searcher {
|
||||
default:
|
||||
return status
|
||||
}
|
||||
|
||||
await utils.delay(wait * (Math.random() + 0.5));
|
||||
d_storage.updateDyid(Lottery.dyid)
|
||||
await utils.delay(config.wait * (Math.random() + 0.5));
|
||||
}
|
||||
log.info('抽奖', '开始转发下一组动态');
|
||||
if (is_exception) {
|
||||
@@ -179,7 +170,6 @@ class Monitor extends Searcher {
|
||||
/** 所有抽奖信息 */
|
||||
let alllotteryinfo = [];
|
||||
const { key_words, model, chatmodel, is_imitator, only_followed, at_users, blockword, blacklist } = config;
|
||||
|
||||
/**Map<String, Boolean> */
|
||||
let dyids_map = new Map();
|
||||
|
||||
@@ -192,15 +182,24 @@ class Monitor extends Searcher {
|
||||
return true
|
||||
});
|
||||
|
||||
/**并发查询dyid */
|
||||
await Promise.all(
|
||||
[...dyids_map.keys()]
|
||||
.map(it => d_storage
|
||||
.searchDyid(it)
|
||||
.then(hasIt => dyids_map.set(it, hasIt))
|
||||
)
|
||||
)
|
||||
|
||||
/* 检查动态是否满足要求 */
|
||||
await utils.try_for_each(protoLotteryInfo, async function ({
|
||||
lottery_info_type, is_liked,
|
||||
uids, uname, dyid,
|
||||
lottery_info_type, uids,
|
||||
uname, dyid,
|
||||
ctrl, rid, des, type,
|
||||
hasOfficialLottery
|
||||
}) {
|
||||
/* 遇到转发过就退出 */
|
||||
if (is_liked) return false;
|
||||
if (dyids_map.get(dyid)) return false;
|
||||
|
||||
const
|
||||
/**判断是转发源动态还是现动态 */
|
||||
|
||||
+42
-73
@@ -1,6 +1,7 @@
|
||||
const utils = require('../utils');
|
||||
const bili = require('../net/bili');
|
||||
const config = require("../data/config");
|
||||
const d_storage = require('../helper/d_storage');
|
||||
|
||||
const { log } = utils
|
||||
|
||||
@@ -10,7 +11,6 @@ const { log } = utils
|
||||
* @typedef {object} UsefulDynamicInfo
|
||||
* @property {number} uid
|
||||
* @property {string} uname
|
||||
* @property {boolean} is_liked
|
||||
* @property {number} createtime 10
|
||||
* @property {string} rid_str
|
||||
* @property {string} dynamic_id
|
||||
@@ -35,16 +35,13 @@ function parseDynamicCard(dynamic_detail_card) {
|
||||
/**临时储存单个动态中的信息 */
|
||||
let obj = {};
|
||||
const { desc, card, extension, extend_json } = dynamic_detail_card
|
||||
, { is_liked, user_profile } = desc
|
||||
, { info } = user_profile
|
||||
, { info } = desc.user_profile
|
||||
, cardToJson = strToJson(card)
|
||||
, { item } = cardToJson;
|
||||
/* 转发者的UID */
|
||||
obj.uid = info.uid
|
||||
obj.uid = info.uid;
|
||||
/* 转发者的name */
|
||||
obj.uname = info.uname
|
||||
/* 动态是否点过赞 */
|
||||
obj.is_liked = is_liked > 0
|
||||
obj.uname = info.uname;
|
||||
/* 动态的ts10 */
|
||||
obj.createtime = desc.timestamp
|
||||
/* 动态类型 */
|
||||
@@ -135,7 +132,6 @@ class Searcher {
|
||||
* 整理后的抽奖信息
|
||||
* @typedef {object} LotteryInfo
|
||||
* @property {string} lottery_info_type
|
||||
* @property {boolean} is_liked
|
||||
* @property {number[]} uids `[uid,ouid]`
|
||||
* @property {string} uname
|
||||
* @property {Array<{}>} ctrl
|
||||
@@ -217,50 +213,21 @@ class Searcher {
|
||||
log.info('获取动态', `开始获取用户${UID}的动态信息`);
|
||||
const { allModifyDynamicResArray } = await Searcher.checkAllDynamic(UID, config.uid_scan_page, config.search_wait);
|
||||
|
||||
let { length } = allModifyDynamicResArray
|
||||
|
||||
if (!length) return null;
|
||||
|
||||
const fomatdata = await allModifyDynamicResArray
|
||||
.filter(d => {
|
||||
if (d.type === 1) {
|
||||
return true
|
||||
} else {
|
||||
length--
|
||||
return false
|
||||
}
|
||||
})
|
||||
.reduce(async (pre, cur) => {
|
||||
const results = await pre
|
||||
, { origin_dynamic_id } = cur;
|
||||
|
||||
log.info('获取动态', `查看源动态(${origin_dynamic_id})的细节 (${length--})`)
|
||||
|
||||
const card = await bili.getOneDynamicByDyid(origin_dynamic_id)
|
||||
|
||||
if (card) {
|
||||
await utils.delay(2000)
|
||||
|
||||
const { is_liked } = parseDynamicCard(card)
|
||||
|
||||
return [...results, {
|
||||
lottery_info_type: 'uid',
|
||||
is_liked,
|
||||
uids: [cur.uid, cur.origin_uid],
|
||||
uname: cur.origin_uname,
|
||||
ctrl: [],
|
||||
dyid: cur.origin_dynamic_id,
|
||||
rid: cur.origin_rid_str,
|
||||
des: cur.origin_description,
|
||||
type: cur.orig_type,
|
||||
hasOfficialLottery: cur.origin_hasOfficialLottery
|
||||
}]
|
||||
}
|
||||
|
||||
return results
|
||||
|
||||
}, Promise.resolve([]))
|
||||
if (!allModifyDynamicResArray.length) return null;
|
||||
|
||||
const fomatdata = allModifyDynamicResArray.map(o => {
|
||||
return {
|
||||
lottery_info_type: 'uid',
|
||||
uids: [o.uid, o.origin_uid],
|
||||
uname: o.origin_uname,
|
||||
ctrl: [],
|
||||
dyid: o.origin_dynamic_id,
|
||||
rid: o.origin_rid_str,
|
||||
des: o.origin_description,
|
||||
type: o.orig_type,
|
||||
hasOfficialLottery: o.origin_hasOfficialLottery
|
||||
}
|
||||
}).filter(a => a.type != 0)
|
||||
log.info('获取动态', `成功获取用户${UID}的动态信息`);
|
||||
|
||||
return fomatdata;
|
||||
@@ -304,7 +271,6 @@ class Searcher {
|
||||
const fomatdata = mDRdata.map(o => {
|
||||
return {
|
||||
lottery_info_type: 'tag',
|
||||
is_liked: o.is_liked,
|
||||
uids: [o.uid, o.origin_uid],
|
||||
uname: o.uname,
|
||||
ctrl: o.ctrl,
|
||||
@@ -345,32 +311,36 @@ class Searcher {
|
||||
/**单个专栏中的dyid */
|
||||
_dyinfos = [];
|
||||
log.info('获取动态', `提取专栏(${cv})中提及的dyid(${length})`)
|
||||
|
||||
/**遍历某专栏中的dyids */
|
||||
for (const dyid of dyids_set) {
|
||||
const isRelayed = await d_storage.searchDyid(dyid);
|
||||
if (isRelayed) {
|
||||
_weight += 1;
|
||||
}
|
||||
if (_weight >= weight) {
|
||||
log.warn('获取动态', `1/2动态曾经转过,该专栏或已查看,故中止`)
|
||||
_dyinfos = []
|
||||
break
|
||||
}
|
||||
if (dyid.length === utils.dyid_length) {
|
||||
log.info('获取动态', `查看专栏中所提及动态(${dyid})的细节 (${length--})`)
|
||||
if (!isRelayed) {
|
||||
log.info('获取动态', `查看动态(${dyid})的细节 (${length--})`)
|
||||
const res = await bili.getOneDynamicByDyid(dyid)
|
||||
, { code, data } = utils.strToJson(res)
|
||||
, { card } = data || {};
|
||||
|
||||
const card = await bili.getOneDynamicByDyid(dyid)
|
||||
|
||||
if (card) {
|
||||
await utils.delay(2000)
|
||||
|
||||
const parsed_card = parseDynamicCard(card)
|
||||
, { is_liked } = parsed_card;
|
||||
|
||||
if (is_liked) {
|
||||
log.info('获取动态', `动态(${dyid})已转发过`)
|
||||
_weight += 1;
|
||||
}
|
||||
|
||||
if (_weight >= weight && !config.not_check_article) {
|
||||
log.warn('获取动态', `1/2动态曾经转过,该专栏或已查看,故中止`)
|
||||
_dyinfos = []
|
||||
if (code !== 0) {
|
||||
log.error('获取动态', '获取动态数据出错,可能是访问太频繁 \n' + res)
|
||||
break
|
||||
}
|
||||
|
||||
_dyinfos.push(parsed_card);
|
||||
await utils.delay(2000)
|
||||
|
||||
if (card) {
|
||||
_dyinfos.push(parseDynamicCard(card));
|
||||
}
|
||||
} else {
|
||||
log.info('获取动态', `动态(${dyid})已转发过 (${length--})`)
|
||||
}
|
||||
} else {
|
||||
log.warn('获取动态', `动态(${dyid})无效 (${length--})`)
|
||||
@@ -381,7 +351,6 @@ class Searcher {
|
||||
const fomatdata = dyinfos.map(o => {
|
||||
return {
|
||||
lottery_info_type: 'article',
|
||||
is_liked: o.is_liked,
|
||||
uids: [o.uid, o.origin_uid],
|
||||
uname: o.uname,
|
||||
ctrl: o.ctrl,
|
||||
@@ -399,4 +368,4 @@ class Searcher {
|
||||
}
|
||||
|
||||
|
||||
module.exports = { Searcher };
|
||||
module.exports = { Searcher };
|
||||
+6
-15
@@ -1,28 +1,19 @@
|
||||
const { config_file } = require('../utils');
|
||||
const my_config = require(config_file);
|
||||
|
||||
const config = {
|
||||
/**
|
||||
* 原始设置
|
||||
* @returns {Object}
|
||||
*/
|
||||
raw_config() {
|
||||
delete require.cache[config_file];
|
||||
return require(config_file)
|
||||
},
|
||||
...my_config["default_config"],
|
||||
/**
|
||||
* @param {string} n
|
||||
*/
|
||||
updata(n) {
|
||||
const new_config = this.raw_config()[`config_${n}`];
|
||||
const new_config = my_config[`config_${n}`];
|
||||
if (new_config) {
|
||||
this.setObject(new_config)
|
||||
Object.entries(new_config)
|
||||
.forEach(([k, v]) => this[k] = v)
|
||||
}
|
||||
},
|
||||
init() {
|
||||
this.setObject(this.raw_config()["default_config"])
|
||||
},
|
||||
setObject(o) {
|
||||
Object.entries(o).forEach(([k, v]) => this[k] = v)
|
||||
init () {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
const { env_file } = require("../utils");
|
||||
|
||||
const env = {
|
||||
/**
|
||||
* 原始环境
|
||||
* @returns {Object}
|
||||
*/
|
||||
raw_env() {
|
||||
delete require.cache[env_file];
|
||||
return require(env_file)
|
||||
},
|
||||
init() {
|
||||
const raw_env = this.raw_env()
|
||||
this.setEnv({
|
||||
...raw_env["account_parm"],
|
||||
...raw_env["push_parm"]
|
||||
})
|
||||
},
|
||||
/**
|
||||
* @returns {Object[]}
|
||||
*/
|
||||
get_multiple_account() {
|
||||
return this.raw_env()["multiple_account_parm"]
|
||||
},
|
||||
setEnv(o) {
|
||||
process.env = {
|
||||
...process.env,
|
||||
...o
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
module.exports = env;
|
||||
@@ -37,6 +37,8 @@ let global_var = {
|
||||
]);
|
||||
this.set('remoteconfig', await getRemoteConfig());
|
||||
}
|
||||
await createDir('dyids');
|
||||
await createFile(n < 2 ? 'dyid.txt' : `dyid${n}.txt`, '', 'a')
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
const { log, readDyidFile, writeDyidFile, dyid_length } = require("../utils");
|
||||
|
||||
const d_storage = {
|
||||
/**
|
||||
* 搜索dyid
|
||||
* @param {string} dyid
|
||||
* @returns {Promise<boolean>}
|
||||
*/
|
||||
searchDyid: (dyid) => {
|
||||
return new Promise((resolve) => {
|
||||
const Rdyid = new RegExp(dyid);
|
||||
const rs = readDyidFile(Number(process.env.NUMBER));
|
||||
let status = false;
|
||||
rs.on('data', chunk => {
|
||||
if (Rdyid.test(chunk)) {
|
||||
status = true
|
||||
}
|
||||
})
|
||||
rs.on('end', () => {
|
||||
resolve(status)
|
||||
})
|
||||
rs.on('error', err => {
|
||||
log.error('搜索dyid', err)
|
||||
resolve(status)
|
||||
})
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 更新dyid
|
||||
* @param {string} dyid
|
||||
*/
|
||||
updateDyid: (dyid) => {
|
||||
log.info('更新dyid', `写入${dyid}`);
|
||||
if (dyid.length !== dyid_length) {
|
||||
log.error('更新dyid', `dyid(${dyid})长度不为18 若出现此问题请即时通知开发者`)
|
||||
}
|
||||
return new Promise((resolve) => {
|
||||
const ws = writeDyidFile(Number(process.env.NUMBER));
|
||||
ws.write(dyid + ',', () => {
|
||||
ws.destroy();
|
||||
resolve()
|
||||
})
|
||||
ws.on('error', err => {
|
||||
log.error('更新dyid', err)
|
||||
resolve()
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
module.exports = d_storage;
|
||||
@@ -1,39 +0,0 @@
|
||||
const config = require("../data/config");
|
||||
const bili = require("../net/bili");
|
||||
const utils = require("../utils");
|
||||
|
||||
/**
|
||||
* 随机动态
|
||||
* @param {number} num
|
||||
* @returns
|
||||
*/
|
||||
async function randomDynamic(num) {
|
||||
const { create_dy_type, dy_contents } = config;
|
||||
|
||||
if (create_dy_type === -1 || create_dy_type === 0 || typeof create_dy_type === 'undefined') {
|
||||
for (let index = 0; index < num; index++) {
|
||||
await bili.createDynamic(utils.getRandomOne(dy_contents));
|
||||
await utils.delay(2000);
|
||||
}
|
||||
}
|
||||
|
||||
if (create_dy_type === -1 || create_dy_type === 1) {
|
||||
let videos = await bili.getTopRcmd()
|
||||
for (let index = 0; videos.length < num; index++) {
|
||||
videos.push(...await bili.getTopRcmd())
|
||||
}
|
||||
|
||||
await utils.try_for_each(videos, async ([uid, aid]) => {
|
||||
if (num--) {
|
||||
await bili.shareVideo(uid, aid)
|
||||
await utils.delay(2000)
|
||||
return false
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
module.exports = { randomDynamic }
|
||||
+6
-2
@@ -1,10 +1,10 @@
|
||||
const utils = require('./utils');
|
||||
const bili = require('./net/bili');
|
||||
const event_bus = require('./helper/event_bus');
|
||||
const global_var = require('./data/global_var');
|
||||
const { Searcher } = require('./core/searcher');
|
||||
const { Monitor } = require('./core/monitor');
|
||||
const config = require('./data/config');
|
||||
const { randomDynamic } = require('./helper/randomDynamic');
|
||||
const { log } = utils;
|
||||
|
||||
async function createRandomDynamic(num) {
|
||||
@@ -12,7 +12,10 @@ async function createRandomDynamic(num) {
|
||||
log.info('随机动态', `准备创建${num}条随机动态`);
|
||||
const Dynamic = await Searcher.checkAllDynamic(global_var.get("myUID"), 1);
|
||||
if ((Dynamic.allModifyDynamicResArray[0] || { type: 0 }).type === 1) {
|
||||
await randomDynamic(num)
|
||||
for (let index = 0; index < num; index++) {
|
||||
await bili.createDynamic(utils.getRandomOne(config.dy_contents));
|
||||
await utils.delay(2000);
|
||||
}
|
||||
} else {
|
||||
log.info('随机动态', '已有非抽奖动态故无需创建');
|
||||
}
|
||||
@@ -36,6 +39,7 @@ function start() {
|
||||
return;
|
||||
}
|
||||
if (times.value() === lotterys.length) {
|
||||
await createRandomDynamic(config.create_dy_num);
|
||||
log.info('抽奖', '所有动态转发完毕');
|
||||
times.clear();
|
||||
event_bus.emit('Turn_off_the_Monitor', '目前无抽奖信息,过一会儿再来看看吧')
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
module.exports = Object.freeze({
|
||||
DYNAMIC_LIKE_THUMB: 'https://api.vc.bilibili.com/dynamic_like/v1/dynamic_like/thumb',
|
||||
DYNAMIC_REPOST_REPOST: 'https://api.vc.bilibili.com/dynamic_repost/v1/dynamic_repost/repost',
|
||||
DYNAMIC_REPOST_SHARE: 'https://api.vc.bilibili.com/dynamic_repost/v1/dynamic_repost/share',
|
||||
DYNAMIC_SVR_CREATE_DRAW: 'https://api.vc.bilibili.com/dynamic_svr/v1/dynamic_svr/create_draw',
|
||||
DYNAMIC_SVR_CREATE: 'https://api.vc.bilibili.com/dynamic_svr/v1/dynamic_svr/create',
|
||||
DYNAMIC_SVR_GET_DYNAMIC_DETAIL: 'https://api.vc.bilibili.com/dynamic_svr/v1/dynamic_svr/get_dynamic_detail',
|
||||
@@ -26,7 +25,6 @@ module.exports = Object.freeze({
|
||||
SESSION_SVR_UPDATE_ACK: 'https://api.vc.bilibili.com/session_svr/v1/session_svr/update_ack',
|
||||
SPACE_MYINFO: 'https://api.bilibili.com/x/space/myinfo',
|
||||
TAG_INFO: 'https://api.bilibili.com/x/tag/info',
|
||||
TOP_RCMD: "https://api.bilibili.com/x/web-interface/index/top/rcmd",
|
||||
TOPIC_SVR_TOPIC_HISTORY: 'https://api.vc.bilibili.com/topic_svr/v1/topic_svr/topic_history',
|
||||
TOPIC_SVR_TOPIC_NEW: 'https://api.vc.bilibili.com/topic_svr/v1/topic_svr/topic_new',
|
||||
WEB_INTERFACE_CARD: 'https://api.bilibili.com/x/web-interface/card',
|
||||
|
||||
+1
-63
@@ -247,7 +247,7 @@ const bili_client = {
|
||||
/**
|
||||
* 获取一个动态的细节
|
||||
* @param {string} dynamic_id
|
||||
* @return {Promise<JSON>} 失败返回undefined
|
||||
* @return {Promise<string>}
|
||||
*/
|
||||
getOneDynamicByDyid(dynamic_id) {
|
||||
return get({
|
||||
@@ -255,21 +255,6 @@ const bili_client = {
|
||||
query: {
|
||||
dynamic_id
|
||||
}
|
||||
}).then(responseText => {
|
||||
const { code, data } = strToJson(responseText)
|
||||
, { card } = data || {};
|
||||
|
||||
if (code !== 0) {
|
||||
log.error('获取一个动态的细节', `获取动态(${dynamic_id})数据出错:\n${responseText}`)
|
||||
return
|
||||
}
|
||||
|
||||
if (!card) {
|
||||
log.warn('获取一个动态的细节', `动态(${dynamic_id})不存在`)
|
||||
return
|
||||
}
|
||||
|
||||
return card
|
||||
})
|
||||
},
|
||||
/**
|
||||
@@ -716,53 +701,6 @@ const bili_client = {
|
||||
}
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 获取推荐
|
||||
* @returns {Promise<Array<[number, number]>>}
|
||||
*/
|
||||
getTopRcmd() {
|
||||
return get(
|
||||
{
|
||||
url: API.TOP_RCMD,
|
||||
}
|
||||
).then(responseText => {
|
||||
const res = strToJson(responseText);
|
||||
if (res.code === 0) {
|
||||
log.info('获取推荐', `成功`);
|
||||
return res.data.item.map(it => {
|
||||
return [it.owner.mid, it.id]
|
||||
})
|
||||
} else {
|
||||
log.error('获取推荐', `获取推荐失败\n${responseText}`);
|
||||
return []
|
||||
}
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 分享视频
|
||||
* @param {number} uid
|
||||
* @param {number} aid
|
||||
*/
|
||||
shareVideo(uid, aid) {
|
||||
return post({
|
||||
url: API.DYNAMIC_REPOST_SHARE,
|
||||
contents: {
|
||||
platform: "pc",
|
||||
uid,
|
||||
type: 8,
|
||||
content: "分享视频",
|
||||
repost_code: 20000,
|
||||
rid: aid,
|
||||
csrf_token: GlobalVar.get("csrf")
|
||||
}
|
||||
}).then(responseText => {
|
||||
if (/^{"code":0/.test(responseText)) {
|
||||
log.info('转发视频', `成功转发视频(av${aid})`);
|
||||
} else {
|
||||
log.error('转发视频', `转发失败\n${responseText}`);
|
||||
}
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 移除动态
|
||||
* @param {string} dyid
|
||||
|
||||
@@ -13,6 +13,8 @@ const utils = {
|
||||
env_file: path.join(process.cwd(), "env.js"),
|
||||
/**配置文件 */
|
||||
config_file: path.join(process.cwd(), "my_config.js"),
|
||||
/**dyid存储文件 */
|
||||
dyids_dir: path.join(process.cwd(), "dyids"),
|
||||
/**dyid长度 */
|
||||
dyid_length: 18,
|
||||
/**
|
||||
@@ -292,6 +294,50 @@ const utils = {
|
||||
resolve()
|
||||
})
|
||||
});
|
||||
},
|
||||
/**
|
||||
* CreateFile
|
||||
* @param {string} filepath 相对于dyids的文件路径
|
||||
* @param {string} [defaultValue] 写入默认值
|
||||
* @param {string} flag
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
createFile(filepath, defaultValue, flag) {
|
||||
const fpath = path.join(utils.dyids_dir, filepath);
|
||||
const buffer = Buffer.from(defaultValue);
|
||||
return new Promise((resolve, rejects) => {
|
||||
fs.open(fpath, flag, (err, fd) => {
|
||||
if (err) {
|
||||
rejects(err)
|
||||
} else {
|
||||
fs.write(fd, buffer, 0, buffer.length, 0, err => {
|
||||
if (err) {
|
||||
rejects(err)
|
||||
} else {
|
||||
resolve();
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 读取dyid文件
|
||||
* @param {number} num
|
||||
* @returns {fs.ReadStream}
|
||||
*/
|
||||
readDyidFile(num) {
|
||||
const fpath = num < 2 ? path.join(utils.dyids_dir, 'dyid.txt') : path.join(utils.dyids_dir, `dyid${num}.txt`);
|
||||
return fs.createReadStream(fpath, { encoding: 'utf8', highWaterMark: (utils.dyid_length + 1) * 1000 })
|
||||
},
|
||||
/**
|
||||
* 追加dyid
|
||||
* @param {number} num
|
||||
* @returns {fs.WriteStream}
|
||||
*/
|
||||
writeDyidFile(num) {
|
||||
const fpath = num < 2 ? path.join(utils.dyids_dir, 'dyid.txt') : path.join(utils.dyids_dir, `dyid${num}.txt`);
|
||||
return fs.createWriteStream(fpath, { flags: 'a' })
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -95,21 +95,15 @@ async function main() {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化环境
|
||||
* @returns {boolean} 出错true
|
||||
*/
|
||||
function initEnv() {
|
||||
if (hasFileOrDir(env_file)) {
|
||||
const
|
||||
env = require("./lib/data/env"),
|
||||
multiple_account_parm = env.get_multiple_account();
|
||||
(async function () {
|
||||
log.proPrint(metainfo, '\n')
|
||||
|
||||
if (hasFileOrDir(env_file)) {
|
||||
const { initEnv, multiple_account_parm } = require(env_file);
|
||||
if (multiple_account_parm) {
|
||||
multiple_account = multiple_account_parm;
|
||||
}
|
||||
|
||||
env.init();
|
||||
initEnv();
|
||||
log.init();
|
||||
log.info('环境变量初始化', '成功加载env.js文件');
|
||||
} else if (hasEnv('COOKIE') || hasEnv('MULTIPLE_ACCOUNT_PARM')) {
|
||||
@@ -118,34 +112,17 @@ function initEnv() {
|
||||
} else {
|
||||
log.init();
|
||||
log.error('环境变量初始化', '未在当前目录下找到env.js文件或者在环境变量中设置所需参数');
|
||||
return true
|
||||
return
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化设置
|
||||
* @returns {boolean} 出错true
|
||||
*/
|
||||
function initConfig() {
|
||||
if (hasFileOrDir(config_file)) {
|
||||
const config = require("./lib/data/config");
|
||||
config.init();
|
||||
require("./lib/data/config");
|
||||
log.info('配置文件初始化', '成功加载my_config.js文件');
|
||||
} else {
|
||||
log.error('配置文件初始化', '未在当前目录下找到my_config.js文件');
|
||||
return true
|
||||
return
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
(async function () {
|
||||
log.proPrint(metainfo, '\n')
|
||||
|
||||
if (initEnv() || initConfig()) return;
|
||||
|
||||
/**OPTIONS */
|
||||
process.env.lottery_mode = process.argv[2]
|
||||
|
||||
@@ -158,7 +135,6 @@ function initConfig() {
|
||||
while (loop_wait) {
|
||||
log.info('程序休眠', `${loop_wait / 1000}秒后再次启动`)
|
||||
await delay(loop_wait)
|
||||
if (initEnv() || initConfig()) return;
|
||||
await main()
|
||||
}
|
||||
log.info('结束运行', '未在config.js中设置休眠时间')
|
||||
|
||||
+6
-23
@@ -1,4 +1,4 @@
|
||||
module.exports = Object.freeze({
|
||||
module.exports = {
|
||||
/**
|
||||
* 默认设置(公用)
|
||||
*/
|
||||
@@ -7,6 +7,7 @@ module.exports = Object.freeze({
|
||||
* 监视更转的用户uid
|
||||
*/
|
||||
UIDs: [
|
||||
31252386,
|
||||
689277291,
|
||||
241675899
|
||||
],
|
||||
@@ -73,12 +74,6 @@ module.exports = Object.freeze({
|
||||
*/
|
||||
article_scan_page: 3,
|
||||
|
||||
/**
|
||||
* - 不检查专栏是否看过,若选择检查可以提高检测效率
|
||||
* - 默认false(检查)
|
||||
*/
|
||||
not_check_article: false,
|
||||
|
||||
/**
|
||||
* - 开奖时间距离现在的最大天数
|
||||
* - 默认不限制
|
||||
@@ -123,21 +118,15 @@ module.exports = Object.freeze({
|
||||
create_dy: false,
|
||||
|
||||
/**
|
||||
* 随机动态类型
|
||||
* - 0 自定义文字与图片
|
||||
* - 1 推荐视频
|
||||
* - -1 混合
|
||||
*/
|
||||
create_dy_type: 0,
|
||||
|
||||
/**
|
||||
* - 结束运行时发送随机动态的数量
|
||||
* - 发送随机动态的数量
|
||||
*/
|
||||
create_dy_num: 1,
|
||||
|
||||
/**
|
||||
* - 随机动态内容
|
||||
* - 类型 `content[]`
|
||||
*/
|
||||
/**
|
||||
* @typedef Picture
|
||||
* @property {string} img_src 站内源
|
||||
* @property {number} img_width
|
||||
@@ -146,12 +135,6 @@ module.exports = Object.freeze({
|
||||
*/
|
||||
dy_contents: ['[doge]', '[doge][doge]'],
|
||||
|
||||
/**
|
||||
* - 每转发x条抽奖动态就发送x条随机动态
|
||||
* - @example [[10,11,9],[6,8,9]] 每转发9,10,11条抽奖动态就发送6,8,9条随机动态
|
||||
*/
|
||||
create_dy_mode: [[0], [0]],
|
||||
|
||||
/**
|
||||
* 转发时[at]的用户
|
||||
*/
|
||||
@@ -266,4 +249,4 @@ module.exports = Object.freeze({
|
||||
config_1: {},
|
||||
config_2: {},
|
||||
config_3: {}
|
||||
})
|
||||
}
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "lottery-auto-script",
|
||||
"version": "2.2.2",
|
||||
"version": "2.1.4",
|
||||
"description": "自动参与B站动态抽奖",
|
||||
"main": "main.js",
|
||||
"scripts": {
|
||||
@@ -52,4 +52,4 @@
|
||||
"chalk": "^4.1.1",
|
||||
"nodemailer": "^6.5.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,8 @@ set -e
|
||||
|
||||
# 脚本根目录
|
||||
SCRIPT_FOLDER=lottery
|
||||
# dyid存放目录
|
||||
DYID_FOLDER=dyids
|
||||
# 设置环境变量文件
|
||||
ENV_FILE=env.js
|
||||
# 自定义设置文件
|
||||
@@ -24,6 +26,14 @@ fi
|
||||
|
||||
cd $SCRIPT_FOLDER/
|
||||
|
||||
# 新建dyid储存目录
|
||||
if [ ! -d "$DYID_FOLDER" ]; then
|
||||
echo "create $DYID_FOLDER/"
|
||||
mkdir $DYID_FOLDER
|
||||
else
|
||||
echo "$DYID_FOLDER/ exists"
|
||||
fi
|
||||
|
||||
# 新建环境变量设置文件
|
||||
if [ ! -f "$ENV_FILE" ]; then
|
||||
echo "create $ENV_FILE"
|
||||
@@ -48,6 +58,7 @@ echo -e "#!/bin/bash\n\
|
||||
docker run \
|
||||
-v $PWD/$ENV_FILE:/lottery/$ENV_FILE \
|
||||
-v $PWD/$CONFIG_FILE:/lottery/$CONFIG_FILE \
|
||||
-v $PWD/$DYID_FOLDER/:/lottery/$DYID_FOLDER/ \
|
||||
$DOCKER_REPO \
|
||||
start" \
|
||||
> start.sh
|
||||
@@ -58,6 +69,7 @@ echo -e "#!/bin/bash\n\
|
||||
docker run \
|
||||
-v $PWD/$ENV_FILE:/lottery/$ENV_FILE \
|
||||
-v $PWD/$CONFIG_FILE:/lottery/$CONFIG_FILE \
|
||||
-v $PWD/$DYID_FOLDER/:/lottery/$DYID_FOLDER/ \
|
||||
$DOCKER_REPO \
|
||||
check" \
|
||||
> check.sh
|
||||
@@ -68,6 +80,7 @@ echo -e "#!/bin/bash\n\
|
||||
docker run \
|
||||
-v $PWD/$ENV_FILE:/lottery/$ENV_FILE \
|
||||
-v $PWD/$CONFIG_FILE:/lottery/$CONFIG_FILE \
|
||||
-v $PWD/$DYID_FOLDER/:/lottery/$DYID_FOLDER/ \
|
||||
$DOCKER_REPO \
|
||||
clear" \
|
||||
> clear.sh
|
||||
|
||||
Reference in New Issue
Block a user