mirror of
https://github.com/NapNeko/NapCatQQ.git
synced 2025-12-19 05:05:44 +08:00
249 lines
8.9 KiB
TypeScript
249 lines
8.9 KiB
TypeScript
import { ModifyProfileParams, User, UserDetailSource } from '@/napcat-core/types';
|
|
import { RequestUtil } from 'napcat-common/src/request';
|
|
import { InstanceContext, NapCatCore, ProfileBizType } from '..';
|
|
import { solveAsyncProblem } from 'napcat-common/src/helper';
|
|
import { Fallback, FallbackUtil } from 'napcat-common/src/fall-back';
|
|
|
|
export class NTQQUserApi {
|
|
context: InstanceContext;
|
|
core: NapCatCore;
|
|
|
|
constructor (context: InstanceContext, core: NapCatCore) {
|
|
this.context = context;
|
|
this.core = core;
|
|
}
|
|
|
|
async getCoreAndBaseInfo (uids: string[]) {
|
|
return await this.core.eventWrapper.callNoListenerEvent(
|
|
'NodeIKernelProfileService/getCoreAndBaseInfo',
|
|
'nodeStore',
|
|
uids
|
|
);
|
|
}
|
|
|
|
// 默认获取自己的 type = 2 获取别人 type = 1
|
|
async getProfileLike (uid: string, start: number, count: number, type: number = 2) {
|
|
return this.context.session.getProfileLikeService().getBuddyProfileLike({
|
|
friendUids: [uid],
|
|
basic: 1,
|
|
vote: 1,
|
|
favorite: 0,
|
|
userProfile: 1,
|
|
type,
|
|
start,
|
|
limit: count,
|
|
});
|
|
}
|
|
|
|
async setLongNick (longNick: string) {
|
|
return this.context.session.getProfileService().setLongNick(longNick);
|
|
}
|
|
|
|
async setSelfOnlineStatus (status: number, extStatus: number, batteryStatus: number) {
|
|
return this.context.session.getMsgService().setStatus({
|
|
status,
|
|
extStatus,
|
|
batteryStatus,
|
|
});
|
|
}
|
|
|
|
async setDiySelfOnlineStatus (faceId: string, wording: string, faceType: string) {
|
|
return this.context.session.getMsgService().setStatus({
|
|
status: 10,
|
|
extStatus: 2000,
|
|
customStatus: { faceId, wording, faceType },
|
|
batteryStatus: 0,
|
|
});
|
|
}
|
|
|
|
async getBuddyRecommendContactArkJson (uin: string, sencenID = '') {
|
|
return this.context.session.getBuddyService().getBuddyRecommendContactArkJson(uin, sencenID);
|
|
}
|
|
|
|
async like (uid: string, count = 1): Promise<{ result: number, errMsg: string, succCounts: number; }> {
|
|
return this.context.session.getProfileLikeService().setBuddyProfileLike({
|
|
friendUid: uid,
|
|
sourceId: 71,
|
|
doLikeCount: count,
|
|
doLikeTollCount: 0,
|
|
});
|
|
}
|
|
|
|
async setQQAvatar (filePath: string) {
|
|
const ret = await this.context.session.getProfileService().setHeader(filePath);
|
|
return { result: ret?.result, errMsg: ret?.errMsg };
|
|
}
|
|
|
|
async setGroupAvatar (gc: string, filePath: string) {
|
|
return this.context.session.getGroupService().setHeader(gc, filePath);
|
|
}
|
|
|
|
async fetchUserDetailInfo (uid: string, mode: UserDetailSource = UserDetailSource.KDB) {
|
|
const [, profile] = await this.core.eventWrapper.callNormalEventV2(
|
|
'NodeIKernelProfileService/fetchUserDetailInfo',
|
|
'NodeIKernelProfileListener/onUserDetailInfoChanged',
|
|
[
|
|
'BuddyProfileStore',
|
|
[uid],
|
|
mode,
|
|
[ProfileBizType.KALL],
|
|
],
|
|
() => true,
|
|
(profile) => profile.uid === uid
|
|
);
|
|
return profile;
|
|
}
|
|
|
|
async getUserDetailInfo (uid: string, no_cache: boolean = false): Promise<User> {
|
|
let profile = await solveAsyncProblem(async (uid) => this.fetchUserDetailInfo(uid, no_cache ? UserDetailSource.KSERVER : UserDetailSource.KDB), uid);
|
|
if (profile && profile.uin !== '0' && profile.commonExt) {
|
|
return {
|
|
...profile.simpleInfo.status,
|
|
...profile.simpleInfo.vasInfo,
|
|
...profile.commonExt,
|
|
...profile.simpleInfo.baseInfo,
|
|
...profile.simpleInfo.coreInfo,
|
|
qqLevel: profile.commonExt?.qqLevel,
|
|
age: profile.simpleInfo.baseInfo.age,
|
|
pendantId: '',
|
|
nick: profile.simpleInfo.coreInfo.nick || '',
|
|
};
|
|
}
|
|
this.context.logger.logDebug('[NapCat] [Mark] getUserDetailInfo Mode1 Failed.');
|
|
profile = await this.fetchUserDetailInfo(uid, UserDetailSource.KSERVER);
|
|
if (profile && profile.uin === '0') {
|
|
profile.uin = await this.core.apis.UserApi.getUidByUinV2(uid) ?? '0';
|
|
}
|
|
return {
|
|
...profile.simpleInfo.status,
|
|
...profile.simpleInfo.vasInfo,
|
|
...profile.commonExt,
|
|
...profile.simpleInfo.baseInfo,
|
|
...profile.simpleInfo.coreInfo,
|
|
qqLevel: profile.commonExt?.qqLevel,
|
|
age: profile.simpleInfo.baseInfo.age,
|
|
pendantId: '',
|
|
nick: profile.simpleInfo.coreInfo.nick || '',
|
|
};
|
|
}
|
|
|
|
async modifySelfProfile (param: ModifyProfileParams) {
|
|
return this.context.session.getProfileService().modifyDesktopMiniProfile(param);
|
|
}
|
|
|
|
async getCookies (domain: string) {
|
|
const ClientKeyData = await this.forceFetchClientKey();
|
|
const requestUrl = 'https://ssl.ptlogin2.qq.com/jump?ptlang=1033&clientuin=' + this.core.selfInfo.uin +
|
|
'&clientkey=' + ClientKeyData.clientKey + '&u1=https%3A%2F%2F' + domain + '%2F' + this.core.selfInfo.uin + '%2Finfocenter&keyindex=19%27';
|
|
const data = await RequestUtil.HttpsGetCookies(requestUrl);
|
|
if (!data['p_skey'] || data['p_skey'].length === 0) {
|
|
try {
|
|
const pskey = (await this.getPSkey([domain])).domainPskeyMap.get(domain);
|
|
if (pskey) data['p_skey'] = pskey;
|
|
} catch {
|
|
return data;
|
|
}
|
|
}
|
|
return data;
|
|
}
|
|
|
|
async getPSkey (domainList: string[]) {
|
|
return await this.context.session.getTipOffService().getPskey(domainList, true);
|
|
}
|
|
|
|
async getRobotUinRange (): Promise<Array<unknown>> {
|
|
const robotUinRanges = await this.context.session.getRobotService().getRobotUinRange({
|
|
justFetchMsgConfig: '1',
|
|
type: 1,
|
|
version: 0,
|
|
aioKeywordVersion: 0,
|
|
});
|
|
return robotUinRanges?.response?.robotUinRanges;
|
|
}
|
|
|
|
// 需要异常处理
|
|
|
|
async getQzoneCookies () {
|
|
const ClientKeyData = await this.forceFetchClientKey();
|
|
const requestUrl = 'https://ssl.ptlogin2.qq.com/jump?ptlang=1033&clientuin=' + this.core.selfInfo.uin + '&clientkey=' + ClientKeyData.clientKey + '&u1=https%3A%2F%2Fuser.qzone.qq.com%2F' + this.core.selfInfo.uin + '%2Finfocenter&keyindex=19%27';
|
|
return await RequestUtil.HttpsGetCookies(requestUrl);
|
|
}
|
|
|
|
// 需要异常处理
|
|
|
|
async getSKey (): Promise<string | undefined> {
|
|
const ClientKeyData = await this.forceFetchClientKey();
|
|
if (ClientKeyData.result !== 0) {
|
|
throw new Error('getClientKey Error');
|
|
}
|
|
const clientKey = ClientKeyData.clientKey;
|
|
// const keyIndex = ClientKeyData.keyIndex;
|
|
const requestUrl = 'https://ssl.ptlogin2.qq.com/jump?ptlang=1033&clientuin=' + this.core.selfInfo.uin + '&clientkey=' + clientKey + '&u1=https%3A%2F%2Fh5.qzone.qq.com%2Fqqnt%2Fqzoneinpcqq%2Ffriend%3Frefresh%3D0%26clientuin%3D0%26darkMode%3D0&keyindex=19%27';
|
|
const cookies: { [key: string]: string; } = await RequestUtil.HttpsGetCookies(requestUrl);
|
|
const skey = cookies['skey'];
|
|
if (!skey) {
|
|
throw new Error('SKey is Empty');
|
|
}
|
|
|
|
return skey;
|
|
}
|
|
|
|
async getUidByUinV2 (uin: string) {
|
|
if (!uin) {
|
|
return '';
|
|
}
|
|
|
|
const fallback =
|
|
new Fallback<string | undefined>((uid) => FallbackUtil.boolchecker(uid, uid !== undefined && uid.indexOf('*') === -1 && uid !== ''))
|
|
.add(() => this.context.session.getUixConvertService().getUid([uin]).then((data) => data.uidInfo.get(uin)))
|
|
.add(() => this.context.session.getProfileService().getUidByUin('FriendsServiceImpl', [uin]).get(uin))
|
|
.add(() => this.context.session.getGroupService().getUidByUins([uin]).then((data) => data.uids.get(uin)))
|
|
.add(() => this.getUserDetailInfoByUin(uin).then((data) => data.detail.uid));
|
|
|
|
const uid = await fallback.run().catch(() => '');
|
|
return uid ?? '';
|
|
}
|
|
|
|
async getUinByUidV2 (uid: string) {
|
|
if (!uid) {
|
|
return '0';
|
|
}
|
|
|
|
const fallback = new Fallback<string | undefined>((uin) => FallbackUtil.boolchecker(uin, uin !== undefined && uin !== '0' && uin !== ''))
|
|
.add(() => this.context.session.getUixConvertService().getUin([uid]).then((data) => data.uinInfo.get(uid)))
|
|
.add(() => this.context.session.getProfileService().getUinByUid('FriendsServiceImpl', [uid]).get(uid))
|
|
.add(() => this.context.session.getGroupService().getUinByUids([uid]).then((data) => data.uins.get(uid)))
|
|
.add(() => this.getUserDetailInfo(uid).then((data) => data.uin));
|
|
|
|
const uin = await fallback.run().catch(() => '0');
|
|
return uin ?? '0';
|
|
}
|
|
|
|
async getRecentContactListSnapShot (count: number) {
|
|
return await this.context.session.getRecentContactService().getRecentContactListSnapShot(count);
|
|
}
|
|
|
|
async getRecentContactListSyncLimit (count: number) {
|
|
return await this.context.session.getRecentContactService().getRecentContactListSyncLimit(count);
|
|
}
|
|
|
|
async getRecentContactListSync () {
|
|
return await this.context.session.getRecentContactService().getRecentContactListSync();
|
|
}
|
|
|
|
async getRecentContactList () {
|
|
return await this.context.session.getRecentContactService().getRecentContactList();
|
|
}
|
|
|
|
async getUserDetailInfoByUin (Uin: string) {
|
|
return await this.core.eventWrapper.callNoListenerEvent(
|
|
'NodeIKernelProfileService/getUserDetailInfoByUin',
|
|
Uin
|
|
);
|
|
}
|
|
|
|
async forceFetchClientKey () {
|
|
return await this.context.session.getTicketService().forceFetchClientKey('');
|
|
}
|
|
}
|