rc-plugin/apps/neteasepro.js
2023-03-14 21:15:57 +08:00

138 lines
4.8 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import plugin from "../../../lib/plugins/plugin.js";
import axios from "axios";
import fs from 'node:fs';
import {segment} from "oicq";
import {getQrCode, getKey, getLoginStatus, getDailyRecommend, getCookies} from '../utils/netease.js';
import {ha12store, store2ha1} from '../utils/encrypt.js';
export class neteasepro extends plugin {
constructor() {
super({
/** 功能名称 */
name: 'R插件网易云音乐解析',
/** 功能描述 */
dsc: '网易云音乐解析Pro',
/** https://oicqjs.github.io/oicq/#events */
event: 'message',
/** 优先级,数字越小等级越高 */
priority: 1,
rule: [
{
/** 命令正则匹配 */
reg: '#网易云登陆',
/** 执行方法 */
fnc: 'neteaseCloudLogin'
},
{
reg: '#网易云每日推荐',
fnc: 'neteaseDailyRecommend'
}
]
})
}
async neteaseCloudLogin(e) {
let userInfo;
// 如果不存在cookie
if (!await redis.exists(await this.getRedisKey(e.user_id))) {
// 获取密钥
const key = await getKey();
// console.log(key);
// 获取二维码
const qrPic = await getQrCode(key);
// 下载qrcode
await this.downloadQrCode(qrPic).then(path => {
// 发送二维码
e.reply(segment.image(fs.readFileSync(path)))
})
// 定时轮询
await this.poll(key).then(async cookie => {
// 存放到redis
await redis.set(await this.getRedisKey(e.user_id), ha12store(cookie))
});
}
// 从redis中获取
const realCookie = await store2ha1(await redis.get(await this.getRedisKey(e.user_id)));
// 获取用户信息
userInfo = await getLoginStatus(realCookie);
// 提取信息
const {nickname, avatarUrl} = userInfo.profile;
e.reply(["欢迎使用 🎶网易云音乐 🎶," + nickname, segment.image(avatarUrl)])
}
async neteaseDailyRecommend(e) {
const realCookie = await this.aopBefore(e);
if (realCookie === "") {
return true;
}
// 获取每日推荐所有数据
const dailyRecommend = await getDailyRecommend(realCookie);
// 由于数据过大取前10
let combineMsg = []
dailyRecommend.dailySongs.slice(0, 10).forEach(item => {
combineMsg.push([`${item?.id}: ${item?.name}-${item?.ar?.[0].name}-${item?.al?.name}`, segment.image(item?.al?.picUrl)])
})
await e.reply(await Bot.makeForwardMsg(combineMsg));
}
// 切面方法检测cookie
async aopBefore(e) {
// 取出cookie
const cookie = await redis.get(await this.getRedisKey(e.user_id));
// 如果不存在cookie
if (!cookie) {
e.reply("请先#网易云登录");
return "";
}
// 解析cookie
return store2ha1(cookie);
}
// 下载二维码
async downloadQrCode(qrPic) {
return axios
.get(qrPic, {
headers: {
"User-Agent":
"Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Mobile Safari/537.36",
},
responseType: "stream",
})
.then((resp) => {
const filepath = "./netease_qr.jpg";
const writer = fs.createWriteStream(filepath);
resp.data.pipe(writer);
return new Promise((resolve, reject) => {
writer.on("finish", () => resolve(filepath));
writer.on("error", reject);
});
});
}
// 定时轮询
async poll(key) {
let timer;
return new Promise((resolve, reject) => {
timer = setInterval(async () => {
const statusRes = await getCookies(key)
console.log(statusRes)
if (statusRes.code === 800) {
clearInterval(timer)
reject('二维码已过期,请重新获取')
}
if (statusRes.code === 803) {
// 这一步会返回cookie
clearInterval(timer)
const cookie = statusRes.cookie;
resolve(/__csrf=[0-9a-z]+;/.exec(cookie)[0] + /MUSIC_U=[0-9a-z]+;/.exec(cookie)[0]);
}
}, 3000)
});
}
// 获取redis的key
async getRedisKey(user_id) {
return `Yz:rconsole:netease:${user_id}`;
}
}