mirror of
https://github.com/LLOneBot/LLOneBot.git
synced 2024-11-22 01:56:33 +00:00
fix
This commit is contained in:
parent
a56eac0251
commit
2245d0d3de
@ -1,6 +1,6 @@
|
||||
# LLOneBot
|
||||
|
||||
LiteLoaderQQNT 插件,实现 OneBot 11 协议,用以 QQ 机器人开发
|
||||
LiteLoaderQQNT 插件,实现 OneBot 11 协议,用于 QQ 机器人开发
|
||||
|
||||
> [!CAUTION]\
|
||||
> **请不要在 QQ 官方群聊和任何影响力较大的简中互联网平台(包括但不限于: 哔哩哔哩,微博,知乎,抖音等)发布和讨论*任何*与本插件存在相关性的信息**
|
||||
|
@ -6,7 +6,7 @@ const manifest = {
|
||||
type: 'extension',
|
||||
name: 'LLOneBot',
|
||||
slug: 'LLOneBot',
|
||||
description: '实现 OneBot 11 协议,用以 QQ 机器人开发',
|
||||
description: '实现 OneBot 11 协议,用于 QQ 机器人开发',
|
||||
version,
|
||||
icon: './icon.webp',
|
||||
authors: [
|
||||
|
@ -66,6 +66,7 @@ export async function getGroupMember(groupCode: string | number, memberUinOrUid:
|
||||
let member = getMember()
|
||||
if (!member) {
|
||||
members = await NTQQGroupApi.getGroupMembers(groupCodeStr)
|
||||
groupMembers.set(groupCodeStr, members)
|
||||
member = getMember()
|
||||
}
|
||||
return member
|
||||
|
@ -16,7 +16,7 @@ export class RequestUtil {
|
||||
const redirectUrl = new URL(res.headers.location, url);
|
||||
RequestUtil.HttpsGetCookies(redirectUrl.href).then((redirectCookies) => {
|
||||
// 合并重定向过程中的cookies
|
||||
log('redirectCookies', redirectCookies)
|
||||
//log('redirectCookies', redirectCookies)
|
||||
cookies = { ...cookies, ...redirectCookies };
|
||||
resolve(cookies);
|
||||
});
|
||||
@ -33,7 +33,7 @@ export class RequestUtil {
|
||||
});
|
||||
if (res.headers['set-cookie']) {
|
||||
// console.log(res.headers['set-cookie']);
|
||||
log('set-cookie', url, res.headers['set-cookie']);
|
||||
//log('set-cookie', url, res.headers['set-cookie']);
|
||||
res.headers['set-cookie'].forEach((cookie) => {
|
||||
const parts = cookie.split(';')[0].split('=');
|
||||
const key = parts[0];
|
||||
|
@ -138,45 +138,47 @@ export class WebApi {
|
||||
return ret
|
||||
}
|
||||
|
||||
@CacheClassFuncAsync(3600 * 1000, 'webapi_get_group_members')
|
||||
static async getGroupMembers(GroupCode: string, cached: boolean = true): Promise<WebApiGroupMember[]> {
|
||||
//logDebug('webapi 获取群成员', GroupCode)
|
||||
let MemberData: Array<WebApiGroupMember> = new Array<WebApiGroupMember>()
|
||||
try {
|
||||
const CookiesObject = await NTQQUserApi.getCookies('qun.qq.com')
|
||||
const CookieValue = Object.entries(CookiesObject).map(([key, value]) => `${key}=${value}`).join('; ')
|
||||
const Bkn = WebApi.genBkn(CookiesObject.skey)
|
||||
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 });
|
||||
if (!fastRet?.count || fastRet?.errcode !== 0 || !fastRet?.mems) {
|
||||
return []
|
||||
} else {
|
||||
for (const key in fastRet.mems) {
|
||||
MemberData.push(fastRet.mems[key])
|
||||
}
|
||||
const memberData: Array<WebApiGroupMember> = new Array<WebApiGroupMember>()
|
||||
const cookieObject = await NTQQUserApi.getCookies('qun.qq.com')
|
||||
const cookieStr = Object.entries(cookieObject).map(([key, value]) => `${key}=${value}`).join('; ')
|
||||
const retList: Promise<WebApiGroupMemberRet>[] = []
|
||||
const params = new URLSearchParams({
|
||||
st: '0',
|
||||
end: '40',
|
||||
sort: '1',
|
||||
gc: GroupCode,
|
||||
bkn: WebApi.genBkn(cookieObject.skey)
|
||||
})
|
||||
const fastRet = await RequestUtil.HttpGetJson<WebApiGroupMemberRet>(`https://qun.qq.com/cgi-bin/qun_mgr/search_group_members?${params}`, 'POST', '', { 'Cookie': cookieStr })
|
||||
if (!fastRet?.count || fastRet?.errcode !== 0 || !fastRet?.mems) {
|
||||
return []
|
||||
} else {
|
||||
for (const member of fastRet.mems) {
|
||||
memberData.push(member)
|
||||
}
|
||||
//初始化获取PageNum
|
||||
const PageNum = Math.ceil(fastRet.count / 40)
|
||||
//遍历批量请求
|
||||
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 });
|
||||
retList.push(ret)
|
||||
}
|
||||
//批量等待
|
||||
for (let i = 1; i <= PageNum; i++) {
|
||||
const ret = await (retList[i])
|
||||
if (!ret?.count || ret?.errcode !== 0 || !ret?.mems) {
|
||||
continue
|
||||
}
|
||||
for (const key in ret.mems) {
|
||||
MemberData.push(ret.mems[key])
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
return MemberData
|
||||
}
|
||||
return MemberData
|
||||
const pageNum = Math.ceil(fastRet.count / 40)
|
||||
//遍历批量请求
|
||||
for (let i = 2; i <= pageNum; i++) {
|
||||
params.set('st', String((i - 1) * 40))
|
||||
params.set('end', String(i * 40))
|
||||
const ret = RequestUtil.HttpGetJson<WebApiGroupMemberRet>(`https://qun.qq.com/cgi-bin/qun_mgr/search_group_members?${params}`, 'POST', '', { 'Cookie': cookieStr })
|
||||
retList.push(ret)
|
||||
}
|
||||
//批量等待
|
||||
for (let i = 1; i <= pageNum; i++) {
|
||||
const ret = await (retList[i])
|
||||
if (!ret?.count || ret?.errcode !== 0 || !ret?.mems) {
|
||||
continue
|
||||
}
|
||||
for (const member of ret.mems) {
|
||||
memberData.push(member)
|
||||
}
|
||||
}
|
||||
return memberData
|
||||
}
|
||||
|
||||
// public static 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 res = await this.request(url);
|
||||
|
@ -10,7 +10,7 @@ export class OB11Response {
|
||||
data: data,
|
||||
message: message,
|
||||
wording: message,
|
||||
echo: null,
|
||||
echo: undefined,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,33 +1,45 @@
|
||||
import { OB11GroupMember } from '../../types'
|
||||
import { getGroupMember } from '../../../common/data'
|
||||
import { getGroupMember, getSelfUid } from '@/common/data'
|
||||
import { OB11Constructor } from '../../constructor'
|
||||
import BaseAction from '../BaseAction'
|
||||
import { ActionName } from '../types'
|
||||
import { NTQQUserApi } from '../../../ntqqapi/api/user'
|
||||
import { NTQQUserApi, WebApi } from '@/ntqqapi/api'
|
||||
import { isNull } from '@/common/utils/helper'
|
||||
import { log } from '../../../common/utils/log'
|
||||
import { isNull } from '../../../common/utils/helper'
|
||||
|
||||
export interface PayloadType {
|
||||
group_id: number
|
||||
user_id: number
|
||||
interface Payload {
|
||||
group_id: number | string
|
||||
user_id: number | string
|
||||
}
|
||||
|
||||
class GetGroupMemberInfo extends BaseAction<PayloadType, OB11GroupMember> {
|
||||
class GetGroupMemberInfo extends BaseAction<Payload, OB11GroupMember> {
|
||||
actionName = ActionName.GetGroupMemberInfo
|
||||
|
||||
protected async _handle(payload: PayloadType) {
|
||||
protected async _handle(payload: Payload) {
|
||||
const member = await getGroupMember(payload.group_id.toString(), payload.user_id.toString())
|
||||
if (member) {
|
||||
if (isNull(member.sex)) {
|
||||
log('获取群成员详细信息')
|
||||
let info = await NTQQUserApi.getUserDetailInfo(member.uid, true)
|
||||
log('群成员详细信息结果', info)
|
||||
//log('获取群成员详细信息')
|
||||
const info = await NTQQUserApi.getUserDetailInfo(member.uid, true)
|
||||
//log('群成员详细信息结果', info)
|
||||
Object.assign(member, info)
|
||||
}
|
||||
const ret = OB11Constructor.groupMember(payload.group_id.toString(), member)
|
||||
const self = await getGroupMember(payload.group_id.toString(), getSelfUid())
|
||||
if (self?.role === 3 || self?.role === 4) {
|
||||
const webGroupMembers = await WebApi.getGroupMembers(payload.group_id.toString())
|
||||
const target = webGroupMembers.find(e => e?.uin && e.uin === ret.user_id)
|
||||
log(target)
|
||||
if (target) {
|
||||
ret.join_time = target.join_time
|
||||
ret.last_sent_time = target.last_speak_time
|
||||
ret.qage = target.qage
|
||||
ret.level = target.lv.level.toString()
|
||||
}
|
||||
}
|
||||
const date = Math.round(Date.now() / 1000)
|
||||
ret.last_sent_time = Number(member.lastSpeakTime || date)
|
||||
ret.join_time = Number(member.joinTime || date)
|
||||
ret.last_sent_time ||= Number(member.lastSpeakTime || date)
|
||||
ret.join_time ||= Number(member.joinTime || date)
|
||||
return ret
|
||||
} else {
|
||||
throw `群成员${payload.user_id}不存在`
|
||||
|
@ -289,12 +289,12 @@ export async function sendMsg(
|
||||
log('文件大小计算失败', e, fileElement)
|
||||
}
|
||||
}
|
||||
log('发送消息总大小', totalSize, 'bytes')
|
||||
let timeout = ((totalSize / 1024 / 100) * 1000) + 5000 // 100kb/s
|
||||
log('设置消息超时时间', timeout)
|
||||
//log('发送消息总大小', totalSize, 'bytes')
|
||||
const timeout = 10000 + (totalSize / 1024 / 256 * 1000) // 10s Basic Timeout + PredictTime( For File 512kb/s )
|
||||
//log('设置消息超时时间', timeout)
|
||||
const returnMsg = await NTQQMsgApi.sendMsg(peer, sendElements, waitComplete, timeout)
|
||||
log('消息发送结果', returnMsg)
|
||||
returnMsg.msgShortId = MessageUnique.createMsg(peer, returnMsg.msgId)
|
||||
log('消息发送', returnMsg.msgShortId)
|
||||
deleteAfterSentFiles.map(path => fsPromise.unlink(path))
|
||||
return returnMsg
|
||||
}
|
||||
|
@ -61,13 +61,15 @@ export function postOb11Event(msg: PostEventType, reportSelf = false, postWs = t
|
||||
body: msgStr,
|
||||
}).then(
|
||||
async (res) => {
|
||||
log(`新消息事件HTTP上报成功: ${host} `, msgStr)
|
||||
if (msg.post_type) {
|
||||
log(`HTTP 事件上报: ${host} `, msg.post_type)
|
||||
}
|
||||
try {
|
||||
const resJson = await res.json()
|
||||
log(`新消息事件HTTP上报返回快速操作: `, JSON.stringify(resJson))
|
||||
handleQuickOperation(msg as QuickOperationEvent, resJson).then().catch(log);
|
||||
} catch (e) {
|
||||
log(`新消息事件HTTP上报没有返回快速操作,不需要处理`)
|
||||
//log(`新消息事件HTTP上报没有返回快速操作,不需要处理`)
|
||||
return
|
||||
}
|
||||
},
|
||||
|
@ -1,18 +1,15 @@
|
||||
import { WebSocket as WebSocketClass } from 'ws'
|
||||
import { OB11Response } from '../../action/OB11Response'
|
||||
import { PostEventType } from '../post-ob11-event'
|
||||
import { log } from '../../../common/utils/log'
|
||||
import { isNull } from '../../../common/utils/helper'
|
||||
import { log } from '@/common/utils/log'
|
||||
import { OB11Return } from '../../types'
|
||||
|
||||
export function wsReply(wsClient: WebSocketClass, data: OB11Response | PostEventType) {
|
||||
export function wsReply(wsClient: WebSocketClass, data: OB11Return<any> | PostEventType) {
|
||||
try {
|
||||
const packet = Object.assign({}, data)
|
||||
if (isNull(packet['echo'])) {
|
||||
delete packet['echo']
|
||||
wsClient.send(JSON.stringify(data))
|
||||
if (data['post_type']) {
|
||||
log('WebSocket 事件上报', wsClient.url ?? '', data['post_type'])
|
||||
}
|
||||
wsClient.send(JSON.stringify(packet))
|
||||
//log('ws 消息上报', wsClient.url || '', data)
|
||||
} catch (e: any) {
|
||||
log('websocket 回复失败', e.stack, data)
|
||||
log('WebSocket 上报失败', e.stack, data)
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user