diff --git a/src/ntqqapi/hook.ts b/src/ntqqapi/hook.ts
index 9b32d23..6cd3f2f 100644
--- a/src/ntqqapi/hook.ts
+++ b/src/ntqqapi/hook.ts
@@ -1,8 +1,8 @@
 import {BrowserWindow} from 'electron';
-import {NTQQApiClass} from "./ntcall";
+import {NTQQApiClass, NTQQApiMethod} from "./ntcall";
 import {NTQQMsgApi, sendMessagePool} from "./api/msg"
 import {ChatType, Group, GroupMember, GroupMemberRole, RawMessage, User} from "./types";
-import {friends, getGroupMember, groups, selfInfo, tempGroupCodeMap, uidMaps} from "../common/data";
+import {friends, getFriend, getGroupMember, groups, selfInfo, tempGroupCodeMap, uidMaps} from "../common/data";
 import {OB11GroupDecreaseEvent} from "../onebot11/event/notice/OB11GroupDecreaseEvent";
 import {v4 as uuidv4} from "uuid"
 import {postOB11Event} from "../onebot11/server/postOB11Event";
@@ -11,446 +11,503 @@ import fs from "fs";
 import {dbUtil} from "../common/db";
 import {NTQQGroupApi} from "./api/group";
 import {log} from "../common/utils/log";
-import {sleep} from "../common/utils/helper";
+import {isNumeric, sleep} from "../common/utils/helper";
 import {OB11Constructor} from "../onebot11/constructor";
 
 export let hookApiCallbacks: Record<string, (apiReturn: any) => void> = {}
 
 export let ReceiveCmdS = {
-    RECENT_CONTACT: "nodeIKernelRecentContactListener/onRecentContactListChangedVer2",
-    UPDATE_MSG: "nodeIKernelMsgListener/onMsgInfoListUpdate",
-    UPDATE_ACTIVE_MSG: "nodeIKernelMsgListener/onActiveMsgInfoUpdate",
-    NEW_MSG: `nodeIKernelMsgListener/onRecvMsg`,
-    NEW_ACTIVE_MSG: `nodeIKernelMsgListener/onRecvActiveMsg`,
-    SELF_SEND_MSG: "nodeIKernelMsgListener/onAddSendMsg",
-    USER_INFO: "nodeIKernelProfileListener/onProfileSimpleChanged",
-    USER_DETAIL_INFO: "nodeIKernelProfileListener/onProfileDetailInfoChanged",
-    GROUPS: "nodeIKernelGroupListener/onGroupListUpdate",
-    GROUPS_STORE: "onGroupListUpdate",
-    GROUP_MEMBER_INFO_UPDATE: "nodeIKernelGroupListener/onMemberInfoChange",
-    FRIENDS: "onBuddyListChange",
-    MEDIA_DOWNLOAD_COMPLETE: "nodeIKernelMsgListener/onRichMediaDownloadComplete",
-    UNREAD_GROUP_NOTIFY: "nodeIKernelGroupListener/onGroupNotifiesUnreadCountUpdated",
-    GROUP_NOTIFY: "nodeIKernelGroupListener/onGroupSingleScreenNotifies",
-    FRIEND_REQUEST: "nodeIKernelBuddyListener/onBuddyReqChange",
-    SELF_STATUS: 'nodeIKernelProfileListener/onSelfStatusChanged',
-    CACHE_SCAN_FINISH: "nodeIKernelStorageCleanListener/onFinishScan",
-    MEDIA_UPLOAD_COMPLETE: "nodeIKernelMsgListener/onRichMediaUploadComplete",
-    SKEY_UPDATE: "onSkeyUpdate"
+  RECENT_CONTACT: "nodeIKernelRecentContactListener/onRecentContactListChangedVer2",
+  UPDATE_MSG: "nodeIKernelMsgListener/onMsgInfoListUpdate",
+  UPDATE_ACTIVE_MSG: "nodeIKernelMsgListener/onActiveMsgInfoUpdate",
+  NEW_MSG: `nodeIKernelMsgListener/onRecvMsg`,
+  NEW_ACTIVE_MSG: `nodeIKernelMsgListener/onRecvActiveMsg`,
+  SELF_SEND_MSG: "nodeIKernelMsgListener/onAddSendMsg",
+  USER_INFO: "nodeIKernelProfileListener/onProfileSimpleChanged",
+  USER_DETAIL_INFO: "nodeIKernelProfileListener/onProfileDetailInfoChanged",
+  GROUPS: "nodeIKernelGroupListener/onGroupListUpdate",
+  GROUPS_STORE: "onGroupListUpdate",
+  GROUP_MEMBER_INFO_UPDATE: "nodeIKernelGroupListener/onMemberInfoChange",
+  FRIENDS: "onBuddyListChange",
+  MEDIA_DOWNLOAD_COMPLETE: "nodeIKernelMsgListener/onRichMediaDownloadComplete",
+  UNREAD_GROUP_NOTIFY: "nodeIKernelGroupListener/onGroupNotifiesUnreadCountUpdated",
+  GROUP_NOTIFY: "nodeIKernelGroupListener/onGroupSingleScreenNotifies",
+  FRIEND_REQUEST: "nodeIKernelBuddyListener/onBuddyReqChange",
+  SELF_STATUS: 'nodeIKernelProfileListener/onSelfStatusChanged',
+  CACHE_SCAN_FINISH: "nodeIKernelStorageCleanListener/onFinishScan",
+  MEDIA_UPLOAD_COMPLETE: "nodeIKernelMsgListener/onRichMediaUploadComplete",
+  SKEY_UPDATE: "onSkeyUpdate"
 }
 
 export type ReceiveCmd = typeof ReceiveCmdS[keyof typeof ReceiveCmdS]
 
 interface NTQQApiReturnData<PayloadType = unknown> extends Array<any> {
-    0: {
-        "type": "request",
-        "eventName": NTQQApiClass,
-        "callbackId"?: string
-    },
-    1:
-        {
-            cmdName: ReceiveCmd,
-            cmdType: "event",
-            payload: PayloadType
-        }[]
+  0: {
+    "type": "request",
+    "eventName": NTQQApiClass,
+    "callbackId"?: string
+  },
+  1:
+    {
+      cmdName: ReceiveCmd,
+      cmdType: "event",
+      payload: PayloadType
+    }[]
 }
 
 let receiveHooks: Array<{
-    method: ReceiveCmd[],
-    hookFunc: ((payload: any) => void | Promise<void>)
-    id: string
+  method: ReceiveCmd[],
+  hookFunc: ((payload: any) => void | Promise<void>)
+  id: string
 }> = []
 
-export function hookNTQQApiReceive(window: BrowserWindow) {
-    const originalSend = window.webContents.send;
-    const patchSend = (channel: string, ...args: NTQQApiReturnData) => {
-        // console.log("hookNTQQApiReceive", channel, args)
-        let isLogger = false
-        try {
-            isLogger = args[0]?.eventName?.startsWith("ns-LoggerApi")
-        } catch (e) {
+let callHooks: Array<{
+  method: NTQQApiMethod[],
+  hookFunc: ((callParams: unknown[]) => void | Promise<void>)
+}> = []
+
+
+export function hookNTQQApiReceive(window: BrowserWindow) {
+  const originalSend = window.webContents.send;
+  const patchSend = (channel: string, ...args: NTQQApiReturnData) => {
+    // console.log("hookNTQQApiReceive", channel, args)
+    let isLogger = false
+    try {
+      isLogger = args[0]?.eventName?.startsWith("ns-LoggerApi")
+    } catch (e) {
 
-        }
-        if (!isLogger) {
-            try {
-                HOOK_LOG && log(`received ntqq api message: ${channel}`, args)
-            } catch (e) {
-                log("hook log error", e, args)
-            }
-        }
-        try {
-            if (args?.[1] instanceof Array) {
-                for (let receiveData of args?.[1]) {
-                    const ntQQApiMethodName = receiveData.cmdName;
-                    // log(`received ntqq api message: ${channel} ${ntQQApiMethodName}`, JSON.stringify(receiveData))
-                    for (let hook of receiveHooks) {
-                        if (hook.method.includes(ntQQApiMethodName)) {
-                            new Promise((resolve, reject) => {
-                                try {
-                                    let _ = hook.hookFunc(receiveData.payload)
-                                    if (hook.hookFunc.constructor.name === "AsyncFunction") {
-                                        (_ as Promise<void>).then()
-                                    }
-                                } catch (e) {
-                                    log("hook error", e, receiveData.payload)
-                                }
-                            }).then()
-                        }
-                    }
-                }
-            }
-            if (args[0]?.callbackId) {
-                // log("hookApiCallback", hookApiCallbacks, args)
-                const callbackId = args[0].callbackId;
-                if (hookApiCallbacks[callbackId]) {
-                    // log("callback found")
-                    new Promise((resolve, reject) => {
-                        hookApiCallbacks[callbackId](args[1]);
-                    }).then()
-                    delete hookApiCallbacks[callbackId];
-                }
-            }
-        } catch (e) {
-            log("hookNTQQApiReceive error", e.stack.toString(), args)
-        }
-        originalSend.call(window.webContents, channel, ...args);
     }
-    window.webContents.send = patchSend;
+    if (!isLogger) {
+      try {
+        HOOK_LOG && log(`received ntqq api message: ${channel}`, args)
+      } catch (e) {
+        log("hook log error", e, args)
+      }
+    }
+    try {
+      if (args?.[1] instanceof Array) {
+        for (let receiveData of args?.[1]) {
+          const ntQQApiMethodName = receiveData.cmdName;
+          // log(`received ntqq api message: ${channel} ${ntQQApiMethodName}`, JSON.stringify(receiveData))
+          for (let hook of receiveHooks) {
+            if (hook.method.includes(ntQQApiMethodName)) {
+              new Promise((resolve, reject) => {
+                try {
+                  let _ = hook.hookFunc(receiveData.payload)
+                  if (hook.hookFunc.constructor.name === "AsyncFunction") {
+                    (_ as Promise<void>).then()
+                  }
+                } catch (e) {
+                  log("hook error", e, receiveData.payload)
+                }
+              }).then()
+            }
+          }
+        }
+      }
+      if (args[0]?.callbackId) {
+        // log("hookApiCallback", hookApiCallbacks, args)
+        const callbackId = args[0].callbackId;
+        if (hookApiCallbacks[callbackId]) {
+          // log("callback found")
+          new Promise((resolve, reject) => {
+            hookApiCallbacks[callbackId](args[1]);
+          }).then()
+          delete hookApiCallbacks[callbackId];
+        }
+      }
+    } catch (e) {
+      log("hookNTQQApiReceive error", e.stack.toString(), args)
+    }
+    originalSend.call(window.webContents, channel, ...args);
+  }
+  window.webContents.send = patchSend;
 }
 
 export function hookNTQQApiCall(window: BrowserWindow) {
-    // 监听调用NTQQApi
-    let webContents = window.webContents as any;
-    const ipc_message_proxy = webContents._events["-ipc-message"]?.[0] || webContents._events["-ipc-message"];
+  // 监听调用NTQQApi
+  let webContents = window.webContents as any;
+  const ipc_message_proxy = webContents._events["-ipc-message"]?.[0] || webContents._events["-ipc-message"];
 
-    const proxyIpcMsg = new Proxy(ipc_message_proxy, {
-        apply(target, thisArg, args) {
-            // console.log(thisArg, args);
-            let isLogger = false
-            try {
-                isLogger = args[3][0].eventName.startsWith("ns-LoggerApi")
-            } catch (e) {
+  const proxyIpcMsg = new Proxy(ipc_message_proxy, {
+    apply(target, thisArg, args) {
+      // console.log(thisArg, args);
+      let isLogger = false
+      try {
+        isLogger = args[3][0].eventName.startsWith("ns-LoggerApi")
+      } catch (e) {
 
-            }
-            if (!isLogger) {
-                try {
-                    HOOK_LOG && log("call NTQQ api", thisArg, args);
-                } catch (e) {
+      }
+      if (!isLogger) {
+        try {
+          HOOK_LOG && log("call NTQQ api", thisArg, args);
+        } catch (e) {
 
-                }
-            }
-            return target.apply(thisArg, args);
-        },
-    });
-    if (webContents._events["-ipc-message"]?.[0]) {
-        webContents._events["-ipc-message"][0] = proxyIpcMsg;
-    } else {
-        webContents._events["-ipc-message"] = proxyIpcMsg;
-    }
-
-    const ipc_invoke_proxy = webContents._events["-ipc-invoke"]?.[0] || webContents._events["-ipc-invoke"];
-    const proxyIpcInvoke = new Proxy(ipc_invoke_proxy, {
-        apply(target, thisArg, args) {
-            // console.log(args);
-            HOOK_LOG && log("call NTQQ invoke api", thisArg, args)
-            args[0]["_replyChannel"]["sendReply"] = new Proxy(args[0]["_replyChannel"]["sendReply"], {
-                apply(sendtarget, sendthisArg, sendargs) {
-                    sendtarget.apply(sendthisArg, sendargs);
-                }
-            });
-            let ret = target.apply(thisArg, args);
-            try {
-                HOOK_LOG && log("call NTQQ invoke api return", ret)
-            } catch (e) {
-
-            }
-            return ret;
         }
-    });
-    if (webContents._events["-ipc-invoke"]?.[0]) {
-        webContents._events["-ipc-invoke"][0] = proxyIpcInvoke;
-    } else {
-        webContents._events["-ipc-invoke"] = proxyIpcInvoke;
+        try {
+          const _args: unknown[] = args[3][1];
+          const cmdName: NTQQApiMethod = _args[0] as NTQQApiMethod;
+          const callParams = _args.slice(1);
+          callHooks.forEach(hook => {
+            if (hook.method.includes(cmdName)) {
+              new Promise((resolve, reject) => {
+                try {
+                  let _ = hook.hookFunc(callParams)
+                  if (hook.hookFunc.constructor.name === "AsyncFunction") {
+                    (_ as Promise<void>).then()
+                  }
+                } catch (e) {
+                  log("hook call error", e, _args)
+                }
+              }).then()
+            }
+          })
+        } catch (e) {
+
+        }
+      }
+      return target.apply(thisArg, args);
+    },
+  });
+  if (webContents._events["-ipc-message"]?.[0]) {
+    webContents._events["-ipc-message"][0] = proxyIpcMsg;
+  } else {
+    webContents._events["-ipc-message"] = proxyIpcMsg;
+  }
+
+  const ipc_invoke_proxy = webContents._events["-ipc-invoke"]?.[0] || webContents._events["-ipc-invoke"];
+  const proxyIpcInvoke = new Proxy(ipc_invoke_proxy, {
+    apply(target, thisArg, args) {
+      // console.log(args);
+      HOOK_LOG && log("call NTQQ invoke api", thisArg, args)
+      args[0]["_replyChannel"]["sendReply"] = new Proxy(args[0]["_replyChannel"]["sendReply"], {
+        apply(sendtarget, sendthisArg, sendargs) {
+          sendtarget.apply(sendthisArg, sendargs);
+        }
+      });
+      let ret = target.apply(thisArg, args);
+      try {
+        HOOK_LOG && log("call NTQQ invoke api return", ret)
+      } catch (e) {
+
+      }
+      return ret;
     }
+  });
+  if (webContents._events["-ipc-invoke"]?.[0]) {
+    webContents._events["-ipc-invoke"][0] = proxyIpcInvoke;
+  } else {
+    webContents._events["-ipc-invoke"] = proxyIpcInvoke;
+  }
 }
 
 export function registerReceiveHook<PayloadType>(method: ReceiveCmd | ReceiveCmd[], hookFunc: (payload: PayloadType) => void): string {
-    const id = uuidv4()
-    if (!Array.isArray(method)) {
-        method = [method]
-    }
-    receiveHooks.push({
-        method,
-        hookFunc,
-        id
-    })
-    return id;
+  const id = uuidv4()
+  if (!Array.isArray(method)) {
+    method = [method]
+  }
+  receiveHooks.push({
+    method,
+    hookFunc,
+    id
+  })
+  return id;
+}
+
+export function registerCallHook(method: NTQQApiMethod | NTQQApiMethod[], hookFunc: (callParams: unknown[]) => void | Promise<void>): void {
+  if (!Array.isArray(method)) {
+    method = [method]
+  }
+  callHooks.push({
+    method,
+    hookFunc
+  })
 }
 
 export function removeReceiveHook(id: string) {
-    const index = receiveHooks.findIndex(h => h.id === id)
-    receiveHooks.splice(index, 1);
+  const index = receiveHooks.findIndex(h => h.id === id)
+  receiveHooks.splice(index, 1);
 }
 
 let activatedGroups: string[] = [];
 
 async function updateGroups(_groups: Group[], needUpdate: boolean = true) {
-    for (let group of _groups) {
-        log("update group", group)
-        // if (!activatedGroups.includes(group.groupCode)) {
-        NTQQMsgApi.activateChat({peerUid: group.groupCode, chatType: ChatType.group}).then((r) => {
-            // activatedGroups.push(group.groupCode);
-            // log(`激活群聊天窗口${group.groupName}(${group.groupCode})`, r)
-            // if (r.result !== 0) {
-            //     setTimeout(() => NTQQMsgApi.activateGroupChat(group.groupCode).then(r => log(`再次激活群聊天窗口${group.groupName}(${group.groupCode})`, r)), 500);
-            // }else {
-            // }
-        }).catch(log)
-        // }
-        let existGroup = groups.find(g => g.groupCode == group.groupCode);
-        if (existGroup) {
-            Object.assign(existGroup, group);
-        } else {
-            groups.push(group);
-            existGroup = group;
-        }
-
-        if (needUpdate) {
-            const members = await NTQQGroupApi.getGroupMembers(group.groupCode);
-
-            if (members) {
-                existGroup.members = members;
-            }
-        }
+  for (let group of _groups) {
+    log("update group", group)
+    // if (!activatedGroups.includes(group.groupCode)) {
+    NTQQMsgApi.activateChat({peerUid: group.groupCode, chatType: ChatType.group}).then((r) => {
+      // activatedGroups.push(group.groupCode);
+      // log(`激活群聊天窗口${group.groupName}(${group.groupCode})`, r)
+      // if (r.result !== 0) {
+      //     setTimeout(() => NTQQMsgApi.activateGroupChat(group.groupCode).then(r => log(`再次激活群聊天窗口${group.groupName}(${group.groupCode})`, r)), 500);
+      // }else {
+      // }
+    }).catch(log)
+    // }
+    let existGroup = groups.find(g => g.groupCode == group.groupCode);
+    if (existGroup) {
+      Object.assign(existGroup, group);
+    } else {
+      groups.push(group);
+      existGroup = group;
     }
+
+    if (needUpdate) {
+      const members = await NTQQGroupApi.getGroupMembers(group.groupCode);
+
+      if (members) {
+        existGroup.members = members;
+      }
+    }
+  }
 }
 
 async function processGroupEvent(payload: { groupList: Group[] }) {
-    try {
-        const newGroupList = payload.groupList;
-        for (const group of newGroupList) {
-            let existGroup = groups.find(g => g.groupCode == group.groupCode);
-            if (existGroup) {
-                if (existGroup.memberCount > group.memberCount) {
-                    log(`群(${group.groupCode})成员数量减少${existGroup.memberCount} -> ${group.memberCount}`);
-                    const oldMembers = existGroup.members;
+  try {
+    const newGroupList = payload.groupList;
+    for (const group of newGroupList) {
+      let existGroup = groups.find(g => g.groupCode == group.groupCode);
+      if (existGroup) {
+        if (existGroup.memberCount > group.memberCount) {
+          log(`群(${group.groupCode})成员数量减少${existGroup.memberCount} -> ${group.memberCount}`);
+          const oldMembers = existGroup.members;
 
-                    await sleep(200);  // 如果请求QQ API的速度过快,通常无法正确拉取到最新的群信息,因此这里人为引入一个延时
-                    const newMembers = await NTQQGroupApi.getGroupMembers(group.groupCode);
+          await sleep(200);  // 如果请求QQ API的速度过快,通常无法正确拉取到最新的群信息,因此这里人为引入一个延时
+          const newMembers = await NTQQGroupApi.getGroupMembers(group.groupCode);
 
-                    group.members = newMembers;
-                    const newMembersSet = new Set<string>();  // 建立索引降低时间复杂度
+          group.members = newMembers;
+          const newMembersSet = new Set<string>();  // 建立索引降低时间复杂度
 
-                    for (const member of newMembers) {
-                        newMembersSet.add(member.uin);
-                    }
-
-                    // 判断bot是否是管理员,如果是管理员不需要从这里得知有人退群,这里的退群无法得知是主动退群还是被踢
-                    let bot = await getGroupMember(group.groupCode, selfInfo.uin)
-                    if (bot.role == GroupMemberRole.admin || bot.role == GroupMemberRole.owner) {
-                        continue
-                    }
-                    for (const member of oldMembers) {
-                        if (!newMembersSet.has(member.uin) && member.uin != selfInfo.uin) {
-                            postOB11Event(new OB11GroupDecreaseEvent(parseInt(group.groupCode), parseInt(member.uin), parseInt(member.uin), "leave"));
-                            break;
-                        }
-                    }
-                }
+          for (const member of newMembers) {
+            newMembersSet.add(member.uin);
+          }
 
+          // 判断bot是否是管理员,如果是管理员不需要从这里得知有人退群,这里的退群无法得知是主动退群还是被踢
+          let bot = await getGroupMember(group.groupCode, selfInfo.uin)
+          if (bot.role == GroupMemberRole.admin || bot.role == GroupMemberRole.owner) {
+            continue
+          }
+          for (const member of oldMembers) {
+            if (!newMembersSet.has(member.uin) && member.uin != selfInfo.uin) {
+              postOB11Event(new OB11GroupDecreaseEvent(parseInt(group.groupCode), parseInt(member.uin), parseInt(member.uin), "leave"));
+              break;
             }
+          }
         }
 
-        updateGroups(newGroupList, false).then();
-    } catch (e) {
-        updateGroups(payload.groupList).then();
-        log("更新群信息错误", e.stack.toString());
+      }
     }
+
+    updateGroups(newGroupList, false).then();
+  } catch (e) {
+    updateGroups(payload.groupList).then();
+    log("更新群信息错误", e.stack.toString());
+  }
 }
 
 // 群列表变动
 registerReceiveHook<{ groupList: Group[], updateType: number }>(ReceiveCmdS.GROUPS, (payload) => {
-    // updateType 3是群列表变动,2是群成员变动
-    // log("群列表变动", payload.updateType, payload.groupList)
-    if (payload.updateType != 2) {
-        updateGroups(payload.groupList).then();
-    } else {
-        if (process.platform == "win32") {
-            processGroupEvent(payload).then();
-        }
+  // updateType 3是群列表变动,2是群成员变动
+  // log("群列表变动", payload.updateType, payload.groupList)
+  if (payload.updateType != 2) {
+    updateGroups(payload.groupList).then();
+  } else {
+    if (process.platform == "win32") {
+      processGroupEvent(payload).then();
     }
+  }
 })
 registerReceiveHook<{ groupList: Group[], updateType: number }>(ReceiveCmdS.GROUPS_STORE, (payload) => {
-    // updateType 3是群列表变动,2是群成员变动
-    // log("群列表变动", payload.updateType, payload.groupList)
-    if (payload.updateType != 2) {
-        updateGroups(payload.groupList).then();
-    } else {
-        if (process.platform != "win32") {
-            processGroupEvent(payload).then();
-        }
+  // updateType 3是群列表变动,2是群成员变动
+  // log("群列表变动", payload.updateType, payload.groupList)
+  if (payload.updateType != 2) {
+    updateGroups(payload.groupList).then();
+  } else {
+    if (process.platform != "win32") {
+      processGroupEvent(payload).then();
     }
+  }
 })
 
 registerReceiveHook<{
-    groupCode: string,
-    dataSource: number,
-    members: Set<GroupMember>
+  groupCode: string,
+  dataSource: number,
+  members: Set<GroupMember>
 }>(ReceiveCmdS.GROUP_MEMBER_INFO_UPDATE, async (payload) => {
-    const groupCode = payload.groupCode;
-    const members = Array.from(payload.members.values());
-    // log("群成员信息变动", groupCode, members)
-    for (const member of members) {
-        const existMember = await getGroupMember(groupCode, member.uin);
-        if (existMember) {
-            Object.assign(existMember, member);
-        }
+  const groupCode = payload.groupCode;
+  const members = Array.from(payload.members.values());
+  // log("群成员信息变动", groupCode, members)
+  for (const member of members) {
+    const existMember = await getGroupMember(groupCode, member.uin);
+    if (existMember) {
+      Object.assign(existMember, member);
     }
-    // const existGroup = groups.find(g => g.groupCode == groupCode);
-    // if (existGroup) {
-    //     log("对比群成员", existGroup.members, members)
-    //     for (const member of members) {
-    //         const existMember = existGroup.members.find(m => m.uin == member.uin);
-    //         if (existMember) {
-    //             log("对比群名片", existMember.cardName, member.cardName)
-    //             if (existMember.cardName != member.cardName) {
-    //                 postOB11Event(new OB11GroupCardEvent(parseInt(existGroup.groupCode), parseInt(member.uin), member.cardName, existMember.cardName));
-    //             }
-    //             Object.assign(existMember, member);
-    //         }
-    //     }
-    // }
+  }
+  // const existGroup = groups.find(g => g.groupCode == groupCode);
+  // if (existGroup) {
+  //     log("对比群成员", existGroup.members, members)
+  //     for (const member of members) {
+  //         const existMember = existGroup.members.find(m => m.uin == member.uin);
+  //         if (existMember) {
+  //             log("对比群名片", existMember.cardName, member.cardName)
+  //             if (existMember.cardName != member.cardName) {
+  //                 postOB11Event(new OB11GroupCardEvent(parseInt(existGroup.groupCode), parseInt(member.uin), member.cardName, existMember.cardName));
+  //             }
+  //             Object.assign(existMember, member);
+  //         }
+  //     }
+  // }
 })
 
 // 好友列表变动
 registerReceiveHook<{
-    data: { categoryId: number, categroyName: string, categroyMbCount: number, buddyList: User[] }[]
+  data: { categoryId: number, categroyName: string, categroyMbCount: number, buddyList: User[] }[]
 }>(ReceiveCmdS.FRIENDS, payload => {
-    for (const fData of payload.data) {
-        const _friends = fData.buddyList;
-        for (let friend of _friends) {
-            NTQQMsgApi.activateChat({peerUid: friend.uid, chatType: ChatType.friend}).then()
-            let existFriend = friends.find(f => f.uin == friend.uin)
-            if (!existFriend) {
-                friends.push(friend)
-            } else {
-                Object.assign(existFriend, friend)
-            }
-        }
+  for (const fData of payload.data) {
+    const _friends = fData.buddyList;
+    for (let friend of _friends) {
+      NTQQMsgApi.activateChat({peerUid: friend.uid, chatType: ChatType.friend}).then()
+      let existFriend = friends.find(f => f.uin == friend.uin)
+      if (!existFriend) {
+        friends.push(friend)
+      } else {
+        Object.assign(existFriend, friend)
+      }
     }
+  }
 })
 
 registerReceiveHook<{ msgList: Array<RawMessage> }>([ReceiveCmdS.NEW_MSG, ReceiveCmdS.NEW_ACTIVE_MSG], (payload) => {
-    // 保存一下uid
-    for (const message of payload.msgList) {
-        const uid = message.senderUid;
-        const uin = message.senderUin;
-        if (uid && uin) {
-            if (message.chatType === ChatType.temp) {
-                dbUtil.getReceivedTempUinMap().then(receivedTempUinMap => {
-                    if (!receivedTempUinMap[uin]) {
-                        receivedTempUinMap[uin] = uid;
-                        dbUtil.setReceivedTempUinMap(receivedTempUinMap)
-                    }
-                })
-            }
-            uidMaps[uid] = uin;
+  // 保存一下uid
+  for (const message of payload.msgList) {
+    const uid = message.senderUid;
+    const uin = message.senderUin;
+    if (uid && uin) {
+      if (message.chatType === ChatType.temp) {
+        dbUtil.getReceivedTempUinMap().then(receivedTempUinMap => {
+          if (!receivedTempUinMap[uin]) {
+            receivedTempUinMap[uin] = uid;
+            dbUtil.setReceivedTempUinMap(receivedTempUinMap)
+          }
+        })
+      }
+      uidMaps[uid] = uin;
+    }
+  }
+
+
+  // 自动清理新消息文件
+  const {autoDeleteFile} = getConfigUtil().getConfig();
+  if (!autoDeleteFile) {
+    return
+  }
+  for (const message of payload.msgList) {
+    // log("收到新消息,push到历史记录", message.msgId)
+    // dbUtil.addMsg(message).then()
+    // 清理文件
+
+    for (const msgElement of message.elements) {
+      setTimeout(() => {
+        const picPath = msgElement.picElement?.sourcePath
+        const picThumbPath = [...msgElement.picElement?.thumbPath.values()]
+        const pttPath = msgElement.pttElement?.filePath
+        const filePath = msgElement.fileElement?.filePath
+        const videoPath = msgElement.videoElement?.filePath
+        const videoThumbPath: string[] = [...msgElement.videoElement?.thumbPath.values()]
+        const pathList = [picPath, ...picThumbPath, pttPath, filePath, videoPath, ...videoThumbPath]
+        if (msgElement.picElement) {
+          pathList.push(...Object.values(msgElement.picElement.thumbPath))
         }
-    }
-
-
-    // 自动清理新消息文件
-    const {autoDeleteFile} = getConfigUtil().getConfig();
-    if (!autoDeleteFile) {
-        return
-    }
-    for (const message of payload.msgList) {
-        // log("收到新消息,push到历史记录", message.msgId)
-        // dbUtil.addMsg(message).then()
-        // 清理文件
-
-        for (const msgElement of message.elements) {
-            setTimeout(() => {
-                const picPath = msgElement.picElement?.sourcePath
-                const picThumbPath = [...msgElement.picElement?.thumbPath.values()]
-                const pttPath = msgElement.pttElement?.filePath
-                const filePath = msgElement.fileElement?.filePath
-                const videoPath = msgElement.videoElement?.filePath
-                const videoThumbPath: string[] = [...msgElement.videoElement?.thumbPath.values()]
-                const pathList = [picPath, ...picThumbPath, pttPath, filePath, videoPath, ...videoThumbPath]
-                if (msgElement.picElement) {
-                    pathList.push(...Object.values(msgElement.picElement.thumbPath))
-                }
-                const aioOpGrayTipElement = msgElement.grayTipElement?.aioOpGrayTipElement
-                if (aioOpGrayTipElement) {
-                    tempGroupCodeMap[aioOpGrayTipElement.peerUid] = aioOpGrayTipElement.fromGrpCodeOfTmpChat;
-                }
-
-                // log("需要清理的文件", pathList);
-                for (const path of pathList) {
-                    if (path) {
-                        fs.unlink(picPath, () => {
-                            log("删除文件成功", path)
-                        });
-                    }
-                }
-            }, getConfigUtil().getConfig().autoDeleteFileSecond * 1000)
+        const aioOpGrayTipElement = msgElement.grayTipElement?.aioOpGrayTipElement
+        if (aioOpGrayTipElement) {
+          tempGroupCodeMap[aioOpGrayTipElement.peerUid] = aioOpGrayTipElement.fromGrpCodeOfTmpChat;
         }
+
+        // log("需要清理的文件", pathList);
+        for (const path of pathList) {
+          if (path) {
+            fs.unlink(picPath, () => {
+              log("删除文件成功", path)
+            });
+          }
+        }
+      }, getConfigUtil().getConfig().autoDeleteFileSecond * 1000)
     }
+  }
 })
 
 registerReceiveHook<{ msgRecord: RawMessage }>(ReceiveCmdS.SELF_SEND_MSG, ({msgRecord}) => {
-    const message = msgRecord;
-    const peerUid = message.peerUid;
-    // log("收到自己发送成功的消息", Object.keys(sendMessagePool), message);
-    // log("收到自己发送成功的消息", message.msgId, message.msgSeq);
-    dbUtil.addMsg(message).then()
-    const sendCallback = sendMessagePool[peerUid]
-    if (sendCallback) {
-        try {
-            sendCallback(message);
-        } catch (e) {
-            log("receive self msg error", e.stack)
-        }
+  const message = msgRecord;
+  const peerUid = message.peerUid;
+  // log("收到自己发送成功的消息", Object.keys(sendMessagePool), message);
+  // log("收到自己发送成功的消息", message.msgId, message.msgSeq);
+  dbUtil.addMsg(message).then()
+  const sendCallback = sendMessagePool[peerUid]
+  if (sendCallback) {
+    try {
+      sendCallback(message);
+    } catch (e) {
+      log("receive self msg error", e.stack)
     }
+  }
 })
 
 registerReceiveHook<{ info: { status: number } }>(ReceiveCmdS.SELF_STATUS, (info) => {
-    selfInfo.online = info.info.status !== 20
+  selfInfo.online = info.info.status !== 20
 })
 
 
 let activatedPeerUids: string[] = []
 registerReceiveHook<{
-    changedRecentContactLists: {
-        listType: number, sortedContactList: string[],
-        changedList: {
-            id: string,  // peerUid
-            chatType: ChatType
-        }[]
+  changedRecentContactLists: {
+    listType: number, sortedContactList: string[],
+    changedList: {
+      id: string,  // peerUid
+      chatType: ChatType
     }[]
+  }[]
 }>(ReceiveCmdS.RECENT_CONTACT, async (payload) => {
-    for (const recentContact of payload.changedRecentContactLists) {
-        for (const changedContact of recentContact.changedList) {
-            if (activatedPeerUids.includes(changedContact.id)) continue;
-            activatedPeerUids.push(changedContact.id)
-            const peer = {peerUid: changedContact.id, chatType: changedContact.chatType}
-            if (changedContact.chatType === ChatType.temp) {
-                log("收到临时会话消息", peer)
-                NTQQMsgApi.activateChatAndGetHistory(peer).then(
-                    () => {
-                        NTQQMsgApi.getMsgHistory(peer, "", 20).then(({msgList}) => {
-                            let lastTempMsg =  msgList.pop()
-                            log("激活窗口之前的第一条临时会话消息:", lastTempMsg)
-                            if ((Date.now() / 1000) - parseInt(lastTempMsg.msgTime) < 5) {
-                                OB11Constructor.message(lastTempMsg).then(r => postOB11Event(r))
-                            }
-                        })
-                    }
-                )
-            } else {
-                NTQQMsgApi.activateChat(peer).then()
-            }
-        }
+  for (const recentContact of payload.changedRecentContactLists) {
+    for (const changedContact of recentContact.changedList) {
+      if (activatedPeerUids.includes(changedContact.id)) continue;
+      activatedPeerUids.push(changedContact.id)
+      const peer = {peerUid: changedContact.id, chatType: changedContact.chatType}
+      if (changedContact.chatType === ChatType.temp) {
+        log("收到临时会话消息", peer)
+        NTQQMsgApi.activateChatAndGetHistory(peer).then(
+          () => {
+            NTQQMsgApi.getMsgHistory(peer, "", 20).then(({msgList}) => {
+              let lastTempMsg = msgList.pop()
+              log("激活窗口之前的第一条临时会话消息:", lastTempMsg)
+              if ((Date.now() / 1000) - parseInt(lastTempMsg.msgTime) < 5) {
+                OB11Constructor.message(lastTempMsg).then(r => postOB11Event(r))
+              }
+            })
+          }
+        )
+      } else {
+        NTQQMsgApi.activateChat(peer).then()
+      }
     }
+  }
+})
+
+registerCallHook(NTQQApiMethod.DELETE_ACTIVE_CHAT, async (payload) => {
+  const peerUid = payload[0] as string;
+  log("激活的聊天窗口被删除,准备重新激活", peerUid);
+  let chatType = ChatType.friend;
+  if (isNumeric(peerUid)) {
+    chatType = ChatType.group;
+  }
+  else{
+    // 检查是否好友
+    if (!(await getFriend(peerUid))){
+      chatType = ChatType.temp;
+    }
+  }
+  const peer = {peerUid, chatType}
+  await sleep(1000);
+  NTQQMsgApi.activateChat(peer).then((r) => {
+    log("重新激活聊天窗口", peer, {result: r.result, errMsg: r.errMsg})
+  });
 })
\ No newline at end of file
diff --git a/src/ntqqapi/ntcall.ts b/src/ntqqapi/ntcall.ts
index df01ef5..336c384 100644
--- a/src/ntqqapi/ntcall.ts
+++ b/src/ntqqapi/ntcall.ts
@@ -26,6 +26,7 @@ export enum NTQQApiMethod {
     ACTIVE_CHAT_HISTORY = "nodeIKernelMsgService/getMsgsIncludeSelfAndAddActiveChat", // 激活聊天窗口,有时候必须这样才能收到消息, 并返回历史消息
     HISTORY_MSG = "nodeIKernelMsgService/getMsgsIncludeSelf",
     GET_MULTI_MSG = "nodeIKernelMsgService/getMultiMsg",
+    DELETE_ACTIVE_CHAT = "nodeIKernelMsgService/deleteActiveChatByUid",
 
     LIKE_FRIEND = "nodeIKernelProfileLikeService/setBuddyProfileLike",
     SELF_INFO = "fetchAuthData",