feat: V1.6.3 增加bili扫码登录

现在使用 #R插件B站扫码 即可登录体验AI总结功能
This commit is contained in:
zhiyu1998 2024-04-01 20:26:00 +08:00
parent 88849fedd3
commit f131e93830
8 changed files with 140 additions and 21 deletions

View File

@ -12,7 +12,7 @@ import {
downloadBFile,
getBiliAudio,
getDownloadUrl,
getDynamic,
getDynamic, getScanCodeData,
getVideoInfo,
m4sToMp3,
mergeFileToMp4
@ -50,10 +50,8 @@ import {
TIKTOK_INFO,
TWITTER_TWEET_INFO,
XHS_REQ_LINK,
GENERAL_REQ_LINK, WEIBO_SINGLE_INFO, WEISHI_VIDEO_INFO
GENERAL_REQ_LINK, WEIBO_SINGLE_INFO, WEISHI_VIDEO_INFO, BILI_SCAN_CODE_GENERATE
} from "../constants/tools.js";
import child_process from 'node:child_process'
import { getAudio, getVideo } from "../utils/y2b.js";
import { processTikTokUrl } from "../utils/tiktok.js";
import { getDS } from "../utils/mihoyo.js";
import GeneralLinkAdapter from "../utils/general-link-adapter.js";
@ -92,6 +90,11 @@ export class tools extends plugin {
reg: "(www.tiktok.com)|(vt.tiktok.com)|(vm.tiktok.com)",
fnc: "tiktok",
},
{
reg: "^#R插件B站扫码$",
fnc: "biliScan",
permission: 'master',
},
{
reg: "(bilibili.com|b23.tv|t.bilibili.com)",
fnc: "bili",
@ -339,6 +342,24 @@ export class tools extends plugin {
return true;
}
async biliScan(e) {
e.reply('R插件开源免责声明:\n您将通过扫码完成获取哔哩哔哩refresh_token以及ck。\n本Bot将不会保存您的登录状态。\n我方仅提供视频解析及相关B站内容服务,若您的账号封禁、被盗等处罚与我方无关。\n害怕风险请勿扫码 ~', { recallMsg: 180 });
// 图片发送钩子
const imgSendHook = function (e, path) {
e.reply([segment.image(path), segment.at(e.user_id), '请扫码以完成获取'], { recallMsg: 180 })
};
// 发送请求
const saveCodePath = `${ this.defaultPath }qrcode.png`;
const { SESSDATA, refresh_token } = await getScanCodeData(saveCodePath, 8, () => imgSendHook(e, saveCodePath))
// 更新到配置文件
config.updateField("tools", "biliSessData", SESSDATA);
e.reply('登录成功!相关信息已保存至配置文件', true)
return true;
}
// bilibi解析
async bili(e) {
await this.limitUserUse(e, () => {

View File

@ -38,6 +38,9 @@
- icon: bilibili
title: "bilibili/b23"
desc: 哔哩哔哩分享实时下载
- icon: bqrcode
title: "R插件B站扫码"
desc: R插件B站扫码
- icon: bilimusic
title: "bili音乐+链接"
desc: 哔哩哔哩音乐分享实时下载

View File

@ -1,11 +1,10 @@
- {
version: 1.6.2,
version: 1.6.3,
data:
[
新增<span class="cmd">B站扫码</span>功能,
新增<span class="cmd">即刻解析</span>功能,
新增<span class="cmd">微视解析</span>功能,
新增<span class="cmd">小世界解析</span>功能,
新增<span class="cmd">贴吧解析</span>功能,
支持<span class="cmd">锅巴</span>插件,方便查看和修改配置,
添加<span class="cmd">#R帮助</span>获取插件帮助,
添加<span class="cmd">#R版本</span>获取插件版本,

View File

@ -40,6 +40,20 @@ export const BILI_VIDEO_INFO = "http://api.bilibili.com/x/web-interface/view"
*/
export const BILI_NAV = "https://api.bilibili.com/x/web-interface/nav"
/**
* 扫码登录的二维码生成
* https://github.com/SocialSisterYi/bilibili-API-collect/blob/master/docs/login/login_action/QR.md
* @type {string}
*/
export const BILI_SCAN_CODE_GENERATE = "https://passport.bilibili.com/x/passport-login/web/qrcode/generate"
/**
* 扫码登录检测然后发送令牌数据
* https://github.com/SocialSisterYi/bilibili-API-collect/blob/master/docs/login/login_action/QR.md
* @type {string}
*/
export const BILI_SCAN_CODE_DETECT = "https://passport.bilibili.com/x/passport-login/web/qrcode/poll?qrcode_key={}";
/**
* 米游社网页端获取文章
* https://github.com/UIGF-org/mihoyo-api-collect/blob/main/hoyolab/article/article.md#%E8%8E%B7%E5%8F%96%E5%AE%8C%E6%95%B4%E6%96%87%E7%AB%A0%E4%BF%A1%E6%81%AF

View File

@ -28,6 +28,26 @@ class RConfig {
return this.getYaml(name)
}
// 获取指定配置的某个字段
getField(name, field) {
const config = this.getConfig(name);
return config[field];
}
// 更新指定配置的某个字段
updateField(name, field, value) {
let config = this.getConfig(name);
config[field] = value; // 更新字段值
this.saveSet(name, config); // 保存更改
}
// 删除指定配置的某个字段
deleteField(name, field) {
let config = this.getConfig(name);
delete config[field]; // 删除指定字段
this.saveSet(name, config); // 保存更改
}
/**
* 获取配置yaml
* @param name 名称

View File

@ -4,6 +4,7 @@
"type": "module",
"dependencies": {
"axios": "^1.3.4",
"tunnel": "^0.0.6"
"tunnel": "^0.0.6",
"qrcode": "^1.5.3"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

View File

@ -2,8 +2,21 @@ import fs from "node:fs";
import axios from 'axios'
import child_process from 'node:child_process'
import util from "util";
import { BILI_BVID_TO_CID, BILI_DYNAMIC, BILI_PLAY_STREAM, BILI_VIDEO_INFO } from "../constants/tools.js";
import {
BILI_BVID_TO_CID,
BILI_DYNAMIC,
BILI_PLAY_STREAM, BILI_SCAN_CODE_DETECT,
BILI_SCAN_CODE_GENERATE,
BILI_VIDEO_INFO
} from "../constants/tools.js";
import { mkdirIfNotExists } from "./file.js";
import qrcode from "qrcode"
const biliHeaders = {
'User-Agent':
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36',
referer: 'https://www.bilibili.com',
}
/**
* 下载单个bili文件
@ -17,9 +30,7 @@ export async function downloadBFile(url, fullFileName, progressCallback) {
.get(url, {
responseType: 'stream',
headers: {
'User-Agent':
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36',
referer: 'https://www.bilibili.com',
...biliHeaders
},
})
.then(({ data, headers }) => {
@ -53,9 +64,7 @@ export async function getDownloadUrl(url) {
return axios
.get(url, {
headers: {
'User-Agent':
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36',
referer: 'https://www.bilibili.com',
...biliHeaders
},
})
.then(({ data }) => {
@ -127,9 +136,7 @@ export async function m4sToMp3(m4sUrl, path) {
.get(m4sUrl, {
responseType: 'stream',
headers: {
'User-Agent':
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36',
referer: 'https://www.bilibili.com',
...biliHeaders
},
}).then(async res => {
// 如果没有目录就创建一个
@ -231,9 +238,7 @@ export async function getDynamic(dynamicId, SESSDATA) {
const dynamicApi = BILI_DYNAMIC.replace("{}", dynamicId);
return axios.get(dynamicApi, {
headers: {
'User-Agent':
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36',
'referer': 'https://www.bilibili.com',
...biliHeaders,
Cookie: `SESSDATA=${ SESSDATA }`
},
}).then(resp => {
@ -255,3 +260,59 @@ export async function getDynamic(dynamicId, SESSDATA) {
}
})
}
/**
* 扫码
* @param qrcodeSavePath 必须QR保存位置
* @param detectTime 可选检测时间默认10s检测一次
* @param hook 可选钩子函数目前只用来人机交互
* @returns {Promise<{
* SESSDATA,
* refresh_token
* }>}
*/
export async function getScanCodeData(qrcodeSavePath = 'qrcode.png', detectTime = 10, hook = () => {}) {
try {
const resp = await axios.get(BILI_SCAN_CODE_GENERATE, { ...biliHeaders });
// 保存扫码的地址、扫码登录秘钥
const { url: scanUrl, qrcode_key } = resp.data.data;
await qrcode.toFile(qrcodeSavePath, scanUrl);
let code = 1;
// 设置最大尝试次数
let attemptCount = 0;
const maxAttempts = 3;
let loginResp;
// 检测扫码情况默认 10s 检测一次并且尝试3次没扫就拜拜
while (code !== 0 && attemptCount < maxAttempts) {
// 钩子函数,目前用于发送二维码给用户
hook();
loginResp = await axios.get(BILI_SCAN_CODE_DETECT.replace("{}", qrcode_key), { ...biliHeaders });
code = loginResp.data.data.code;
await new Promise(resolve => setTimeout(resolve, detectTime * 1000)); // Wait for detectTime seconds
}
// 获取刷新令牌
const { refresh_token } = loginResp.data.data;
// 获取cookie
const cookies = loginResp.headers['set-cookie'];
const SESSDATA = cookies
.map(cookie => cookie.split(';').find(item => item.trim().startsWith('SESSDATA=')))
.find(item => item !== undefined)
?.split('=')[1];
return {
SESSDATA,
refresh_token
};
} catch (err) {
logger.error(err);
// 可能需要处理错误或返回一个默认值
return {
SESSDATA: '',
refresh_token: ''
};
}
}