mirror of
https://github.com/LLOneBot/LLOneBot.git
synced 2024-11-22 01:56:33 +00:00
feat: .handle_quick_operation of websocket
This commit is contained in:
parent
9d2e9786cc
commit
d4427cfff4
@ -38,7 +38,7 @@ import {
|
|||||||
import { httpHeart, ob11HTTPServer } from '../onebot11/server/http'
|
import { httpHeart, ob11HTTPServer } from '../onebot11/server/http'
|
||||||
import { OB11FriendRecallNoticeEvent } from '../onebot11/event/notice/OB11FriendRecallNoticeEvent'
|
import { OB11FriendRecallNoticeEvent } from '../onebot11/event/notice/OB11FriendRecallNoticeEvent'
|
||||||
import { OB11GroupRecallNoticeEvent } from '../onebot11/event/notice/OB11GroupRecallNoticeEvent'
|
import { OB11GroupRecallNoticeEvent } from '../onebot11/event/notice/OB11GroupRecallNoticeEvent'
|
||||||
import { postOB11Event } from '../onebot11/server/postOB11Event'
|
import { postOb11Event } from '../onebot11/server/post-ob11-event'
|
||||||
import { ob11ReverseWebsockets } from '../onebot11/server/ws/ReverseWebsocket'
|
import { ob11ReverseWebsockets } from '../onebot11/server/ws/ReverseWebsocket'
|
||||||
import { OB11GroupAdminNoticeEvent } from '../onebot11/event/notice/OB11GroupAdminNoticeEvent'
|
import { OB11GroupAdminNoticeEvent } from '../onebot11/event/notice/OB11GroupAdminNoticeEvent'
|
||||||
import { OB11GroupRequestEvent } from '../onebot11/event/request/OB11GroupRequest'
|
import { OB11GroupRequestEvent } from '../onebot11/event/request/OB11GroupRequest'
|
||||||
@ -183,20 +183,20 @@ function onLoad() {
|
|||||||
if (isSelfMsg) {
|
if (isSelfMsg) {
|
||||||
msg.target_id = parseInt(message.peerUin)
|
msg.target_id = parseInt(message.peerUin)
|
||||||
}
|
}
|
||||||
postOB11Event(msg)
|
postOb11Event(msg)
|
||||||
// log("post msg", msg)
|
// log("post msg", msg)
|
||||||
})
|
})
|
||||||
.catch((e) => log('constructMessage error: ', e.stack.toString()))
|
.catch((e) => log('constructMessage error: ', e.stack.toString()))
|
||||||
OB11Constructor.GroupEvent(message).then((groupEvent) => {
|
OB11Constructor.GroupEvent(message).then((groupEvent) => {
|
||||||
if (groupEvent) {
|
if (groupEvent) {
|
||||||
// log("post group event", groupEvent);
|
// log("post group event", groupEvent);
|
||||||
postOB11Event(groupEvent)
|
postOb11Event(groupEvent)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
OB11Constructor.FriendAddEvent(message).then((friendAddEvent) => {
|
OB11Constructor.FriendAddEvent(message).then((friendAddEvent) => {
|
||||||
if (friendAddEvent) {
|
if (friendAddEvent) {
|
||||||
// log("post friend add event", friendAddEvent);
|
// log("post friend add event", friendAddEvent);
|
||||||
postOB11Event(friendAddEvent)
|
postOb11Event(friendAddEvent)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -213,7 +213,7 @@ function onLoad() {
|
|||||||
} else {
|
} else {
|
||||||
pokeEvent = new OB11FriendPokeEvent(parseInt(id))
|
pokeEvent = new OB11FriendPokeEvent(parseInt(id))
|
||||||
}
|
}
|
||||||
postOB11Event(pokeEvent)
|
postOb11Event(pokeEvent)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
registerReceiveHook<{
|
registerReceiveHook<{
|
||||||
@ -244,7 +244,7 @@ function onLoad() {
|
|||||||
OB11Constructor.RecallEvent(message).then((recallEvent) => {
|
OB11Constructor.RecallEvent(message).then((recallEvent) => {
|
||||||
if (recallEvent) {
|
if (recallEvent) {
|
||||||
log('post recall event', recallEvent)
|
log('post recall event', recallEvent)
|
||||||
postOB11Event(recallEvent)
|
postOb11Event(recallEvent)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
// 不让入库覆盖原来消息,不然就获取不到撤回的消息内容了
|
// 不让入库覆盖原来消息,不然就获取不到撤回的消息内容了
|
||||||
@ -322,7 +322,7 @@ function onLoad() {
|
|||||||
? 'unset'
|
? 'unset'
|
||||||
: 'set'
|
: 'set'
|
||||||
// member1.role = notify.type == GroupNotifyTypes.ADMIN_SET ? GroupMemberRole.admin : GroupMemberRole.normal;
|
// member1.role = notify.type == GroupNotifyTypes.ADMIN_SET ? GroupMemberRole.admin : GroupMemberRole.normal;
|
||||||
postOB11Event(groupAdminNoticeEvent, true)
|
postOb11Event(groupAdminNoticeEvent, true)
|
||||||
} else {
|
} else {
|
||||||
log('获取群通知的成员信息失败', notify, getGroup(notify.group.groupCode))
|
log('获取群通知的成员信息失败', notify, getGroup(notify.group.groupCode))
|
||||||
}
|
}
|
||||||
@ -344,7 +344,7 @@ function onLoad() {
|
|||||||
parseInt(operatorId),
|
parseInt(operatorId),
|
||||||
subType,
|
subType,
|
||||||
)
|
)
|
||||||
postOB11Event(groupDecreaseEvent, true)
|
postOb11Event(groupDecreaseEvent, true)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
log('获取群通知的成员信息失败', notify, e.stack.toString())
|
log('获取群通知的成员信息失败', notify, e.stack.toString())
|
||||||
}
|
}
|
||||||
@ -362,7 +362,7 @@ function onLoad() {
|
|||||||
groupRequestEvent.sub_type = 'add'
|
groupRequestEvent.sub_type = 'add'
|
||||||
groupRequestEvent.comment = notify.postscript
|
groupRequestEvent.comment = notify.postscript
|
||||||
groupRequestEvent.flag = notify.seq
|
groupRequestEvent.flag = notify.seq
|
||||||
postOB11Event(groupRequestEvent)
|
postOb11Event(groupRequestEvent)
|
||||||
} else if (notify.type == GroupNotifyTypes.INVITE_ME) {
|
} else if (notify.type == GroupNotifyTypes.INVITE_ME) {
|
||||||
log('收到邀请我加群通知')
|
log('收到邀请我加群通知')
|
||||||
let groupInviteEvent = new OB11GroupRequestEvent()
|
let groupInviteEvent = new OB11GroupRequestEvent()
|
||||||
@ -374,7 +374,7 @@ function onLoad() {
|
|||||||
groupInviteEvent.user_id = parseInt(user_id)
|
groupInviteEvent.user_id = parseInt(user_id)
|
||||||
groupInviteEvent.sub_type = 'invite'
|
groupInviteEvent.sub_type = 'invite'
|
||||||
groupInviteEvent.flag = notify.seq
|
groupInviteEvent.flag = notify.seq
|
||||||
postOB11Event(groupInviteEvent)
|
postOb11Event(groupInviteEvent)
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
log('解析群通知失败', e.stack.toString())
|
log('解析群通知失败', e.stack.toString())
|
||||||
@ -400,7 +400,7 @@ function onLoad() {
|
|||||||
}
|
}
|
||||||
friendRequestEvent.flag = flag
|
friendRequestEvent.flag = flag
|
||||||
friendRequestEvent.comment = req.extWords
|
friendRequestEvent.comment = req.extWords
|
||||||
postOB11Event(friendRequestEvent)
|
postOb11Event(friendRequestEvent)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -76,6 +76,9 @@ export class SendMsgElementConstructor {
|
|||||||
if (fileSize === 0) {
|
if (fileSize === 0) {
|
||||||
throw '文件异常,大小为0'
|
throw '文件异常,大小为0'
|
||||||
}
|
}
|
||||||
|
if (fileSize > 1000 * 1000 * 7){ // todo: 没有采用1024计算,因为具体上限数值未知,大概是7MB
|
||||||
|
throw `图片过大,最大支持7MB,当前文件大小${fileSize}B`
|
||||||
|
}
|
||||||
const imageSize = await NTQQFileApi.getImageSize(picPath)
|
const imageSize = await NTQQFileApi.getImageSize(picPath)
|
||||||
const picElement = {
|
const picElement = {
|
||||||
md5HexStr: md5,
|
md5HexStr: md5,
|
||||||
@ -131,6 +134,9 @@ export class SendMsgElementConstructor {
|
|||||||
if (fileSize === 0) {
|
if (fileSize === 0) {
|
||||||
throw '文件异常,大小为0'
|
throw '文件异常,大小为0'
|
||||||
}
|
}
|
||||||
|
if (fileSize > 1000 * 1000 * 100) { // todo: 没有采用1024计算,因为具体上限数值未知,大概是100MB
|
||||||
|
throw `视频过大,最大支持100MB,当前文件大小${fileSize}B`
|
||||||
|
}
|
||||||
const pathLib = require('path')
|
const pathLib = require('path')
|
||||||
let thumbDir = path.replace(`${pathLib.sep}Ori${pathLib.sep}`, `${pathLib.sep}Thumb${pathLib.sep}`)
|
let thumbDir = path.replace(`${pathLib.sep}Ori${pathLib.sep}`, `${pathLib.sep}Thumb${pathLib.sep}`)
|
||||||
thumbDir = pathLib.dirname(thumbDir)
|
thumbDir = pathLib.dirname(thumbDir)
|
||||||
|
@ -14,7 +14,7 @@ import {
|
|||||||
} from '../common/data'
|
} from '../common/data'
|
||||||
import { OB11GroupDecreaseEvent } from '../onebot11/event/notice/OB11GroupDecreaseEvent'
|
import { OB11GroupDecreaseEvent } from '../onebot11/event/notice/OB11GroupDecreaseEvent'
|
||||||
import { v4 as uuidv4 } from 'uuid'
|
import { v4 as uuidv4 } from 'uuid'
|
||||||
import { postOB11Event } from '../onebot11/server/postOB11Event'
|
import { postOb11Event } from '../onebot11/server/post-ob11-event'
|
||||||
import { getConfigUtil, HOOK_LOG } from '../common/config'
|
import { getConfigUtil, HOOK_LOG } from '../common/config'
|
||||||
import fs from 'fs'
|
import fs from 'fs'
|
||||||
import { dbUtil } from '../common/db'
|
import { dbUtil } from '../common/db'
|
||||||
@ -299,7 +299,7 @@ async function processGroupEvent(payload: { groupList: Group[] }) {
|
|||||||
}
|
}
|
||||||
for (const member of oldMembers) {
|
for (const member of oldMembers) {
|
||||||
if (!newMembersSet.has(member.uin) && member.uin != selfInfo.uin) {
|
if (!newMembersSet.has(member.uin) && member.uin != selfInfo.uin) {
|
||||||
postOB11Event(
|
postOb11Event(
|
||||||
new OB11GroupDecreaseEvent(
|
new OB11GroupDecreaseEvent(
|
||||||
parseInt(group.groupCode),
|
parseInt(group.groupCode),
|
||||||
parseInt(member.uin),
|
parseInt(member.uin),
|
||||||
@ -497,7 +497,7 @@ registerReceiveHook<{
|
|||||||
let lastTempMsg = msgList.pop()
|
let lastTempMsg = msgList.pop()
|
||||||
log('激活窗口之前的第一条临时会话消息:', lastTempMsg)
|
log('激活窗口之前的第一条临时会话消息:', lastTempMsg)
|
||||||
if (Date.now() / 1000 - parseInt(lastTempMsg.msgTime) < 5) {
|
if (Date.now() / 1000 - parseInt(lastTempMsg.msgTime) < 5) {
|
||||||
OB11Constructor.message(lastTempMsg).then((r) => postOB11Event(r))
|
OB11Constructor.message(lastTempMsg).then((r) => postOb11Event(r))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
17
src/onebot11/action/go-cqhttp/QuickOperation.ts
Normal file
17
src/onebot11/action/go-cqhttp/QuickOperation.ts
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
import BaseAction from '../BaseAction'
|
||||||
|
import { handleQuickOperation, QuickOperation, QuickOperationEvent } from '../../server/quick-operation'
|
||||||
|
import { log } from '@/common/utils'
|
||||||
|
import { ActionName } from '../types'
|
||||||
|
|
||||||
|
interface Payload{
|
||||||
|
context: QuickOperationEvent,
|
||||||
|
operation: QuickOperation
|
||||||
|
}
|
||||||
|
|
||||||
|
export class GoCQHTTHandleQuickOperation extends BaseAction<Payload, null>{
|
||||||
|
actionName = ActionName.GoCQHTTP_HandleQuickOperation
|
||||||
|
protected async _handle(payload: Payload): Promise<null> {
|
||||||
|
handleQuickOperation(payload.context, payload.operation).then().catch(log);
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
@ -49,6 +49,7 @@ import { SetMsgEmojiLike } from './msg/SetMsgEmojiLike'
|
|||||||
import { ForwardFriendSingleMsg, ForwardSingleGroupMsg } from './msg/ForwardSingleMsg'
|
import { ForwardFriendSingleMsg, ForwardSingleGroupMsg } from './msg/ForwardSingleMsg'
|
||||||
import { GetGroupEssence } from './group/GetGroupEssence'
|
import { GetGroupEssence } from './group/GetGroupEssence'
|
||||||
import { GetGroupHonorInfo } from './group/GetGroupHonorInfo'
|
import { GetGroupHonorInfo } from './group/GetGroupHonorInfo'
|
||||||
|
import { GoCQHTTHandleQuickOperation } from './go-cqhttp/QuickOperation'
|
||||||
|
|
||||||
export const actionHandlers = [
|
export const actionHandlers = [
|
||||||
new GetFile(),
|
new GetFile(),
|
||||||
@ -104,6 +105,7 @@ export const actionHandlers = [
|
|||||||
new GoCQHTTPUploadPrivateFile(),
|
new GoCQHTTPUploadPrivateFile(),
|
||||||
new GoCQHTTPGetGroupMsgHistory(),
|
new GoCQHTTPGetGroupMsgHistory(),
|
||||||
new GoCQHTTGetForwardMsgAction(),
|
new GoCQHTTGetForwardMsgAction(),
|
||||||
|
new GoCQHTTHandleQuickOperation()
|
||||||
]
|
]
|
||||||
|
|
||||||
function initActionMap() {
|
function initActionMap() {
|
||||||
|
@ -67,5 +67,6 @@ export enum ActionName {
|
|||||||
GoCQHTTP_GetGroupMsgHistory = 'get_group_msg_history',
|
GoCQHTTP_GetGroupMsgHistory = 'get_group_msg_history',
|
||||||
GoCQHTTP_GetForwardMsg = 'get_forward_msg',
|
GoCQHTTP_GetForwardMsg = 'get_forward_msg',
|
||||||
GoCQHTTP_GetEssenceMsg = "get_essence_msg_list",
|
GoCQHTTP_GetEssenceMsg = "get_essence_msg_list",
|
||||||
|
GoCQHTTP_HandleQuickOperation = ".handle_quick_operation",
|
||||||
GetGroupHonorInfo = "get_group_honor_info",
|
GetGroupHonorInfo = "get_group_honor_info",
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@ import { OB11Response } from '../action/OB11Response'
|
|||||||
import { HttpServerBase } from '@/common/server/http'
|
import { HttpServerBase } from '@/common/server/http'
|
||||||
import { actionHandlers, actionMap } from '../action'
|
import { actionHandlers, actionMap } from '../action'
|
||||||
import { getConfigUtil } from '@/common/config'
|
import { getConfigUtil } from '@/common/config'
|
||||||
import { postOB11Event } from './postOB11Event'
|
import { postOb11Event } from './post-ob11-event'
|
||||||
import { OB11HeartbeatEvent } from '../event/meta/OB11HeartbeatEvent'
|
import { OB11HeartbeatEvent } from '../event/meta/OB11HeartbeatEvent'
|
||||||
import { selfInfo } from '@/common/data'
|
import { selfInfo } from '@/common/data'
|
||||||
|
|
||||||
@ -40,7 +40,7 @@ class HTTPHeart {
|
|||||||
}
|
}
|
||||||
this.intervalId = setInterval(() => {
|
this.intervalId = setInterval(() => {
|
||||||
// ws的心跳是ws自己维护的
|
// ws的心跳是ws自己维护的
|
||||||
postOB11Event(new OB11HeartbeatEvent(selfInfo.online, true, heartInterval), false, false)
|
postOb11Event(new OB11HeartbeatEvent(selfInfo.online, true, heartInterval), false, false)
|
||||||
}, heartInterval)
|
}, heartInterval)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
88
src/onebot11/server/post-ob11-event.ts
Normal file
88
src/onebot11/server/post-ob11-event.ts
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
import { OB11Message, OB11MessageAt, OB11MessageData } from '../types'
|
||||||
|
import { getFriend, getGroup, getUidByUin, selfInfo } from '../../common/data'
|
||||||
|
import { OB11BaseMetaEvent } from '../event/meta/OB11BaseMetaEvent'
|
||||||
|
import { OB11BaseNoticeEvent } from '../event/notice/OB11BaseNoticeEvent'
|
||||||
|
import { WebSocket as WebSocketClass } from 'ws'
|
||||||
|
import { wsReply } from './ws/reply'
|
||||||
|
import { log } from '../../common/utils/log'
|
||||||
|
import { getConfigUtil } from '../../common/config'
|
||||||
|
import crypto from 'crypto'
|
||||||
|
import { NTQQFriendApi, NTQQGroupApi, NTQQMsgApi, Peer } from '../../ntqqapi/api'
|
||||||
|
import { ChatType, Group, GroupRequestOperateTypes } from '../../ntqqapi/types'
|
||||||
|
import { convertMessage2List, createSendElements, sendMsg } from '../action/msg/SendMsg'
|
||||||
|
import { dbUtil } from '../../common/db'
|
||||||
|
import { OB11FriendRequestEvent } from '../event/request/OB11FriendRequest'
|
||||||
|
import { OB11GroupRequestEvent } from '../event/request/OB11GroupRequest'
|
||||||
|
import { isNull } from '../../common/utils'
|
||||||
|
import { handleQuickOperation, QuickOperationEvent } from './quick-operation'
|
||||||
|
|
||||||
|
export type PostEventType = OB11Message | OB11BaseMetaEvent | OB11BaseNoticeEvent
|
||||||
|
|
||||||
|
const eventWSList: WebSocketClass[] = []
|
||||||
|
|
||||||
|
export function registerWsEventSender(ws: WebSocketClass) {
|
||||||
|
eventWSList.push(ws)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function unregisterWsEventSender(ws: WebSocketClass) {
|
||||||
|
let index = eventWSList.indexOf(ws)
|
||||||
|
if (index !== -1) {
|
||||||
|
eventWSList.splice(index, 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function postWsEvent(event: PostEventType) {
|
||||||
|
for (const ws of eventWSList) {
|
||||||
|
new Promise(() => {
|
||||||
|
wsReply(ws, event)
|
||||||
|
}).then()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function postOb11Event(msg: PostEventType, reportSelf = false, postWs = true) {
|
||||||
|
const config = getConfigUtil().getConfig()
|
||||||
|
// 判断msg是否是event
|
||||||
|
if (!config.reportSelfMessage && !reportSelf) {
|
||||||
|
if (msg.post_type === 'message' && (msg as OB11Message).user_id.toString() == selfInfo.uin) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (config.ob11.enableHttpPost) {
|
||||||
|
const msgStr = JSON.stringify(msg)
|
||||||
|
const hmac = crypto.createHmac('sha1', config.ob11.httpSecret)
|
||||||
|
hmac.update(msgStr)
|
||||||
|
const sig = hmac.digest('hex')
|
||||||
|
let headers = {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'x-self-id': selfInfo.uin,
|
||||||
|
}
|
||||||
|
if (config.ob11.httpSecret) {
|
||||||
|
headers['x-signature'] = 'sha1=' + sig
|
||||||
|
}
|
||||||
|
for (const host of config.ob11.httpHosts) {
|
||||||
|
fetch(host, {
|
||||||
|
method: 'POST',
|
||||||
|
headers,
|
||||||
|
body: msgStr,
|
||||||
|
}).then(
|
||||||
|
async (res) => {
|
||||||
|
log(`新消息事件HTTP上报成功: ${host} `, msgStr)
|
||||||
|
try {
|
||||||
|
const resJson = await res.json()
|
||||||
|
log(`新消息事件HTTP上报返回快速操作: `, JSON.stringify(resJson))
|
||||||
|
handleQuickOperation(msg as QuickOperationEvent, resJson).then().catch(log);
|
||||||
|
} catch (e) {
|
||||||
|
log(`新消息事件HTTP上报没有返回快速操作,不需要处理`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
},
|
||||||
|
(err: any) => {
|
||||||
|
log(`新消息事件HTTP上报失败: ${host} `, err, msg)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (postWs) {
|
||||||
|
postWsEvent(msg)
|
||||||
|
}
|
||||||
|
}
|
@ -1,185 +0,0 @@
|
|||||||
import { OB11Message, OB11MessageAt, OB11MessageData } from '../types'
|
|
||||||
import { getFriend, getGroup, getUidByUin, selfInfo } from '../../common/data'
|
|
||||||
import { OB11BaseMetaEvent } from '../event/meta/OB11BaseMetaEvent'
|
|
||||||
import { OB11BaseNoticeEvent } from '../event/notice/OB11BaseNoticeEvent'
|
|
||||||
import { WebSocket as WebSocketClass } from 'ws'
|
|
||||||
import { wsReply } from './ws/reply'
|
|
||||||
import { log } from '../../common/utils/log'
|
|
||||||
import { getConfigUtil } from '../../common/config'
|
|
||||||
import crypto from 'crypto'
|
|
||||||
import { NTQQFriendApi, NTQQGroupApi, NTQQMsgApi, Peer } from '../../ntqqapi/api'
|
|
||||||
import { ChatType, Group, GroupRequestOperateTypes } from '../../ntqqapi/types'
|
|
||||||
import { convertMessage2List, createSendElements, sendMsg } from '../action/msg/SendMsg'
|
|
||||||
import { dbUtil } from '../../common/db'
|
|
||||||
import { OB11FriendRequestEvent } from '../event/request/OB11FriendRequest'
|
|
||||||
import { OB11GroupRequestEvent } from '../event/request/OB11GroupRequest'
|
|
||||||
import { isNull } from '../../common/utils'
|
|
||||||
|
|
||||||
export type PostEventType = OB11Message | OB11BaseMetaEvent | OB11BaseNoticeEvent
|
|
||||||
|
|
||||||
interface QuickActionPrivateMessage {
|
|
||||||
reply?: string
|
|
||||||
auto_escape?: boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
interface QuickActionGroupMessage extends QuickActionPrivateMessage {
|
|
||||||
// 回复群消息
|
|
||||||
at_sender?: boolean
|
|
||||||
delete?: boolean
|
|
||||||
kick?: boolean
|
|
||||||
ban?: boolean
|
|
||||||
ban_duration?: number
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
interface QuickActionFriendRequest {
|
|
||||||
approve?: boolean
|
|
||||||
remark?: string
|
|
||||||
}
|
|
||||||
|
|
||||||
interface QuickActionGroupRequest {
|
|
||||||
approve?: boolean
|
|
||||||
reason?: string
|
|
||||||
}
|
|
||||||
|
|
||||||
type QuickAction = QuickActionPrivateMessage &
|
|
||||||
QuickActionGroupMessage &
|
|
||||||
QuickActionFriendRequest &
|
|
||||||
QuickActionGroupRequest
|
|
||||||
|
|
||||||
const eventWSList: WebSocketClass[] = []
|
|
||||||
|
|
||||||
export function registerWsEventSender(ws: WebSocketClass) {
|
|
||||||
eventWSList.push(ws)
|
|
||||||
}
|
|
||||||
|
|
||||||
export function unregisterWsEventSender(ws: WebSocketClass) {
|
|
||||||
let index = eventWSList.indexOf(ws)
|
|
||||||
if (index !== -1) {
|
|
||||||
eventWSList.splice(index, 1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function postWsEvent(event: PostEventType) {
|
|
||||||
for (const ws of eventWSList) {
|
|
||||||
new Promise(() => {
|
|
||||||
wsReply(ws, event)
|
|
||||||
}).then()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function postOB11Event(msg: PostEventType, reportSelf = false, postWs = true) {
|
|
||||||
const config = getConfigUtil().getConfig()
|
|
||||||
// 判断msg是否是event
|
|
||||||
if (!config.reportSelfMessage && !reportSelf) {
|
|
||||||
if (msg.post_type === 'message' && (msg as OB11Message).user_id.toString() == selfInfo.uin) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (config.ob11.enableHttpPost) {
|
|
||||||
const msgStr = JSON.stringify(msg)
|
|
||||||
const hmac = crypto.createHmac('sha1', config.ob11.httpSecret)
|
|
||||||
hmac.update(msgStr)
|
|
||||||
const sig = hmac.digest('hex')
|
|
||||||
let headers = {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
'x-self-id': selfInfo.uin,
|
|
||||||
}
|
|
||||||
if (config.ob11.httpSecret) {
|
|
||||||
headers['x-signature'] = 'sha1=' + sig
|
|
||||||
}
|
|
||||||
for (const host of config.ob11.httpHosts) {
|
|
||||||
fetch(host, {
|
|
||||||
method: 'POST',
|
|
||||||
headers,
|
|
||||||
body: msgStr,
|
|
||||||
}).then(
|
|
||||||
async (res) => {
|
|
||||||
log(`新消息事件HTTP上报成功: ${host} `, msgStr)
|
|
||||||
// todo: 处理不够优雅,应该使用高级泛型进行QuickAction类型识别
|
|
||||||
let resJson: QuickAction
|
|
||||||
try {
|
|
||||||
resJson = await res.json()
|
|
||||||
log(`新消息事件HTTP上报返回快速操作: `, JSON.stringify(resJson))
|
|
||||||
} catch (e) {
|
|
||||||
log(`新消息事件HTTP上报没有返回快速操作,不需要处理`)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (msg.post_type === 'message') {
|
|
||||||
msg = msg as OB11Message
|
|
||||||
const rawMessage = await dbUtil.getMsgByShortId(msg.message_id)
|
|
||||||
resJson = resJson as QuickActionPrivateMessage | QuickActionGroupMessage
|
|
||||||
const reply = resJson.reply
|
|
||||||
let peer: Peer = {
|
|
||||||
chatType: ChatType.friend,
|
|
||||||
peerUid: msg.user_id.toString(),
|
|
||||||
}
|
|
||||||
if (msg.message_type == 'private') {
|
|
||||||
peer.peerUid = getUidByUin(msg.user_id.toString())
|
|
||||||
if (msg.sub_type === 'group') {
|
|
||||||
peer.chatType = ChatType.temp
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
peer.chatType = ChatType.group
|
|
||||||
peer.peerUid = msg.group_id.toString()
|
|
||||||
}
|
|
||||||
if (reply) {
|
|
||||||
let group: Group = null
|
|
||||||
let replyMessage: OB11MessageData[] = []
|
|
||||||
|
|
||||||
if (msg.message_type == 'group') {
|
|
||||||
group = await getGroup(msg.group_id.toString())
|
|
||||||
if ((resJson as QuickActionGroupMessage).at_sender) {
|
|
||||||
replyMessage.push({
|
|
||||||
type: 'at',
|
|
||||||
data: {
|
|
||||||
qq: msg.user_id.toString(),
|
|
||||||
},
|
|
||||||
} as OB11MessageAt)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
replyMessage = replyMessage.concat(convertMessage2List(reply, resJson.auto_escape))
|
|
||||||
const { sendElements, deleteAfterSentFiles } = await createSendElements(replyMessage, group)
|
|
||||||
log(`发送消息给`, peer, sendElements)
|
|
||||||
sendMsg(peer, sendElements, deleteAfterSentFiles, false).then()
|
|
||||||
} else if (resJson.delete) {
|
|
||||||
NTQQMsgApi.recallMsg(peer, [rawMessage.msgId]).then()
|
|
||||||
} else if (resJson.kick) {
|
|
||||||
NTQQGroupApi.kickMember(peer.peerUid, [rawMessage.senderUid]).then()
|
|
||||||
} else if (resJson.ban) {
|
|
||||||
NTQQGroupApi.banMember(peer.peerUid, [
|
|
||||||
{
|
|
||||||
uid: rawMessage.senderUid,
|
|
||||||
timeStamp: resJson.ban_duration || 60 * 30,
|
|
||||||
},
|
|
||||||
]).then()
|
|
||||||
}
|
|
||||||
} else if (msg.post_type === 'request') {
|
|
||||||
if ((msg as OB11FriendRequestEvent).request_type === 'friend') {
|
|
||||||
resJson = resJson as QuickActionFriendRequest
|
|
||||||
if (!isNull(resJson.approve)) {
|
|
||||||
// todo: set remark
|
|
||||||
NTQQFriendApi.handleFriendRequest((msg as OB11FriendRequestEvent).flag, resJson.approve).then()
|
|
||||||
}
|
|
||||||
} else if ((msg as OB11GroupRequestEvent).request_type === 'group') {
|
|
||||||
resJson = resJson as QuickActionGroupRequest
|
|
||||||
if (!isNull(resJson.approve)) {
|
|
||||||
NTQQGroupApi.handleGroupRequest(
|
|
||||||
(msg as OB11FriendRequestEvent).flag,
|
|
||||||
resJson.approve ? GroupRequestOperateTypes.approve : GroupRequestOperateTypes.reject,
|
|
||||||
resJson.reason,
|
|
||||||
).then()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
(err: any) => {
|
|
||||||
log(`新消息事件HTTP上报失败: ${host} `, err, msg)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (postWs) {
|
|
||||||
postWsEvent(msg)
|
|
||||||
}
|
|
||||||
}
|
|
139
src/onebot11/server/quick-operation.ts
Normal file
139
src/onebot11/server/quick-operation.ts
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
// handle quick action, create at 2024-5-18 10:54:39 by linyuchen
|
||||||
|
|
||||||
|
|
||||||
|
import { OB11Message, OB11MessageAt, OB11MessageData } from '../types'
|
||||||
|
import { OB11FriendRequestEvent } from '../event/request/OB11FriendRequest'
|
||||||
|
import { OB11GroupRequestEvent } from '../event/request/OB11GroupRequest'
|
||||||
|
import { dbUtil } from '@/common/db'
|
||||||
|
import { NTQQFriendApi, NTQQGroupApi, NTQQMsgApi, Peer } from '@/ntqqapi/api'
|
||||||
|
import { ChatType, Group, GroupRequestOperateTypes } from '@/ntqqapi/types'
|
||||||
|
import { getGroup, getUidByUin } from '@/common/data'
|
||||||
|
import { convertMessage2List, createSendElements, sendMsg } from '../action/msg/SendMsg'
|
||||||
|
import { isNull, log } from '@/common/utils'
|
||||||
|
|
||||||
|
|
||||||
|
interface QuickOperationPrivateMessage {
|
||||||
|
reply?: string
|
||||||
|
auto_escape?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
interface QuickOperationGroupMessage extends QuickOperationPrivateMessage {
|
||||||
|
// 回复群消息
|
||||||
|
at_sender?: boolean
|
||||||
|
delete?: boolean
|
||||||
|
kick?: boolean
|
||||||
|
ban?: boolean
|
||||||
|
ban_duration?: number
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
interface QuickOperationFriendRequest {
|
||||||
|
approve?: boolean
|
||||||
|
remark?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
interface QuickOperationGroupRequest {
|
||||||
|
approve?: boolean
|
||||||
|
reason?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type QuickOperation = QuickOperationPrivateMessage &
|
||||||
|
QuickOperationGroupMessage &
|
||||||
|
QuickOperationFriendRequest &
|
||||||
|
QuickOperationGroupRequest
|
||||||
|
|
||||||
|
export type QuickOperationEvent = OB11Message | OB11FriendRequestEvent | OB11GroupRequestEvent;
|
||||||
|
|
||||||
|
export async function handleQuickOperation(context: QuickOperationEvent, quickAction: QuickOperation) {
|
||||||
|
if (context.post_type === 'message') {
|
||||||
|
handleMsg(context as OB11Message, quickAction).then().catch(log)
|
||||||
|
}
|
||||||
|
if (context.post_type === 'request') {
|
||||||
|
const friendRequest = context as OB11FriendRequestEvent;
|
||||||
|
const groupRequest = context as OB11GroupRequestEvent;
|
||||||
|
if ((friendRequest).request_type === 'friend') {
|
||||||
|
handleFriendRequest(friendRequest, quickAction).then().catch(log)
|
||||||
|
}
|
||||||
|
else if (groupRequest.request_type === 'group') {
|
||||||
|
handleGroupRequest(groupRequest, quickAction).then().catch(log)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handleMsg(msg: OB11Message, quickAction: QuickOperationPrivateMessage | QuickOperationGroupMessage) {
|
||||||
|
msg = msg as OB11Message
|
||||||
|
const rawMessage = await dbUtil.getMsgByShortId(msg.message_id)
|
||||||
|
const reply = quickAction.reply
|
||||||
|
let peer: Peer = {
|
||||||
|
chatType: ChatType.friend,
|
||||||
|
peerUid: msg.user_id.toString(),
|
||||||
|
}
|
||||||
|
if (msg.message_type == 'private') {
|
||||||
|
peer.peerUid = getUidByUin(msg.user_id.toString())
|
||||||
|
if (msg.sub_type === 'group') {
|
||||||
|
peer.chatType = ChatType.temp
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
peer.chatType = ChatType.group
|
||||||
|
peer.peerUid = msg.group_id.toString()
|
||||||
|
}
|
||||||
|
if (reply) {
|
||||||
|
let group: Group = null
|
||||||
|
let replyMessage: OB11MessageData[] = []
|
||||||
|
|
||||||
|
if (msg.message_type == 'group') {
|
||||||
|
group = await getGroup(msg.group_id.toString())
|
||||||
|
if ((quickAction as QuickOperationGroupMessage).at_sender) {
|
||||||
|
replyMessage.push({
|
||||||
|
type: 'at',
|
||||||
|
data: {
|
||||||
|
qq: msg.user_id.toString(),
|
||||||
|
},
|
||||||
|
} as OB11MessageAt)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
replyMessage = replyMessage.concat(convertMessage2List(reply, quickAction.auto_escape))
|
||||||
|
const { sendElements, deleteAfterSentFiles } = await createSendElements(replyMessage, group)
|
||||||
|
log(`发送消息给`, peer, sendElements)
|
||||||
|
sendMsg(peer, sendElements, deleteAfterSentFiles, false).then().catch(log)
|
||||||
|
}
|
||||||
|
if (msg.message_type === 'group') {
|
||||||
|
const groupMsgQuickAction = quickAction as QuickOperationGroupMessage
|
||||||
|
// handle group msg
|
||||||
|
if (groupMsgQuickAction.delete) {
|
||||||
|
NTQQMsgApi.recallMsg(peer, [rawMessage.msgId]).then().catch(log)
|
||||||
|
}
|
||||||
|
if (groupMsgQuickAction.kick) {
|
||||||
|
NTQQGroupApi.kickMember(peer.peerUid, [rawMessage.senderUid]).then().catch(log)
|
||||||
|
}
|
||||||
|
if (groupMsgQuickAction.ban) {
|
||||||
|
NTQQGroupApi.banMember(peer.peerUid, [
|
||||||
|
{
|
||||||
|
uid: rawMessage.senderUid,
|
||||||
|
timeStamp: groupMsgQuickAction.ban_duration || 60 * 30,
|
||||||
|
},
|
||||||
|
]).then().catch(log)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handleFriendRequest(request: OB11FriendRequestEvent,
|
||||||
|
quickAction: QuickOperationFriendRequest) {
|
||||||
|
if (!isNull(quickAction.approve)) {
|
||||||
|
// todo: set remark
|
||||||
|
NTQQFriendApi.handleFriendRequest(request.flag, quickAction.approve).then().catch(log)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async function handleGroupRequest(request: OB11GroupRequestEvent,
|
||||||
|
quickAction: QuickOperationGroupRequest) {
|
||||||
|
if (!isNull(quickAction.approve)) {
|
||||||
|
NTQQGroupApi.handleGroupRequest(
|
||||||
|
request.flag,
|
||||||
|
quickAction.approve ? GroupRequestOperateTypes.approve : GroupRequestOperateTypes.reject,
|
||||||
|
quickAction.reason,
|
||||||
|
).then().catch(log)
|
||||||
|
}
|
||||||
|
}
|
@ -4,7 +4,7 @@ import { ActionName } from '../../action/types'
|
|||||||
import { OB11Response } from '../../action/OB11Response'
|
import { OB11Response } from '../../action/OB11Response'
|
||||||
import BaseAction from '../../action/BaseAction'
|
import BaseAction from '../../action/BaseAction'
|
||||||
import { actionMap } from '../../action'
|
import { actionMap } from '../../action'
|
||||||
import { postWsEvent, registerWsEventSender, unregisterWsEventSender } from '../postOB11Event'
|
import { postWsEvent, registerWsEventSender, unregisterWsEventSender } from '../post-ob11-event'
|
||||||
import { wsReply } from './reply'
|
import { wsReply } from './reply'
|
||||||
import { WebSocket as WebSocketClass } from 'ws'
|
import { WebSocket as WebSocketClass } from 'ws'
|
||||||
import { OB11HeartbeatEvent } from '../../event/meta/OB11HeartbeatEvent'
|
import { OB11HeartbeatEvent } from '../../event/meta/OB11HeartbeatEvent'
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { WebSocket } from 'ws'
|
import { WebSocket } from 'ws'
|
||||||
import { actionMap } from '../../action'
|
import { actionMap } from '../../action'
|
||||||
import { OB11Response } from '../../action/OB11Response'
|
import { OB11Response } from '../../action/OB11Response'
|
||||||
import { postWsEvent, registerWsEventSender, unregisterWsEventSender } from '../postOB11Event'
|
import { postWsEvent, registerWsEventSender, unregisterWsEventSender } from '../post-ob11-event'
|
||||||
import { ActionName } from '../../action/types'
|
import { ActionName } from '../../action/types'
|
||||||
import BaseAction from '../../action/BaseAction'
|
import BaseAction from '../../action/BaseAction'
|
||||||
import { LifeCycleSubType, OB11LifeCycleEvent } from '../../event/meta/OB11LifeCycleEvent'
|
import { LifeCycleSubType, OB11LifeCycleEvent } from '../../event/meta/OB11LifeCycleEvent'
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { WebSocket as WebSocketClass } from 'ws'
|
import { WebSocket as WebSocketClass } from 'ws'
|
||||||
import { OB11Response } from '../../action/OB11Response'
|
import { OB11Response } from '../../action/OB11Response'
|
||||||
import { PostEventType } from '../postOB11Event'
|
import { PostEventType } from '../post-ob11-event'
|
||||||
import { log } from '../../../common/utils/log'
|
import { log } from '../../../common/utils/log'
|
||||||
import { isNull } from '../../../common/utils/helper'
|
import { isNull } from '../../../common/utils/helper'
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user