diff --git a/package.json b/package.json
index 8e3ac6c..7e73a1d 100644
--- a/package.json
+++ b/package.json
@@ -20,6 +20,7 @@
     "compressing": "^1.10.1",
     "cordis": "^3.18.0",
     "cors": "^2.8.5",
+    "cosmokit": "^1.6.2",
     "express": "^4.19.2",
     "fast-xml-parser": "^4.4.1",
     "file-type": "^19.4.1",
diff --git a/src/common/utils/EventTask.ts b/src/common/utils/EventTask.ts
index bc32199..a7279fe 100644
--- a/src/common/utils/EventTask.ts
+++ b/src/common/utils/EventTask.ts
@@ -22,6 +22,7 @@ export class NTEventWrapper {
   private WrapperSession: NodeIQQNTWrapperSession | undefined//WrapperSession
   private ListenerManger: Map<string, ListenerClassBase> = new Map<string, ListenerClassBase>() //ListenerName-Unique -> Listener实例
   private EventTask = new Map<string, Map<string, Map<string, Internal_MapKey>>>()//tasks ListenerMainName -> ListenerSubName-> uuid -> {timeout,createtime,func}
+  public initialised = false
 
   constructor() {
   }
@@ -46,6 +47,7 @@ export class NTEventWrapper {
   init({ ListenerMap, WrapperSession }: { ListenerMap: { [key: string]: typeof ListenerClassBase }, WrapperSession: NodeIQQNTWrapperSession }) {
     this.ListenerMap = ListenerMap
     this.WrapperSession = WrapperSession
+    this.initialised = true
   }
 
   createEventFunction<T extends (...args: any) => any>(eventName: string): T | undefined {
diff --git a/src/main/main.ts b/src/main/main.ts
index 6d1aea1..72cfde0 100644
--- a/src/main/main.ts
+++ b/src/main/main.ts
@@ -14,7 +14,7 @@ import {
   CHANNEL_UPDATE,
 } from '../common/channels'
 import { ob11WebsocketServer } from '../onebot11/server/ws/WebsocketServer'
-import { DATA_DIR, TEMP_DIR } from '../common/utils'
+import { DATA_DIR, getBuildVersion, TEMP_DIR } from '../common/utils'
 import {
   llonebotError,
   setSelfInfo,
@@ -341,7 +341,7 @@ function onLoad() {
       }
     })
 
-    registerReceiveHook<FriendRequestNotify>(ReceiveCmdS.FRIEND_REQUEST, async (payload) => {
+    /*registerReceiveHook<FriendRequestNotify>(ReceiveCmdS.FRIEND_REQUEST, async (payload) => {
       for (const req of payload.data.buddyReqs) {
         if (!!req.isInitiator || (req.isDecide && req.reqType !== BuddyReqType.KMEINITIATORWAITPEERCONFIRM)) {
           continue
@@ -362,7 +362,7 @@ function onLoad() {
         )
         postOb11Event(friendRequestEvent)
       }
-    })
+    })*/
   }
 
   let startTime = 0 // 毫秒
@@ -380,7 +380,10 @@ function onLoad() {
     }
     llonebotError.otherError = ''
     startTime = Date.now()
-    NTEventDispatch.init({ ListenerMap: wrapperConstructor, WrapperSession: getSession()! })
+    const WrapperSession = getSession()
+    if (WrapperSession) {
+      NTEventDispatch.init({ ListenerMap: wrapperConstructor, WrapperSession })
+    }
     MessageUnique.init(uin)
 
     //log('start activate group member info')
@@ -405,6 +408,8 @@ function onLoad() {
     log('LLOneBot start')
   }
 
+  const buildVersion = getBuildVersion()
+
   const intervalId = setInterval(() => {
     const current = getSelfInfo()
     if (!current.uin) {
@@ -414,7 +419,7 @@ function onLoad() {
         nick: current.uin,
       })
     }
-    if (current.uin && getSession()) {
+    if (current.uin && (buildVersion >= 27187 || getSession())) {
       clearInterval(intervalId)
       start(current.uid, current.uin)
     }
diff --git a/src/ntqqapi/api/file.ts b/src/ntqqapi/api/file.ts
index e4d51c6..f1f50fc 100644
--- a/src/ntqqapi/api/file.ts
+++ b/src/ntqqapi/api/file.ts
@@ -25,6 +25,7 @@ import fsPromise from 'node:fs/promises'
 import { NTEventDispatch } from '@/common/utils/EventTask'
 import { OnRichMediaDownloadCompleteParams } from '@/ntqqapi/listeners'
 import { NodeIKernelSearchService } from '@/ntqqapi/services'
+import { Time } from 'cosmokit'
 
 export class NTQQFileApi {
   static async getVideoUrl(peer: Peer, msgId: string, elementId: string): Promise<string> {
@@ -379,7 +380,7 @@ export class NTQQFileCacheApi {
     return callNTQQApi<CacheScanResult>({
       methodName: NTQQApiMethod.CACHE_SCAN,
       args: [null, null],
-      timeoutSecond: 300,
+      timeout: 300 * Time.second,
     })
   }
 
diff --git a/src/ntqqapi/api/friend.ts b/src/ntqqapi/api/friend.ts
index fcab865..717c5c0 100644
--- a/src/ntqqapi/api/friend.ts
+++ b/src/ntqqapi/api/friend.ts
@@ -121,6 +121,16 @@ export class NTQQFriendApi {
 
   static async isBuddy(uid: string): Promise<boolean> {
     const session = getSession()
-    return session?.getBuddyService().isBuddy(uid)!
+    if (session) {
+      return session.getBuddyService().isBuddy(uid)
+    } else {
+      return await callNTQQApi<boolean>({
+        methodName: 'nodeIKernelBuddyService/isBuddy',
+        args: [
+          { uid },
+          null,
+        ],
+      })
+    }
   }
 }
diff --git a/src/ntqqapi/api/group.ts b/src/ntqqapi/api/group.ts
index 2e39155..866033a 100644
--- a/src/ntqqapi/api/group.ts
+++ b/src/ntqqapi/api/group.ts
@@ -71,11 +71,36 @@ export class NTQQGroupApi {
 
   static async getGroupMembers(groupQQ: string, num = 3000): Promise<Map<string, GroupMember>> {
     const session = getSession()
-    const groupService = session?.getGroupService()
-    const sceneId = groupService?.createMemberListScene(groupQQ, 'groupMemberList_MainWindow')
-    const result = await groupService?.getNextMemberList(sceneId!, undefined, num)
-    if (result?.errCode !== 0) {
-      throw ('获取群成员列表出错,' + result?.errMsg)
+    let result: Awaited<ReturnType<NodeIKernelGroupService['getNextMemberList']>>
+    if (session) {
+      const groupService = session.getGroupService()
+      const sceneId = groupService.createMemberListScene(groupQQ, 'groupMemberList_MainWindow')
+      result = await groupService.getNextMemberList(sceneId, undefined, num)
+    } else {
+      const sceneId = await callNTQQApi<string>({
+        methodName: NTQQApiMethod.GROUP_MEMBER_SCENE,
+        args: [
+          {
+            groupCode: groupQQ,
+            scene: 'groupMemberList_MainWindow',
+          },
+        ],
+      })
+      result = await callNTQQApi<
+        ReturnType<NodeIKernelGroupService['getNextMemberList']>
+      >({
+        methodName: NTQQApiMethod.GROUP_MEMBERS,
+        args: [
+          {
+            sceneId,
+            num,
+          },
+          null,
+        ],
+      })
+    }
+    if (result.errCode !== 0) {
+      throw ('获取群成员列表出错,' + result.errMsg)
     }
     return result.result.infos
   }
diff --git a/src/ntqqapi/api/msg.ts b/src/ntqqapi/api/msg.ts
index c581e50..9c8a185 100644
--- a/src/ntqqapi/api/msg.ts
+++ b/src/ntqqapi/api/msg.ts
@@ -139,56 +139,6 @@ export class NTQQMsgApi {
     return retMsg!
   }
 
-  static async sendMsgV2(peer: Peer, msgElements: SendMessageElement[], waitComplete = true, timeout = 10000) {
-    function generateMsgId() {
-      const timestamp = Math.floor(Date.now() / 1000)
-      const random = Math.floor(Math.random() * Math.pow(2, 32))
-      const buffer = Buffer.alloc(8)
-      buffer.writeUInt32BE(timestamp, 0)
-      buffer.writeUInt32BE(random, 4)
-      const msgId = BigInt('0x' + buffer.toString('hex')).toString()
-      return msgId
-    }
-    // 此处有采用Hack方法 利用数据返回正确得到对应消息
-    // 与之前 Peer队列 MsgSeq队列 真正的MsgId并发不同
-    // 谨慎采用 目前测试暂无问题  Developer.Mlikiowa
-    let msgId: string
-    try {
-      msgId = await NTQQMsgApi.getMsgUnique(peer.chatType, await NTQQMsgApi.getServerTime())
-    } catch (error) {
-      //if (!napCatCore.session.getMsgService()['generateMsgUniqueId'])
-      //兜底识别策略V2
-      msgId = generateMsgId().toString()
-    }
-    let data = await NTEventDispatch.CallNormalEvent<
-      (msgId: string, peer: Peer, msgElements: SendMessageElement[], map: Map<any, any>) => Promise<unknown>,
-      (msgList: RawMessage[]) => void
-    >(
-      'NodeIKernelMsgService/sendMsg',
-      'NodeIKernelMsgListener/onMsgInfoListUpdate',
-      1,
-      timeout,
-      (msgRecords: RawMessage[]) => {
-        for (let msgRecord of msgRecords) {
-          if (msgRecord.msgId === msgId && msgRecord.sendStatus === 2) {
-            return true
-          }
-        }
-        return false
-      },
-      msgId,
-      peer,
-      msgElements,
-      new Map()
-    )
-    const retMsg = data[1].find(msgRecord => {
-      if (msgRecord.msgId === msgId) {
-        return true
-      }
-    })
-    return retMsg!
-  }
-
   static async getMsgUnique(chatType: number, time: string) {
     const session = getSession()
     if (getBuildVersion() >= 26702) {
diff --git a/src/ntqqapi/api/user.ts b/src/ntqqapi/api/user.ts
index 1d6c6b5..8cb4ce4 100644
--- a/src/ntqqapi/api/user.ts
+++ b/src/ntqqapi/api/user.ts
@@ -1,5 +1,5 @@
 import { callNTQQApi, GeneralCallResult, NTQQApiClass, NTQQApiMethod } from '../ntcall'
-import { SelfInfo, User, UserDetailInfoByUin, UserDetailInfoByUinV2 } from '../types'
+import { SelfInfo, User, UserDetailInfoByUin, UserDetailInfoByUinV2, UserDetailInfoListenerArg } from '../types'
 import { ReceiveCmdS } from '../hook'
 import { friends, groupMembers, getSelfUin } from '@/common/data'
 import { CacheClassFuncAsync, log, getBuildVersion } from '@/common/utils'
@@ -9,6 +9,7 @@ import { NodeIKernelProfileService, UserDetailSource, ProfileBizType } from '../
 import { NodeIKernelProfileListener } from '../listeners'
 import { NTEventDispatch } from '@/common/utils/EventTask'
 import { NTQQFriendApi } from './friend'
+import { Time } from 'cosmokit'
 
 export class NTQQUserApi {
   static async setQQAvatar(filePath: string) {
@@ -20,7 +21,7 @@ export class NTQQUserApi {
         },
         null,
       ],
-      timeoutSecond: 10, // 10秒不一定够
+      timeout: 10 * Time.second, // 10秒不一定够
     })
   }
 
@@ -28,7 +29,7 @@ export class NTQQUserApi {
     return await callNTQQApi<SelfInfo>({
       className: NTQQApiClass.GLOBAL_DATA,
       methodName: NTQQApiMethod.SELF_INFO,
-      timeoutSecond: 2,
+      timeout: 2 * Time.second,
     })
   }
 
@@ -41,33 +42,53 @@ export class NTQQUserApi {
     return result.profiles.get(uid)
   }
 
-  /** 26702 */
   static async fetchUserDetailInfo(uid: string) {
-    type EventService = NodeIKernelProfileService['fetchUserDetailInfo']
-    type EventListener = NodeIKernelProfileListener['onUserDetailInfoChanged']
-    const [_retData, profile] = await NTEventDispatch.CallNormalEvent
-      <EventService, EventListener>
-      (
-        'NodeIKernelProfileService/fetchUserDetailInfo',
-        'NodeIKernelProfileListener/onUserDetailInfoChanged',
-        1,
-        5000,
-        (profile) => profile.uid === uid,
-        'BuddyProfileStore',
-        [uid],
-        UserDetailSource.KSERVER,
-        [ProfileBizType.KALL]
-      )
-    const RetUser: User = {
-      ...profile.simpleInfo.coreInfo,
-      ...profile.simpleInfo.status,
-      ...profile.simpleInfo.vasInfo,
-      ...profile.commonExt,
-      ...profile.simpleInfo.baseInfo,
-      qqLevel: profile.commonExt.qqLevel,
+    let info: UserDetailInfoListenerArg
+    if (NTEventDispatch.initialised) {
+      type EventService = NodeIKernelProfileService['fetchUserDetailInfo']
+      type EventListener = NodeIKernelProfileListener['onUserDetailInfoChanged']
+      const [_retData, profile] = await NTEventDispatch.CallNormalEvent
+        <EventService, EventListener>
+        (
+          'NodeIKernelProfileService/fetchUserDetailInfo',
+          'NodeIKernelProfileListener/onUserDetailInfoChanged',
+          1,
+          5000,
+          (profile) => profile.uid === uid,
+          'BuddyProfileStore',
+          [uid],
+          UserDetailSource.KSERVER,
+          [ProfileBizType.KALL]
+        )
+      info = profile
+    } else {
+      const result = await callNTQQApi<{ info: UserDetailInfoListenerArg }>({
+        methodName: 'nodeIKernelProfileService/fetchUserDetailInfo',
+        cbCmd: 'nodeIKernelProfileListener/onUserDetailInfoChanged',
+        afterFirstCmd: false,
+        cmdCB: payload => payload.info.uid === uid,
+        args: [
+          {
+            callFrom: 'BuddyProfileStore',
+            uid: [uid],
+            source: UserDetailSource.KSERVER,
+            bizList: [ProfileBizType.KALL]
+          },
+          null
+        ],
+      })
+      info = result.info
+    }
+    const ret: User = {
+      ...info.simpleInfo.coreInfo,
+      ...info.simpleInfo.status,
+      ...info.simpleInfo.vasInfo,
+      ...info.commonExt,
+      ...info.simpleInfo.baseInfo,
+      qqLevel: info.commonExt?.qqLevel,
       pendantId: ''
     }
-    return RetUser
+    return ret
   }
 
   static async getUserDetailInfo(uid: string, getLevel = false, withBizInfo = true) {
@@ -115,7 +136,7 @@ export class NTQQUserApi {
     }
     return cookies
   }
-  
+
   static async getSkey(): Promise<string> {
     const clientKeyData = await NTQQUserApi.getClientKey()
     if (clientKeyData.result !== 0) {
diff --git a/src/ntqqapi/hook.ts b/src/ntqqapi/hook.ts
index cef1672..494b3db 100644
--- a/src/ntqqapi/hook.ts
+++ b/src/ntqqapi/hook.ts
@@ -77,15 +77,17 @@ let callHooks: Array<{
   hookFunc: (callParams: unknown[]) => void | Promise<void>
 }> = []
 
+const logHook = false
+
 export function hookNTQQApiReceive(window: BrowserWindow) {
   const originalSend = window.webContents.send
   const patchSend = (channel: string, ...args: NTQQApiReturnData) => {
-    /*try {
+    try {
       const isLogger = args[0]?.eventName?.startsWith('ns-LoggerApi')
-      if (!isLogger) {
+      if (logHook && !isLogger) {
         log(`received ntqq api message: ${channel}`, args)
       }
-    } catch { }*/
+    } catch { }
     if (args?.[1] instanceof Array) {
       for (const receiveData of args?.[1]) {
         const ntQQApiMethodName = receiveData.cmdName
@@ -134,9 +136,9 @@ export function hookNTQQApiCall(window: BrowserWindow) {
         isLogger = args[3][0].eventName.startsWith('ns-LoggerApi')
       } catch (e) { }
       if (!isLogger) {
-        /*try {
-          HOOK_LOG && log('call NTQQ api', thisArg, args)
-        } catch (e) { }*/
+        try {
+          logHook && log('call NTQQ api', thisArg, args)
+        } catch (e) { }
         try {
           const _args: unknown[] = args[3][1]
           const cmdName: NTQQApiMethod = _args[0] as NTQQApiMethod
@@ -145,13 +147,11 @@ export function hookNTQQApiCall(window: BrowserWindow) {
             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) {
+                  hook.hookFunc(callParams)
+                } catch (e: any) {
                   log('hook call error', e, _args)
                 }
+                resolve(undefined)
               }).then()
             }
           })
@@ -399,7 +399,7 @@ export async function startHook() {
         friendList.push(...fData.buddyList)
       }
     }
-    log('好友列表变动', friendList)
+    log('好友列表变动', friendList.length)
     for (let friend of friendList) {
       NTQQMsgApi.activateChat({ peerUid: friend.uid, chatType: ChatType.friend }).then()
       let existFriend = friends.find((f) => f.uin == friend.uin)
diff --git a/src/ntqqapi/ntcall.ts b/src/ntqqapi/ntcall.ts
index 9fec4d2..e172c57 100644
--- a/src/ntqqapi/ntcall.ts
+++ b/src/ntqqapi/ntcall.ts
@@ -1,7 +1,8 @@
 import { ipcMain } from 'electron'
-import { hookApiCallbacks, ReceiveCmd, ReceiveCmdS, registerReceiveHook, removeReceiveHook } from './hook'
+import { hookApiCallbacks, ReceiveCmd, registerReceiveHook, removeReceiveHook } from './hook'
 import { log } from '../common/utils/log'
 import { randomUUID } from 'node:crypto'
+import { GeneralCallResult } from './services/common'
 
 export enum NTQQApiClass {
   NT_API = 'ns-ntApi',
@@ -108,38 +109,24 @@ interface NTQQApiParams {
   cbCmd?: ReceiveCmd | ReceiveCmd[] | null
   cmdCB?: (payload: any) => boolean
   afterFirstCmd?: boolean // 是否在methodName调用完之后再去hook cbCmd
-  timeoutSecond?: number
+  timeout?: number
 }
 
 export function callNTQQApi<ReturnType>(params: NTQQApiParams) {
-  let {
-    className,
-    methodName,
-    channel,
-    args,
-    cbCmd,
-    timeoutSecond: timeout,
-    classNameIsRegister,
-    cmdCB,
-    afterFirstCmd,
-  } = params
-  className = className ?? NTQQApiClass.NT_API
-  channel = channel ?? NTQQApiChannel.IPC_UP_2
-  args = args ?? []
-  timeout = timeout ?? 5
-  afterFirstCmd = afterFirstCmd ?? true
+  const className = params.className ?? NTQQApiClass.NT_API
+  const channel = params.channel ?? NTQQApiChannel.IPC_UP_2
+  const timeout = params.timeout ?? 5000
+  const afterFirstCmd = params.afterFirstCmd ?? true
   const uuid = randomUUID()
-  //HOOK_LOG && log('callNTQQApi', channel, className, methodName, args, uuid)
+  let eventName = className + '-' + channel[channel.length - 1]
+  if (params.classNameIsRegister) {
+    eventName += '-register'
+  }
+  const apiArgs = [params.methodName, ...(params.args ?? [])]
+  //log('callNTQQApi', channel, eventName, apiArgs, uuid)
   return new Promise((resolve: (data: ReturnType) => void, reject) => {
-    // log("callNTQQApiPromise", channel, className, methodName, args, uuid)
-    const _timeout = timeout * 1000
     let success = false
-    let eventName = className + '-' + channel[channel.length - 1]
-    if (classNameIsRegister) {
-      eventName += '-register'
-    }
-    const apiArgs = [methodName, ...args]
-    if (!cbCmd) {
+    if (!params.cbCmd) {
       // QQ后端会返回结果,并且可以根据uuid识别
       hookApiCallbacks[uuid] = (r: ReturnType) => {
         success = true
@@ -149,10 +136,10 @@ export function callNTQQApi<ReturnType>(params: NTQQApiParams) {
     else {
       // 这里的callback比较特殊,QQ后端先返回是否调用成功,再返回一条结果数据
       const secondCallback = () => {
-        const hookId = registerReceiveHook<ReturnType>(cbCmd, (payload) => {
+        const hookId = registerReceiveHook<ReturnType>(params.cbCmd!, (payload) => {
           // log(methodName, "second callback", cbCmd, payload, cmdCB);
-          if (!!cmdCB) {
-            if (cmdCB(payload)) {
+          if (!!params.cmdCB) {
+            if (params.cmdCB(payload)) {
               removeReceiveHook(hookId)
               success = true
               resolve(payload)
@@ -167,8 +154,8 @@ export function callNTQQApi<ReturnType>(params: NTQQApiParams) {
       }
       !afterFirstCmd && secondCallback()
       hookApiCallbacks[uuid] = (result: GeneralCallResult) => {
-        log(`${methodName} callback`, result)
-        if (result?.result == 0 || result === undefined) {
+        log(`${params.methodName} callback`, result)
+        if (result?.result === 0 || result === undefined) {
           afterFirstCmd && secondCallback()
         }
         else {
@@ -180,10 +167,10 @@ export function callNTQQApi<ReturnType>(params: NTQQApiParams) {
     setTimeout(() => {
       // log("ntqq api timeout", success, channel, className, methodName)
       if (!success) {
-        log(`ntqq api timeout ${channel}, ${eventName}, ${methodName}`, apiArgs)
-        reject(`ntqq api timeout ${channel}, ${eventName}, ${methodName}, ${apiArgs}`)
+        log(`ntqq api timeout ${channel}, ${eventName}, ${params.methodName}`, apiArgs)
+        reject(`ntqq api timeout ${channel}, ${eventName}, ${params.methodName}, ${apiArgs}`)
       }
-    }, _timeout)
+    }, timeout)
 
     ipcMain.emit(
       channel,
@@ -199,7 +186,4 @@ export function callNTQQApi<ReturnType>(params: NTQQApiParams) {
   })
 }
 
-export interface GeneralCallResult {
-  result: number // 0: success
-  errMsg: string
-}
\ No newline at end of file
+export { GeneralCallResult }
\ No newline at end of file