mirror of
https://github.com/LLOneBot/LLOneBot.git
synced 2024-11-22 01:56:33 +00:00

fix: ignore post history msg before login fix: quit group not sync to groups of data feat: support post url params feat: support port http heart
178 lines
7.3 KiB
TypeScript
178 lines
7.3 KiB
TypeScript
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);
|
||
}
|
||
} |