refactor: shared logic in webapi.ts

This commit is contained in:
Wesley F. Young 2024-08-09 15:14:11 +08:00
parent 0f77d9df1f
commit fa5d5f1bcc

View File

@ -1,69 +1,100 @@
import { RequestUtil } from '@/common/utils/request'; import { RequestUtil } from '@/common/utils/request';
import { InstanceContext } from '../wrapper'; import {
GroupEssenceMsgRet,
InstanceContext,
WebApiGroupMember,
WebApiGroupMemberRet,
WebApiGroupNoticeRet,
WebHonorType,
} from '@/core';
import { NapCatCore } from '..'; import { NapCatCore } from '..';
import { GroupEssenceMsgRet, WebApiGroupMember, WebApiGroupMemberRet, WebApiGroupNoticeRet, WebHonorType } from '../entities/webapi';
export class NTQQWebApi { export class NTQQWebApi {
context: InstanceContext; context: InstanceContext;
core: NapCatCore; core: NapCatCore;
constructor(context: InstanceContext, core: NapCatCore) { constructor(context: InstanceContext, core: NapCatCore) {
this.context = context; this.context = context;
this.core = core; this.core = core;
} }
async shareDigest(groupCode: string, msgSeq: string, msgRandom: string, targetGroupCode: string) { async shareDigest(groupCode: string, msgSeq: string, msgRandom: string, targetGroupCode: string) {
const CookiesObject = await this.core.getApiContext().UserApi.getCookies('qun.qq.com'); const cookieObject = await this.core.getApiContext().UserApi.getCookies('qun.qq.com');
const CookieValue = Object.entries(CookiesObject).map(([key, value]) => `${key}=${value}`).join('; '); const url = `https://qun.qq.com/cgi-bin/group_digest/share_digest?${
const Bkn = this.genBkn(CookiesObject.skey); new URLSearchParams({
let ret: any = undefined; bkn: this.getBknFromCookie(cookieObject),
const data = 'group_code=' + groupCode + '&msg_seq=' + msgSeq + '&msg_random=' + msgRandom + '&target_group_code=' + targetGroupCode; group_code: groupCode,
const url = 'https://qun.qq.com/cgi-bin/group_digest/share_digest?bkn=' + Bkn + "&" + data; msg_seq: msgSeq,
//console.log(url); msg_random: msgRandom,
target_group_code: targetGroupCode,
}).toString()
}`;
try { try {
ret = await RequestUtil.HttpGetText(url, 'GET', '', { 'Cookie': CookieValue }); return RequestUtil.HttpGetText(url, 'GET', '', { 'Cookie': this.cookieToString(cookieObject) });
return ret;
} catch (e) { } catch (e) {
return undefined; return undefined;
} }
return undefined;
} }
async getGroupEssenceMsg(GroupCode: string, page_start: string) { async getGroupEssenceMsg(GroupCode: string, page_start: string) {
const CookiesObject = await this.core.getApiContext().UserApi.getCookies('qun.qq.com'); const cookieObject = await this.core.getApiContext().UserApi.getCookies('qun.qq.com');
const CookieValue = Object.entries(CookiesObject).map(([key, value]) => `${key}=${value}`).join('; '); const url = `https://qun.qq.com/cgi-bin/group_digest/digest_list?${
const Bkn = this.genBkn(CookiesObject.skey); new URLSearchParams({
const url = 'https://qun.qq.com/cgi-bin/group_digest/digest_list?bkn=' + Bkn + '&group_code=' + GroupCode + '&page_start=' + page_start + '&page_limit=20'; bkn: this.getBknFromCookie(cookieObject),
group_code: GroupCode,
page_start,
page_limit: '20',
}).toString()
}`;
let ret; let ret;
try { try {
ret = await RequestUtil.HttpGetJson<GroupEssenceMsgRet>(url, 'GET', '', { 'Cookie': CookieValue }); ret = await RequestUtil.HttpGetJson<GroupEssenceMsgRet>
(url, 'GET', '', { 'Cookie': this.cookieToString(cookieObject) });
} catch { } catch {
return undefined; return undefined;
} }
//console.log(url, CookieValue);
if (ret.retcode !== 0) { if (ret.retcode !== 0) {
return undefined; return undefined;
} }
return ret; return ret;
} }
async getGroupMembers(GroupCode: string, cached: boolean = true): Promise<WebApiGroupMember[]> { async getGroupMembers(GroupCode: string, cached: boolean = true): Promise<WebApiGroupMember[]> {
//logDebug('webapi 获取群成员', GroupCode); //logDebug('webapi 获取群成员', GroupCode);
let MemberData: Array<WebApiGroupMember> = new Array<WebApiGroupMember>(); const memberData: Array<WebApiGroupMember> = new Array<WebApiGroupMember>();
try { const cookieObject = await this.core.getApiContext().UserApi.getCookies('qun.qq.com');
const CookiesObject = await this.core.getApiContext().UserApi.getCookies('qun.qq.com');
const CookieValue = Object.entries(CookiesObject).map(([key, value]) => `${key}=${value}`).join('; ');
const Bkn = this.genBkn(CookiesObject.skey);
const retList: Promise<WebApiGroupMemberRet>[] = []; const retList: Promise<WebApiGroupMemberRet>[] = [];
const fastRet = await RequestUtil.HttpGetJson<WebApiGroupMemberRet>('https://qun.qq.com/cgi-bin/qun_mgr/search_group_members?st=0&end=40&sort=1&gc=' + GroupCode + '&bkn=' + Bkn, 'POST', '', { 'Cookie': CookieValue }); const fastRet = await RequestUtil.HttpGetJson<WebApiGroupMemberRet>
(`https://qun.qq.com/cgi-bin/qun_mgr/search_group_members?${
new URLSearchParams({
st: '0',
end: '40',
sort: '1',
gc: GroupCode,
bkn: this.getBknFromCookie(cookieObject)
}).toString()
}`, 'POST', '', { 'Cookie': this.cookieToString(cookieObject) });
if (!fastRet?.count || fastRet?.errcode !== 0 || !fastRet?.mems) { if (!fastRet?.count || fastRet?.errcode !== 0 || !fastRet?.mems) {
return []; return [];
} else { } else {
for (const key in fastRet.mems) { for (const key in fastRet.mems) {
MemberData.push(fastRet.mems[key]); memberData.push(fastRet.mems[key]);
} }
} }
//初始化获取PageNum //初始化获取PageNum
const PageNum = Math.ceil(fastRet.count / 40); const PageNum = Math.ceil(fastRet.count / 40);
//遍历批量请求 //遍历批量请求
for (let i = 2; i <= PageNum; i++) { for (let i = 2; i <= PageNum; i++) {
const ret: Promise<WebApiGroupMemberRet> = RequestUtil.HttpGetJson<WebApiGroupMemberRet>('https://qun.qq.com/cgi-bin/qun_mgr/search_group_members?st=' + (i - 1) * 40 + '&end=' + i * 40 + '&sort=1&gc=' + GroupCode + '&bkn=' + Bkn, 'POST', '', { 'Cookie': CookieValue }); const ret = RequestUtil.HttpGetJson<WebApiGroupMemberRet>
(`https://qun.qq.com/cgi-bin/qun_mgr/search_group_members?${
new URLSearchParams({
st: ((i - 1) * 40).toString(),
end: (i * 40).toString(),
sort: '1',
gc: GroupCode,
bkn: this.getBknFromCookie(cookieObject)
}).toString()
}`, 'POST', '', { 'Cookie': this.cookieToString(cookieObject) });
retList.push(ret); retList.push(ret);
} }
//批量等待 //批量等待
@ -73,14 +104,12 @@ export class NTQQWebApi {
continue; continue;
} }
for (const key in ret.mems) { for (const key in ret.mems) {
MemberData.push(ret.mems[key]); memberData.push(ret.mems[key]);
} }
} }
} catch { return memberData;
return MemberData;
}
return MemberData;
} }
// public async addGroupDigest(groupCode: string, msgSeq: string) { // public async addGroupDigest(groupCode: string, msgSeq: string) {
// const url = `https://qun.qq.com/cgi-bin/group_digest/cancel_digest?random=665&X-CROSS-ORIGIN=fetch&group_code=${groupCode}&msg_seq=${msgSeq}&msg_random=444021292`; // const url = `https://qun.qq.com/cgi-bin/group_digest/cancel_digest?random=665&X-CROSS-ORIGIN=fetch&group_code=${groupCode}&msg_seq=${msgSeq}&msg_random=444021292`;
// const res = await this.request(url); // const res = await this.request(url);
@ -92,33 +121,41 @@ export class NTQQWebApi {
// const res = await this.request(url); // const res = await this.request(url);
// return await res.json(); // return await res.json();
// } // }
async setGroupNotice(GroupCode: string, Content: string = '') {
//https://web.qun.qq.com/cgi-bin/announce/add_qun_notice?bkn=${bkn}
//qid=${群号}&bkn=${bkn}&text=${内容}&pinned=0&type=1&settings={"is_show_edit_card":1,"tip_window_type":1,"confirm_required":1}
const CookiesObject = await this.core.getApiContext().UserApi.getCookies('qun.qq.com'); async setGroupNotice(GroupCode: string, Content: string) {
const CookieValue = Object.entries(CookiesObject).map(([key, value]) => `${key}=${value}`).join('; '); const cookieObject = await this.core.getApiContext().UserApi.getCookies('qun.qq.com');
const Bkn = this.genBkn(CookiesObject.skey);
let ret: any = undefined; let ret: any = undefined;
const data = 'qid=' + GroupCode + '&bkn=' + Bkn + '&text=' + Content + '&pinned=0&type=1&settings={"is_show_edit_card":1,"tip_window_type":1,"confirm_required":1}';
const url = 'https://web.qun.qq.com/cgi-bin/announce/add_qun_notice?bkn=' + Bkn;
try { try {
ret = await RequestUtil.HttpGetJson<any>(url, 'GET', '', { 'Cookie': CookieValue }); ret = await RequestUtil.HttpGetJson<any>
(`https://web.qun.qq.com/cgi-bin/announce/add_qun_notice${
new URLSearchParams({
bkn: this.getBknFromCookie(cookieObject),
qid: GroupCode,
text: Content,
pinned: '0',
type: '1',
settings: '{"is_show_edit_card":1,"tip_window_type":1,"confirm_required":1}',
}).toString()
}`, 'GET', '', { 'Cookie': this.cookieToString(cookieObject) });
return ret; return ret;
} catch (e) { } catch (e) {
return undefined; return undefined;
} }
return undefined;
} }
async getGrouptNotice(GroupCode: string): Promise<undefined | WebApiGroupNoticeRet> {
const CookiesObject = await this.core.getApiContext().UserApi.getCookies('qun.qq.com'); async getGroupNotice(GroupCode: string): Promise<undefined | WebApiGroupNoticeRet> {
const CookieValue = Object.entries(CookiesObject).map(([key, value]) => `${key}=${value}`).join('; '); const cookieObject = await this.core.getApiContext().UserApi.getCookies('qun.qq.com');
const Bkn = this.genBkn(CookiesObject.skey);
let ret: WebApiGroupNoticeRet | undefined = undefined; let ret: WebApiGroupNoticeRet | undefined = undefined;
//console.log(CookieValue);
const url = 'https://web.qun.qq.com/cgi-bin/announce/get_t_list?bkn=' + Bkn + '&qid=' + GroupCode + '&ft=23&ni=1&n=1&i=1&log_read=1&platform=1&s=-1&n=20';
try { try {
ret = await RequestUtil.HttpGetJson<WebApiGroupNoticeRet>(url, 'GET', '', { 'Cookie': CookieValue }); ret = await RequestUtil.HttpGetJson<WebApiGroupNoticeRet>(`https://web.qun.qq.com/cgi-bin/announce/get_t_list?${
new URLSearchParams({
bkn: this.getBknFromCookie(cookieObject),
qid: GroupCode,
type: '1',
start: '0',
num: '1',
}).toString()
}`, 'GET', '', { 'Cookie': this.cookieToString(cookieObject) });
if (ret?.ec !== 0) { if (ret?.ec !== 0) {
return undefined; return undefined;
} }
@ -126,29 +163,20 @@ export class NTQQWebApi {
} catch (e) { } catch (e) {
return undefined; return undefined;
} }
return undefined;
}
genBkn(sKey: string) {
sKey = sKey || '';
let hash = 5381;
for (let i = 0; i < sKey.length; i++) {
const code = sKey.charCodeAt(i);
hash = hash + (hash << 5) + code;
} }
return (hash & 0x7FFFFFFF).toString();
}
async getGroupHonorInfo(groupCode: string, getType: WebHonorType) { async getGroupHonorInfo(groupCode: string, getType: WebHonorType) {
const CookiesObject = await this.core.getApiContext().UserApi.getCookies('qun.qq.com'); const cookieObject = await this.core.getApiContext().UserApi.getCookies('qun.qq.com');
const CookieValue = Object.entries(CookiesObject).map(([key, value]) => `${key}=${value}`).join('; ');
const Bkn = this.genBkn(CookiesObject.skey);
const getDataInternal = async (Internal_groupCode: string, Internal_type: number) => { const getDataInternal = async (Internal_groupCode: string, Internal_type: number) => {
let url = 'https://qun.qq.com/interactive/honorlist?gc=' + Internal_groupCode + '&type=' + Internal_type.toString(); const url = `https://qun.qq.com/interactive/honorlist?${
let res = ''; new URLSearchParams({
gc: Internal_groupCode,
type: Internal_type.toString(),
}).toString()
}`;
let resJson; let resJson;
try { try {
res = await RequestUtil.HttpGetText(url, 'GET', '', { 'Cookie': CookieValue }); const res = await RequestUtil.HttpGetText(url, 'GET', '', { 'Cookie': this.cookieToString(cookieObject) });
const match = res.match(/window\.__INITIAL_STATE__=(.*?);/); const match = res.match(/window\.__INITIAL_STATE__=(.*?);/);
if (match) { if (match) {
resJson = JSON.parse(match[1].trim()); resJson = JSON.parse(match[1].trim());
@ -162,13 +190,13 @@ export class NTQQWebApi {
this.context.logger.logDebug('获取当前群荣耀失败', url, e); this.context.logger.logDebug('获取当前群荣耀失败', url, e);
} }
return undefined; return undefined;
} };
const HonorInfo: any = { group_id: groupCode }; const HonorInfo: any = { group_id: groupCode };
if (getType === WebHonorType.TALKACTIVE || getType === WebHonorType.ALL) { if (getType === WebHonorType.TALKACTIVE || getType === WebHonorType.ALL) {
try { try {
let RetInternal = await getDataInternal(groupCode, 1); const RetInternal = await getDataInternal(groupCode, 1);
if (!RetInternal) { if (!RetInternal) {
throw new Error('获取龙王信息失败'); throw new Error('获取龙王信息失败');
} }
@ -177,8 +205,8 @@ export class NTQQWebApi {
avatar: RetInternal[0]?.avatar, avatar: RetInternal[0]?.avatar,
nickname: RetInternal[0]?.name, nickname: RetInternal[0]?.name,
day_count: 0, day_count: 0,
description: RetInternal[0]?.desc description: RetInternal[0]?.desc,
} };
HonorInfo.talkative_list = []; HonorInfo.talkative_list = [];
for (const talkative_ele of RetInternal) { for (const talkative_ele of RetInternal) {
HonorInfo.talkative_list.push({ HonorInfo.talkative_list.push({
@ -186,7 +214,7 @@ export class NTQQWebApi {
avatar: talkative_ele?.avatar, avatar: talkative_ele?.avatar,
description: talkative_ele?.desc, description: talkative_ele?.desc,
day_count: 0, day_count: 0,
nickname: talkative_ele?.name nickname: talkative_ele?.name,
}); });
} }
} catch (e) { } catch (e) {
@ -195,7 +223,7 @@ export class NTQQWebApi {
} }
if (getType === WebHonorType.PERFROMER || getType === WebHonorType.ALL) { if (getType === WebHonorType.PERFROMER || getType === WebHonorType.ALL) {
try { try {
let RetInternal = await getDataInternal(groupCode, 2); const RetInternal = await getDataInternal(groupCode, 2);
if (!RetInternal) { if (!RetInternal) {
throw new Error('获取群聊之火失败'); throw new Error('获取群聊之火失败');
} }
@ -205,7 +233,7 @@ export class NTQQWebApi {
user_id: performer_ele?.uin, user_id: performer_ele?.uin,
nickname: performer_ele?.name, nickname: performer_ele?.name,
avatar: performer_ele?.avatar, avatar: performer_ele?.avatar,
description: performer_ele?.desc description: performer_ele?.desc,
}); });
} }
} catch (e) { } catch (e) {
@ -214,7 +242,7 @@ export class NTQQWebApi {
} }
if (getType === WebHonorType.PERFROMER || getType === WebHonorType.ALL) { if (getType === WebHonorType.PERFROMER || getType === WebHonorType.ALL) {
try { try {
let RetInternal = await getDataInternal(groupCode, 3); const RetInternal = await getDataInternal(groupCode, 3);
if (!RetInternal) { if (!RetInternal) {
throw new Error('获取群聊炽焰失败'); throw new Error('获取群聊炽焰失败');
} }
@ -224,7 +252,7 @@ export class NTQQWebApi {
user_id: legend_ele?.uin, user_id: legend_ele?.uin,
nickname: legend_ele?.name, nickname: legend_ele?.name,
avatar: legend_ele?.avatar, avatar: legend_ele?.avatar,
desc: legend_ele?.description desc: legend_ele?.description,
}); });
} }
} catch (e) { } catch (e) {
@ -233,17 +261,17 @@ export class NTQQWebApi {
} }
if (getType === WebHonorType.EMOTION || getType === WebHonorType.ALL) { if (getType === WebHonorType.EMOTION || getType === WebHonorType.ALL) {
try { try {
let RetInternal = await getDataInternal(groupCode, 6); const RetInternal = await getDataInternal(groupCode, 6);
if (!RetInternal) { if (!RetInternal) {
throw new Error('获取快乐源泉失败'); throw new Error('获取快乐源泉失败');
} }
HonorInfo.emotion_list = []; HonorInfo.emotion_list = [];
for (const emotion_ele of RetInternal) { for (const emotion_ele of RetInternal) {
HonorInfo.emotion_list.push({ HonorInfo.emotion_list.push({
user_id: emotion_ele?.uin, user_id: emotion_ele.uin,
nickname: emotion_ele?.name, nickname: emotion_ele.name,
avatar: emotion_ele?.avatar, avatar: emotion_ele.avatar,
desc: emotion_ele?.description desc: emotion_ele.description,
}); });
} }
} catch (e) { } catch (e) {
@ -256,4 +284,19 @@ export class NTQQWebApi {
} }
return HonorInfo; return HonorInfo;
} }
private cookieToString(cookieObject: any) {
return Object.entries(cookieObject).map(([key, value]) => `${key}=${value}`).join('; ');
}
private getBknFromCookie(cookieObject: any) {
const sKey = cookieObject.skey as string;
let hash = 5381;
for (let i = 0; i < sKey.length; i++) {
const code = sKey.charCodeAt(i);
hash = hash + (hash << 5) + code;
}
return (hash & 0x7FFFFFFF).toString();
}
} }