From c1edd270df1718db8ddb28450331cbbc1bffc2e4 Mon Sep 17 00:00:00 2001 From: Lkeme <19500576+lkeme@users.noreply.github.com> Date: Sun, 6 Aug 2023 19:37:35 +0800 Subject: [PATCH] [add] BatchUnfollow --- README.md | 1 + docs/CHANGELOG.md | 6 +- plugin/BatchUnfollow/BatchUnfollow.php | 161 +++++++++++++++++++++++ plugin/PluginTemplate/PluginTemplate.php | 2 +- profile/example/config/user.ini | 6 +- src/Api/Api/X/Relation/ApiRelation.php | 123 +++++++++++++++++ 6 files changed, 295 insertions(+), 4 deletions(-) create mode 100644 plugin/BatchUnfollow/BatchUnfollow.php create mode 100644 src/Api/Api/X/Relation/ApiRelation.php diff --git a/README.md b/README.md index 1c24342..db991dd 100644 --- a/README.md +++ b/README.md @@ -116,6 +116,7 @@ Group: [602815575](https://jq.qq.com/?_wv=1027&k=UaalVexM) | **请不要来问 | Lottery | 0.0.2 | 抽奖 | MoeHero/Lkeme | 1113 | 5(分钟) | √ | | DailyGold | 0.0.1 | 每日电池(APP) | Lkeme | 1114 | 24(小时) | √ | | PolishMedal | 0.0.1 | 点亮灰色勋章 | possible318/Lkeme | 1115 | 1(小时) | √ | +| BatchUnfollow | 0.0.1 | 批量取消关注 | Lkeme | 1116 | 5-10(分钟) | √ | diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index c8ae26a..27df002 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -12,11 +12,13 @@ ### Added -- +- 批量取关插件 +- ### Changed -- +- 更新会员大积分任务 +- ### Fixed diff --git a/plugin/BatchUnfollow/BatchUnfollow.php b/plugin/BatchUnfollow/BatchUnfollow.php new file mode 100644 index 0000000..08a5692 --- /dev/null +++ b/plugin/BatchUnfollow/BatchUnfollow.php @@ -0,0 +1,161 @@ + __CLASS__, // hook + 'name' => 'BatchUnfollow', // 插件名称 + 'version' => '0.0.1', // 插件版本 + 'desc' => '批量取消关注', // 插件描述 + 'author' => 'Lkeme',// 作者 + 'priority' => 1116, // 插件优先级 + 'cycle' => '5-10(分钟)', // 运行周期 + // 新增字段 + 'start' => '08:00:00', // 插件开始日期 + 'end' => '23:00:00', // 插件结束日期 + ]; + + /** + * @var array + */ + protected array $wait_unfollows = []; + + /** + * @param Plugin $plugin + */ + public function __construct(Plugin &$plugin) + { + // 时间锁 + TimeLock::initTimeLock(); + // 缓存 + // Cache::initCache(); + // $this::class + $plugin->register($this, 'execute'); + } + + /** + * 执行 + * @return void + */ + public function execute(): void + { + // 时间段限制 + // if (!TimeLock::isWithinTimeRange($this->info['start'], $this->info['end'])) return; + // 时间锁限制 + if (TimeLock::getTimes() > time() || !getEnable('batch_unfollow')) return; + // + if (empty($this->wait_unfollows)) { + $this->fetchFollows(); + // + if (empty($this->wait_unfollows)) { + TimeLock::setTimes(mt_rand(60, 120) * 60); + return; + } + } else { + $this->unfollow(); + } + TimeLock::setTimes(mt_rand(5, 10) * 60); + } + + /** + * 获取关注列表 + * @return void + */ + protected function fetchFollows(): void + { + $follows = []; + // + if (getConf('batch_unfollow.tag') == 'all') { + $response = ApiRelation::followings(1, 50); + if ($response['code'] != 0) { + Log::warning("批量取关: 获取关注列表失败: {$response['code']} -> {$response['message']}"); + return; + } + foreach ($response['data']['list'] as $item) { + $follows[] = ['mid' => $item['mid'], 'uname' => $item['uname']]; + } + } else { + $target_tag = getConf('batch_unfollow.tag'); + // + $response = ApiRelation::tags(); + if ($response['code'] != 0) { + Log::warning("批量取关: 获取分组列表失败: {$response['code']} -> {$response['message']}"); + return; + } + // + $tagid = 0; + foreach ($response['data'] as $item) { + if ($item['name'] == $target_tag) { + $tagid = $item['tagid']; + break; + } + } + if ($tagid == 0) { + Log::warning("批量取关: 未找到目标分组: {$target_tag}"); + return; + } + // + $response = ApiRelation::tag($tagid, 1, 50); + if ($response['code'] != 0) { + Log::warning("批量取关: 获取分组内列表失败: {$response['code']} -> {$response['message']}"); + return; + } + // + foreach ($response['data']['list'] as $item) { + $follows[] = ['mid' => $item['mid'], 'uname' => $item['uname']]; + } + } + + $this->wait_unfollows = $follows; + Log::info("批量取关: 获取关注列表成功 Count: " . count($follows)); + } + + /** + * 取关 + * @return void + */ + protected function unfollow(): void + { + $follow = array_shift($this->wait_unfollows); + if (is_null($follow)) { + Log::info("批量取关: 暂无关注列表"); + return; + } + // + Log::info("批量取关: 尝试取关用户: {$follow['uname']}({$follow['mid']})"); + // + $response = ApiRelation::modify($follow['mid']); + if ($response['code'] != 0) { + Log::warning("批量取关: 取关失败: {$response['code']} -> {$response['message']}"); + return; + } + Log::notice('批量取关: 取关成功'); + } + + +} diff --git a/plugin/PluginTemplate/PluginTemplate.php b/plugin/PluginTemplate/PluginTemplate.php index 774a8e3..076069a 100644 --- a/plugin/PluginTemplate/PluginTemplate.php +++ b/plugin/PluginTemplate/PluginTemplate.php @@ -27,7 +27,7 @@ class PluginTemplate extends BasePlugin */ protected ?array $info = [ 'hook' => __CLASS__, // hook - 'name' => 'PolishTheMedal', // 插件名称 + 'name' => 'PluginTemplate', // 插件名称 'version' => '0.0.1', // 插件版本 'desc' => '插件模板', // 插件描述 'author' => 'Lkeme',// 作者 diff --git a/profile/example/config/user.ini b/profile/example/config/user.ini index 1871fab..0d42fbe 100644 --- a/profile/example/config/user.ini +++ b/profile/example/config/user.ini @@ -122,12 +122,16 @@ enable = false target_up_id = 11153765 target_room_id = 23058 - ; 擦亮徽章/ 每日擦亮 默认擦亮变灰徽章 [polish_medal] enable = false everyday = false +; 批量取消关注/分组名称/默认为all(全部) +[batch_unfollow] +enable = false +tag = all + ####################### # 通知设置 # ####################### diff --git a/src/Api/Api/X/Relation/ApiRelation.php b/src/Api/Api/X/Relation/ApiRelation.php new file mode 100644 index 0000000..3d13895 --- /dev/null +++ b/src/Api/Api/X/Relation/ApiRelation.php @@ -0,0 +1,123 @@ + 'https://space.bilibili.com', + 'referer' => "https://space.bilibili.com/{$user['uid']}/fans/follow" + ]; + $payload = [ + 'vmid' => $user['uid'], + 'pn' => $pn, + 'ps' => $ps, + 'order' => $order, + 'order_type' => $order_type, + ]; + // + return Request::getJson(true, 'pc', $url, $payload, $headers); + } + + + /** + * 获取关注分组列表 + * @return array + */ + public static function tags(): array + { + $user = User::parseCookie(); + // + $url = 'https://api.bilibili.com/x/relation/tags'; + $headers = [ + 'origin' => 'https://space.bilibili.com', + 'referer' => "https://space.bilibili.com/{$user['uid']}/fans/follow" + ]; + $payload = []; + // + return Request::getJson(true, 'pc', $url, $payload, $headers); + } + + /** + * 获取关注分组列表 + * @param int $tag_id + * @param int $pn + * @param int $ps + * @return array + */ + public static function tag(int $tag_id, int $pn = 1, int $ps = 20): array + { + $user = User::parseCookie(); + // + $url = 'https://api.bilibili.com/x/relation/tag'; + $headers = [ + 'origin' => 'https://space.bilibili.com', + 'referer' => "https://space.bilibili.com/{$user['uid']}/fans/follow" + ]; + $payload = [ + 'mid' => $user['uid'], + 'tagid' => $tag_id, + 'pn' => $pn, + 'ps' => $ps, + ]; + // + return Request::getJson(true, 'pc', $url, $payload, $headers); + } + + + /** + * 取关 + * @param int $uid + * @return array + */ + public static function modify(int $uid): array + { + $user = User::parseCookie(); + // + $url = 'https://api.bilibili.com/x/relation/modify'; + $headers = [ + 'origin' => 'https://space.bilibili.com', + 'referer' => "https://space.bilibili.com/{$user['uid']}/fans/follow" + ]; + $payload = [ + 'fid' => $uid, + 'act' => 2, + 're_src' => 11, + 'csrf' => $user['csrf'], + ]; + // + return Request::postJson(true, 'pc', $url, $payload, $headers); + } +}