diff --git a/src/main/main.ts b/src/main/main.ts
index a1b1032..c103f37 100644
--- a/src/main/main.ts
+++ b/src/main/main.ts
@@ -198,6 +198,13 @@ function onLoad() {
           postOb11Event(privateEvent)
         }
       })
+      // OB11Constructor.FriendAddEvent(message).then((friendAddEvent) => {
+      //   log(message)
+      //   if (friendAddEvent) {
+      //     // log("post friend add event", friendAddEvent);
+      //     postOb11Event(friendAddEvent)
+      //   }
+      // })
     }
   }
 
@@ -216,7 +223,7 @@ function onLoad() {
             pokeEvent = new OB11GroupPokeEvent(parseInt(id))
           }
           else {
-            pokeEvent = new OB11FriendPokeEvent(parseInt(id))
+            pokeEvent = new OB11FriendPokeEvent(parseInt(selfInfo.uin), parseInt(id))
           }
           postOb11Event(pokeEvent)
         })
@@ -311,34 +318,36 @@ function onLoad() {
             // if (notify.user2.uid) {
             //     member2 = await getGroupMember(notify.group.groupCode, null, notify.user2.uid);
             // }
-            if (
-              [GroupNotifyTypes.ADMIN_SET, GroupNotifyTypes.ADMIN_UNSET, GroupNotifyTypes.ADMIN_UNSET_OTHER].includes(
-                notify.type,
-              )
-            ) {
-              const member1 = await getGroupMember(notify.group.groupCode, notify.user1.uid)
-              log('有管理员变动通知')
-              refreshGroupMembers(notify.group.groupCode).then()
-              let groupAdminNoticeEvent = new OB11GroupAdminNoticeEvent()
-              groupAdminNoticeEvent.group_id = parseInt(notify.group.groupCode)
-              log('开始获取变动的管理员')
-              if (member1) {
-                log('变动管理员获取成功')
-                groupAdminNoticeEvent.user_id = parseInt(member1.uin)
-                groupAdminNoticeEvent.sub_type = [
-                  GroupNotifyTypes.ADMIN_UNSET,
-                  GroupNotifyTypes.ADMIN_UNSET_OTHER,
-                ].includes(notify.type)
-                  ? 'unset'
-                  : 'set'
-                // member1.role = notify.type == GroupNotifyTypes.ADMIN_SET ? GroupMemberRole.admin : GroupMemberRole.normal;
-                postOb11Event(groupAdminNoticeEvent, true)
-              }
-              else {
-                log('获取群通知的成员信息失败', notify, getGroup(notify.group.groupCode))
-              }
-            }
-            else if (notify.type == GroupNotifyTypes.MEMBER_EXIT || notify.type == GroupNotifyTypes.KICK_MEMBER) {
+            // 原本的群管变更通知事件处理
+            // if (
+            //   [GroupNotifyTypes.ADMIN_SET, GroupNotifyTypes.ADMIN_UNSET, GroupNotifyTypes.ADMIN_UNSET_OTHER].includes(
+            //     notify.type,
+            //   )
+            // ) {
+            //   const member1 = await getGroupMember(notify.group.groupCode, notify.user1.uid)
+            //   log('有管理员变动通知')
+            //   refreshGroupMembers(notify.group.groupCode).then()
+            //   let groupAdminNoticeEvent = new OB11GroupAdminNoticeEvent()
+            //   groupAdminNoticeEvent.group_id = parseInt(notify.group.groupCode)
+            //   log('开始获取变动的管理员')
+            //   if (member1) {
+            //     log('变动管理员获取成功')
+            //     groupAdminNoticeEvent.user_id = parseInt(member1.uin)
+            //     groupAdminNoticeEvent.sub_type = [
+            //       GroupNotifyTypes.ADMIN_UNSET,
+            //       GroupNotifyTypes.ADMIN_UNSET_OTHER,
+            //     ].includes(notify.type)
+            //       ? 'unset'
+            //       : 'set'
+            //     // member1.role = notify.type == GroupNotifyTypes.ADMIN_SET ? GroupMemberRole.admin : GroupMemberRole.normal;
+            //     postOb11Event(groupAdminNoticeEvent, true)
+            //   }
+            //   else {
+            //     log('获取群通知的成员信息失败', notify, getGroup(notify.group.groupCode))
+            //   }
+            // }
+            // else 
+            if (notify.type == GroupNotifyTypes.MEMBER_EXIT || notify.type == GroupNotifyTypes.KICK_MEMBER) {
               log('有成员退出通知', notify)
               try {
                 const member1 = await NTQQUserApi.getUserDetailInfo(notify.user1.uid)
diff --git a/src/ntqqapi/api/group.ts b/src/ntqqapi/api/group.ts
index 06d00c5..6617dcc 100644
--- a/src/ntqqapi/api/group.ts
+++ b/src/ntqqapi/api/group.ts
@@ -5,6 +5,7 @@ import { deleteGroup, uidMaps } from '../../common/data'
 import { dbUtil } from '../../common/db'
 import { log } from '../../common/utils/log'
 import { NTQQWindowApi, NTQQWindows } from './window'
+import { wrapperApi } from '../native/wrapper'
 
 export class NTQQGroupApi {
 
@@ -282,4 +283,28 @@ export class NTQQGroupApi {
     })
   }
   static publishGroupBulletin(groupQQ: string, title: string, content: string) {}
+  static async removeGroupEssence(GroupCode: string, msgId: string) {
+    // 代码没测过
+    // 需要 ob11msgid->msgId + (peer) -> msgSeq + msgRandom
+    let MsgData = await wrapperApi.NodeIQQNTWrapperSession.getMsgService().getMsgsIncludeSelf({ chatType: 2, guildId: '', peerUid: GroupCode }, msgId, 1, false);
+    let param = {
+      groupCode: GroupCode,
+      msgRandom: parseInt(MsgData.msgList[0].msgRandom),
+      msgSeq: parseInt(MsgData.msgList[0].msgSeq)
+    };
+    // GetMsgByShoretID(ShoretID); -> MsgService.getMsgs(Peer,MsgId,1,false); -> 组出参数
+    return wrapperApi.NodeIQQNTWrapperSession.getGroupService().removeGroupEssence(param);
+  }
+  static async addGroupEssence(GroupCode: string, msgId: string) {
+    // 代码没测过
+    // 需要 ob11msgid->msgId + (peer) -> msgSeq + msgRandom
+    let MsgData = await wrapperApi.NodeIQQNTWrapperSession.getMsgService().getMsgsIncludeSelf({ chatType: 2, guildId: '', peerUid: GroupCode }, msgId, 1, false);
+    let param = {
+      groupCode: GroupCode,
+      msgRandom: parseInt(MsgData.msgList[0].msgRandom),
+      msgSeq: parseInt(MsgData.msgList[0].msgSeq)
+    };
+    // GetMsgByShoretID(ShoretID); -> MsgService.getMsgs(Peer,MsgId,1,false); -> 组出参数
+    return wrapperApi.NodeIQQNTWrapperSession.getGroupService().addGroupEssence(param);
+  }
 }
diff --git a/src/ntqqapi/api/msg.ts b/src/ntqqapi/api/msg.ts
index 54ca551..1bd2da8 100644
--- a/src/ntqqapi/api/msg.ts
+++ b/src/ntqqapi/api/msg.ts
@@ -1,22 +1,17 @@
 import { callNTQQApi, GeneralCallResult, NTQQApiMethod } from '../ntcall'
-import { ChatType, RawMessage, SendMessageElement } from '../types'
+import { ChatType, RawMessage, SendMessageElement, Peer } from '../types'
 import { dbUtil } from '../../common/db'
 import { selfInfo } from '../../common/data'
 import { ReceiveCmdS, registerReceiveHook } from '../hook'
 import { log } from '../../common/utils/log'
 import { sleep } from '../../common/utils/helper'
 import { isQQ998 } from '../../common/utils'
+import { wrapperApi } from '@/ntqqapi/native/wrapper'
 
 export let sendMessagePool: Record<string, ((sendSuccessMsg: RawMessage) => void) | null> = {} // peerUid: callbackFunc
 
 export let sentMessages: Record<string, RawMessage> = {}  // msgId: RawMessage
 
-export interface Peer {
-  chatType: ChatType
-  peerUid: string // 如果是群聊uid为群号,私聊uid就是加密的字符串
-  guildId?: ''
-}
-
 async function sendWaiter(peer: Peer, waitComplete = true, timeout: number = 10000) {
   // 等待上一个相同的peer发送完
   const peerUid = peer.peerUid
@@ -293,4 +288,7 @@ export class NTQQMsgApi {
       })
     })
   }
+  static async getMsgsBySeqAndCount(peer: Peer, seq: string, count: number, desc: boolean, z: boolean) {
+    return await wrapperApi.NodeIQQNTWrapperSession.getMsgService().getMsgsBySeqAndCount(peer, seq, count, desc, z);
+  }
 }
diff --git a/src/ntqqapi/hook.ts b/src/ntqqapi/hook.ts
index ca2708d..3e9fee6 100644
--- a/src/ntqqapi/hook.ts
+++ b/src/ntqqapi/hook.ts
@@ -23,6 +23,7 @@ import { log } from '@/common/utils'
 import { isNumeric, sleep } from '@/common/utils'
 import { OB11Constructor } from '../onebot11/constructor'
 import { OB11GroupCardEvent } from '../onebot11/event/notice/OB11GroupCardEvent'
+import { OB11GroupAdminNoticeEvent } from '../onebot11/event/notice/OB11GroupAdminNoticeEvent'
 
 export let hookApiCallbacks: Record<string, (apiReturn: any) => void> = {}
 
@@ -369,6 +370,13 @@ export async function startHook() {
           postOb11Event(
             new OB11GroupCardEvent(parseInt(groupCode), parseInt(member.uin), member.cardName, existMember.cardName),
           )
+        } else if (member.role != existMember.role) {
+          log('有管理员变动通知')
+          let groupAdminNoticeEvent = new OB11GroupAdminNoticeEvent()
+          groupAdminNoticeEvent.group_id = parseInt(groupCode)
+          groupAdminNoticeEvent.user_id = parseInt(member.uin)
+          groupAdminNoticeEvent.sub_type = member.role == GroupMemberRole.admin ? 'set' : 'unset'
+          postOb11Event(groupAdminNoticeEvent, true)
         }
         Object.assign(existMember, member)
       }
diff --git a/src/ntqqapi/types/msg.ts b/src/ntqqapi/types/msg.ts
index 1e74520..e50295f 100644
--- a/src/ntqqapi/types/msg.ts
+++ b/src/ntqqapi/types/msg.ts
@@ -415,3 +415,9 @@ export interface RawMessage {
     multiForwardMsgElement: MultiForwardMsgElement
   }[]
 }
+
+export interface Peer {
+  chatType: ChatType;
+  peerUid: string;  // 如果是群聊uid为群号,私聊uid就是加密的字符串
+  guildId?: string;
+}
\ No newline at end of file
diff --git a/src/onebot11/action/go-cqhttp/DelEssenceMsg.ts b/src/onebot11/action/go-cqhttp/DelEssenceMsg.ts
new file mode 100644
index 0000000..2bc5c3b
--- /dev/null
+++ b/src/onebot11/action/go-cqhttp/DelEssenceMsg.ts
@@ -0,0 +1,24 @@
+
+import BaseAction from '../BaseAction';
+import { ActionName } from '../types';
+import { NTQQGroupApi } from '../../../ntqqapi/api/group'
+import { dbUtil } from '@/common/db';
+
+interface Payload {
+  message_id: number | string;
+}
+
+export default class GoCQHTTPDelEssenceMsg extends BaseAction<Payload, any> {
+  actionName = ActionName.GoCQHTTP_DelEssenceMsg;
+
+  protected async _handle(payload: Payload): Promise<any> {
+    const msg = await dbUtil.getMsgByShortId(parseInt(payload.message_id.toString()));
+    if (!msg) {
+      throw new Error('msg not found');
+    }
+    return await NTQQGroupApi.removeGroupEssence(
+      msg.peerUid,
+      msg.msgId
+    );
+  }
+}
diff --git a/src/onebot11/action/go-cqhttp/SetEssenceMsg.ts b/src/onebot11/action/go-cqhttp/SetEssenceMsg.ts
new file mode 100644
index 0000000..682eddd
--- /dev/null
+++ b/src/onebot11/action/go-cqhttp/SetEssenceMsg.ts
@@ -0,0 +1,23 @@
+import BaseAction from '../BaseAction';
+import { ActionName } from '../types';
+import { NTQQGroupApi } from '../../../ntqqapi/api/group'
+import { dbUtil } from '@/common/db';
+
+interface Payload {
+    message_id: number | string;
+}
+
+export default class GoCQHTTPSetEssenceMsg extends BaseAction<Payload, any> {
+  actionName = ActionName.GoCQHTTP_SetEssenceMsg;
+
+  protected async _handle(payload: Payload): Promise<any> {
+    const msg = await dbUtil.getMsgByShortId(parseInt(payload.message_id.toString()));
+    if (!msg) {
+      throw new Error('msg not found');
+    }
+    return await NTQQGroupApi.addGroupEssence(
+      msg.peerUid,
+      msg.msgId
+    );
+  }
+}
diff --git a/src/onebot11/action/index.ts b/src/onebot11/action/index.ts
index 3785082..a0a8b02 100644
--- a/src/onebot11/action/index.ts
+++ b/src/onebot11/action/index.ts
@@ -50,6 +50,10 @@ import { ForwardFriendSingleMsg, ForwardGroupSingleMsg } from './msg/ForwardSing
 import { GetGroupEssence } from './group/GetGroupEssence'
 import { GetGroupHonorInfo } from './group/GetGroupHonorInfo'
 import { GoCQHTTHandleQuickOperation } from './go-cqhttp/QuickOperation'
+import GoCQHTTPSetEssenceMsg from './go-cqhttp/SetEssenceMsg'
+import GoCQHTTPDelEssenceMsg from './go-cqhttp/DelEssenceMsg'
+import GetEvent from './llonebot/GetEvent'
+
 
 export const actionHandlers = [
   new GetFile(),
@@ -59,6 +63,7 @@ export const actionHandlers = [
   new GetGroupAddRequest(),
   new SetQQAvatar(),
   new GetFriendWithCategory(),
+  new GetEvent(),
   // onebot11
   new SendLike(),
   new GetMsg(),
@@ -106,7 +111,9 @@ export const actionHandlers = [
   new GoCQHTTPUploadPrivateFile(),
   new GoCQHTTPGetGroupMsgHistory(),
   new GoCQHTTGetForwardMsgAction(),
-  new GoCQHTTHandleQuickOperation()
+  new GoCQHTTHandleQuickOperation(),
+  new GoCQHTTPSetEssenceMsg(),
+  new GoCQHTTPDelEssenceMsg()
 ]
 
 function initActionMap() {
diff --git a/src/onebot11/action/llonebot/GetEvent.ts b/src/onebot11/action/llonebot/GetEvent.ts
new file mode 100644
index 0000000..09827b1
--- /dev/null
+++ b/src/onebot11/action/llonebot/GetEvent.ts
@@ -0,0 +1,23 @@
+import BaseAction from '../BaseAction'
+import { ActionName } from '../types'
+import { getHttpEvent } from '../../server/event-for-http'
+import { PostEventType } from '../../server/post-ob11-event'
+// import { log } from "../../../common/utils";
+
+interface Payload {
+  key: string
+  timeout: number
+}
+
+export default class GetEvent extends BaseAction<Payload, PostEventType[]> {
+  actionName = ActionName.GetEvent
+  protected async _handle(payload: Payload): Promise<PostEventType[]> {
+    let key = ''
+    if (payload.key) {
+      key = payload.key;
+    }
+    let timeout = parseInt(payload.timeout?.toString()) || 0;
+    let evts = await getHttpEvent(key,timeout);
+    return evts;
+  }
+}
diff --git a/src/onebot11/action/types.ts b/src/onebot11/action/types.ts
index 1b61ecc..88cdd0f 100644
--- a/src/onebot11/action/types.ts
+++ b/src/onebot11/action/types.ts
@@ -22,6 +22,7 @@ export enum ActionName {
   Debug = 'llonebot_debug',
   GetFile = 'get_file',
   GetFriendsWithCategory = 'get_friends_with_category',
+  GetEvent = 'get_event',
   // onebot 11
   SendLike = 'send_like',
   GetLoginInfo = 'get_login_info',
@@ -70,4 +71,6 @@ export enum ActionName {
   GoCQHTTP_GetEssenceMsg = "get_essence_msg_list",
   GoCQHTTP_HandleQuickOperation = ".handle_quick_operation",
   GetGroupHonorInfo = "get_group_honor_info",
+  GoCQHTTP_SetEssenceMsg = 'set_essence_msg',
+  GoCQHTTP_DelEssenceMsg = 'delete_essence_msg',
 }
diff --git a/src/onebot11/constructor.ts b/src/onebot11/constructor.ts
index addc4fb..df39b01 100644
--- a/src/onebot11/constructor.ts
+++ b/src/onebot11/constructor.ts
@@ -15,6 +15,7 @@ import {
   FaceIndex,
   GrayTipElementSubType,
   Group,
+  Peer,
   GroupMember,
   PicType,
   RawMessage,
@@ -34,6 +35,7 @@ import { OB11GroupUploadNoticeEvent } from './event/notice/OB11GroupUploadNotice
 import { OB11GroupNoticeEvent } from './event/notice/OB11GroupNoticeEvent'
 import { NTQQUserApi } from '../ntqqapi/api/user'
 import { NTQQFileApi } from '../ntqqapi/api/file'
+import { NTQQMsgApi } from '../ntqqapi/api/msg'
 import { calcQQLevel } from '../common/utils/qqlevel'
 import { log } from '../common/utils/log'
 import { sleep } from '../common/utils/helper'
@@ -49,6 +51,7 @@ import { OB11FriendRecallNoticeEvent } from './event/notice/OB11FriendRecallNoti
 import { OB11GroupRecallNoticeEvent } from './event/notice/OB11GroupRecallNoticeEvent'
 import { OB11FriendPokeEvent, OB11GroupPokeEvent } from './event/notice/OB11PokeEvent'
 import { OB11BaseNoticeEvent } from './event/notice/OB11BaseNoticeEvent';
+import { OB11GroupEssenceEvent } from './event/notice/OB11GroupEssenceEvent';
 
 let lastRKeyUpdateTime = 0
 
@@ -109,33 +112,40 @@ export class OB11Constructor {
     }
 
     for (let element of msg.elements) {
-      let message_data: OB11MessageData | any = {
-        data: {},
-        type: 'unknown',
+      let message_data: OB11MessageData = {
+        data: {} as any,
+        type: 'unknown' as any,
       }
       if (element.textElement && element.textElement?.atType !== AtType.notAt) {
-        message_data['type'] = OB11MessageDataType.at
+        let qq: string
+        let name: string | undefined
         if (element.textElement.atType == AtType.atAll) {
-          // message_data["data"]["mention"] = "all"
-          message_data['data']['qq'] = 'all'
+          qq = 'all'
         }
         else {
-          let atUid = element.textElement.atNtUid
+          const { atNtUid, content } = element.textElement
           let atQQ = element.textElement.atUid
           if (!atQQ || atQQ === '0') {
-            const atMember = await getGroupMember(msg.peerUin, atUid)
+            const atMember = await getGroupMember(msg.peerUin, atNtUid)
             if (atMember) {
               atQQ = atMember.uin
             }
           }
           if (atQQ) {
-            // message_data["data"]["mention"] = atQQ
-            message_data['data']['qq'] = atQQ
+            qq = atQQ
+            name = content.replace('@', '')
+          }
+        }
+        message_data = {
+          type: OB11MessageDataType.at,
+          data: {
+            qq,
+            name
           }
         }
       }
       else if (element.textElement) {
-        message_data['type'] = 'text'
+        message_data['type'] = OB11MessageDataType.text
         let text = element.textElement.content
         if (!text.trim()) {
           continue
@@ -143,7 +153,7 @@ export class OB11Constructor {
         message_data['data']['text'] = text
       }
       else if (element.replyElement) {
-        message_data['type'] = 'reply'
+        message_data['type'] = OB11MessageDataType.reply
         // log("收到回复消息", element.replyElement.replayMsgSeq)
         try {
           const replyMsg = await dbUtil.getMsgBySeqId(element.replyElement.replayMsgSeq)
@@ -159,7 +169,7 @@ export class OB11Constructor {
         }
       }
       else if (element.picElement) {
-        message_data['type'] = 'image'
+        message_data['type'] = OB11MessageDataType.image
         // message_data["data"]["file"] = element.picElement.sourcePath
         let fileName = element.picElement.fileName
         const sourcePath = element.picElement.sourcePath
@@ -204,9 +214,9 @@ export class OB11Constructor {
         message_data['data']['file_size'] = videoOrFileElement.fileSize
         if (element.videoElement) {
           message_data['data']['url'] = await NTQQFileApi.getVideoUrl({
-              chatType: msg.chatType,
-              peerUid: msg.peerUid,
-            }, msg.msgId, element.elementId,
+            chatType: msg.chatType,
+            peerUid: msg.peerUid,
+          }, msg.msgId, element.elementId,
           )
         }
         dbUtil
@@ -296,7 +306,7 @@ export class OB11Constructor {
         message_data['type'] = OB11MessageDataType.forward
         message_data['data']['id'] = msg.msgId
       }
-      if (message_data.type !== 'unknown' && message_data.data) {
+      if ((message_data.type as string) !== 'unknown' && message_data.data) {
         const cqCode = encodeCQCode(message_data)
         if (messagePostFormat === 'string') {
           (resMsg.message as string) += cqCode
@@ -321,11 +331,11 @@ export class OB11Constructor {
           if (element.grayTipElement.jsonGrayTipElement.busiId == 1061) {
             //判断业务类型
             //Poke事件
-            let pokedetail: any[] = json.items;
+            const pokedetail: any[] = json.items;
             //筛选item带有uid的元素
-            pokedetail = pokedetail.filter(item => item.uid);
-            if (pokedetail.length == 2) {
-              return new OB11FriendPokeEvent(parseInt((uidMaps[pokedetail[0].uid])!), parseInt((uidMaps[pokedetail[1].uid])));
+            const poke_uid = pokedetail.filter(item => item.uid);
+            if (poke_uid.length == 2) {
+              return new OB11FriendPokeEvent(parseInt((uidMaps[poke_uid[0].uid])!), parseInt((uidMaps[poke_uid[1].uid])), pokedetail);
             }
           }
           //下面得改 上面也是错的grayTipElement.subElementType == GrayTipElementSubType.MEMBER_NEW_TITLE
@@ -526,20 +536,43 @@ export class OB11Constructor {
           if (grayTipElement.jsonGrayTipElement.busiId == 1061) {
             //判断业务类型
             //Poke事件
-            let pokedetail: any[] = json.items;
+            const pokedetail: any[] = json.items;
             //筛选item带有uid的元素
-            pokedetail = pokedetail.filter(item => item.uid);
-            if (pokedetail.length == 2) {
-              return new OB11GroupPokeEvent(parseInt(msg.peerUid), parseInt((uidMaps[pokedetail[0].uid])!), parseInt((uidMaps[pokedetail[1].uid])));
+            const poke_uid = pokedetail.filter(item => item.uid);
+            if (poke_uid.length == 2) {
+              return new OB11GroupPokeEvent(parseInt(msg.peerUid), parseInt((uidMaps[poke_uid[0].uid])!), parseInt((uidMaps[poke_uid[1].uid])), pokedetail);
             }
           }
-          const memberUin = json.items[1].param[0]
-          const title = json.items[3].txt
-          log('收到群成员新头衔消息', json)
-          getGroupMember(msg.peerUid, memberUin).then((member) => {
-            member.memberSpecialTitle = title
-          })
-          return new OB11GroupTitleEvent(parseInt(msg.peerUid), parseInt(memberUin), title)
+          if (grayTipElement.jsonGrayTipElement.busiId == 2401) {
+            log('收到群精华消息', json)
+            const searchParams = new URL(json.items[0].jp).searchParams;
+            const msgSeq = searchParams.get('msgSeq')!;
+            const Group = searchParams.get('groupCode');
+            const Businessid = searchParams.get('businessid');
+            const Peer: Peer = {
+              guildId: '',
+              chatType: ChatType.group,
+              peerUid: Group!
+            };
+            let msgList = (await NTQQMsgApi.getMsgsBySeqAndCount(Peer, msgSeq.toString(), 1, true, true)).msgList;
+            const origMsg = await dbUtil.getMsgByLongId(msgList[0].msgId);
+            const postMsg = await dbUtil.getMsgBySeqId(origMsg.msgSeq) ?? origMsg;
+            // 如果 senderUin 为 0,可能是 历史消息 或 自身消息
+            if (msgList[0].senderUin === '0') {
+                msgList[0].senderUin = postMsg?.senderUin ?? selfInfo.uin;
+            }
+            return new OB11GroupEssenceEvent(parseInt(msg.peerUid), postMsg.msgShortId, parseInt(msgList[0].senderUin));
+            // 获取MsgSeq+Peer可获取具体消息
+          }
+          if (grayTipElement.jsonGrayTipElement.busiId == 2407) {
+            const memberUin = json.items[1].param[0]
+            const title = json.items[3].txt
+            log('收到群成员新头衔消息', json)
+            getGroupMember(msg.peerUid, memberUin).then((member) => {
+              member.memberSpecialTitle = title
+            })
+            return new OB11GroupTitleEvent(parseInt(msg.peerUid), parseInt(memberUin), title)
+          }
         }
       }
     }
diff --git a/src/onebot11/cqcode.ts b/src/onebot11/cqcode.ts
index 6b61160..6ffcddb 100644
--- a/src/onebot11/cqcode.ts
+++ b/src/onebot11/cqcode.ts
@@ -50,7 +50,6 @@ export function encodeCQCode(data: OB11MessageData) {
   }
 
   const CQCodeEscape = (text: string) => {
-    text = text.toString()
     return text.replace(/\&/g, '&amp;').replace(/\[/g, '&#91;').replace(/\]/g, '&#93;').replace(/,/g, '&#44;')
   }
 
@@ -61,15 +60,15 @@ export function encodeCQCode(data: OB11MessageData) {
   let result = '[CQ:' + data.type
   for (const name in data.data) {
     const value = data.data[name]
+    if (value === undefined) {
+      continue
+    }
     try {
-      // Check if the value can be converted to a string
-      value.toString();
+      const text = value.toString()
+      result += `,${name}=${CQCodeEscape(text)}`
     } catch (error) {
       // If it can't be converted, skip this name-value pair
-      // console.warn(`Skipping problematic name-value pair. Name: ${name}, Value: ${value}`);
-      continue;
     }
-    result += `,${name}=${CQCodeEscape(value)}`
   }
   result += ']'
   return result
diff --git a/src/onebot11/event/notice/OB11GroupEssenceEvent.ts b/src/onebot11/event/notice/OB11GroupEssenceEvent.ts
new file mode 100644
index 0000000..ae1053e
--- /dev/null
+++ b/src/onebot11/event/notice/OB11GroupEssenceEvent.ts
@@ -0,0 +1,14 @@
+import { OB11GroupNoticeEvent } from './OB11GroupNoticeEvent';
+export class OB11GroupEssenceEvent extends OB11GroupNoticeEvent {
+  notice_type = 'essence';
+  message_id: number;
+  sender_id: number;
+  sub_type: 'add' | 'delete' = 'add';
+
+  constructor(groupId: number, message_id: number, sender_id: number) {
+    super();
+    this.group_id = groupId;
+    this.message_id = message_id;
+    this.sender_id = sender_id;
+  }
+}
diff --git a/src/onebot11/event/notice/OB11PokeEvent.ts b/src/onebot11/event/notice/OB11PokeEvent.ts
index 4811a35..0f98ef6 100644
--- a/src/onebot11/event/notice/OB11PokeEvent.ts
+++ b/src/onebot11/event/notice/OB11PokeEvent.ts
@@ -5,25 +5,28 @@ import { OB11BaseEvent } from '../OB11BaseEvent'
 class OB11PokeEvent extends OB11BaseNoticeEvent {
   notice_type = 'notify'
   sub_type = 'poke'
-  target_id = parseInt(selfInfo.uin)
+  target_id = 0
   user_id: number
+  raw_message: any
 }
 
 export class OB11FriendPokeEvent extends OB11PokeEvent {
-  constructor(user_id: number, target_id: number) {
+
+  constructor(user_id: number, target_id: number, raw_message: any) {
     super();
     this.target_id = target_id;
     this.user_id = user_id;
+    this.raw_message = raw_message;
   }
 }
 
 export class OB11GroupPokeEvent extends OB11PokeEvent {
   group_id: number
-
-  constructor(group_id: number, user_id: number = 0, target_id: number = 0) {
+  constructor(group_id: number, user_id: number = 0, target_id: number = 0, raw_message: any) {
     super()
     this.group_id = group_id
     this.target_id = target_id
     this.user_id = user_id
+    this.raw_message = raw_message
   }
 }
diff --git a/src/onebot11/server/event-for-http.ts b/src/onebot11/server/event-for-http.ts
new file mode 100644
index 0000000..086aa2a
--- /dev/null
+++ b/src/onebot11/server/event-for-http.ts
@@ -0,0 +1,68 @@
+import { PostEventType } from "./post-ob11-event"
+
+
+interface HttpEventType {
+    seq: number
+    event: PostEventType
+}
+
+interface HttpUserType {
+    lastAccessTime: number
+    userSeq: number
+}
+
+let curentSeq:number = 0;
+let eventList:HttpEventType[] = [];
+let httpUser:Record<string,HttpUserType> = {};
+
+
+export function postHttpEvent(event: PostEventType) {
+    curentSeq += 1;
+    eventList.push({
+        seq: curentSeq,
+        event: event
+    });
+    while(eventList.length > 100) {
+        eventList.shift();
+    }
+}
+
+
+export async function getHttpEvent(userKey:string,timeout = 0) {
+    let toRetEvent = [];
+
+    // 清除过时的user,5分钟没访问过的user将被删除
+    let now = Date.now();
+    for(let key in httpUser) {
+        let user = httpUser[key];
+        if(now - user.lastAccessTime > 1000 * 60 * 5) {
+            delete httpUser[key];
+        }
+    }
+
+    // 增加新的user
+    if(!httpUser[userKey] ) {
+        httpUser[userKey] = {
+            lastAccessTime: now,
+            userSeq: curentSeq
+        }
+    }
+
+    let user = httpUser[userKey];
+    // 等待数据到来,暂时先这么写吧......
+    while(curentSeq == user.userSeq && Date.now() - now < timeout) {
+        await new Promise( resolve => setTimeout(resolve, 10) );
+    }
+    // 取数据
+    for(let i = 0; i < eventList.length; i++) {
+        let evt = eventList[i];
+        if(evt.seq > user.userSeq) {
+            toRetEvent.push(evt.event);
+        }
+    }
+
+    // 更新user数据
+    user.lastAccessTime = Date.now();
+    user.userSeq = curentSeq;
+    return toRetEvent;
+}
diff --git a/src/onebot11/server/post-ob11-event.ts b/src/onebot11/server/post-ob11-event.ts
index d78f130..c781ea6 100644
--- a/src/onebot11/server/post-ob11-event.ts
+++ b/src/onebot11/server/post-ob11-event.ts
@@ -8,6 +8,7 @@ import { log } from '@/common/utils'
 import { getConfigUtil } from '@/common/config'
 import crypto from 'crypto'
 import { handleQuickOperation, QuickOperationEvent } from '../action/quick-operation'
+import { postHttpEvent } from './event-for-http'
 
 export type PostEventType = OB11Message | OB11BaseMetaEvent | OB11BaseNoticeEvent
 
@@ -78,4 +79,9 @@ export function postOb11Event(msg: PostEventType, reportSelf = false, postWs = t
   if (postWs) {
     postWsEvent(msg)
   }
+  if(!(msg.post_type == 'meta_event' && (msg as OB11BaseMetaEvent).meta_event_type == 'heartbeat')) {
+    // 不上报心跳
+    postHttpEvent(msg)
+  }
+  
 }
diff --git a/src/onebot11/types.ts b/src/onebot11/types.ts
index de9c2ed..90a9f3c 100644
--- a/src/onebot11/types.ts
+++ b/src/onebot11/types.ts
@@ -195,6 +195,7 @@ export interface OB11MessageAt {
   type: OB11MessageDataType.at
   data: {
     qq: string | 'all'
+    name?: string
   }
 }
 
@@ -241,6 +242,20 @@ export interface OB11MessageJson {
   data: { data: string /* , config: { token: string } */ }
 }
 
+export interface OB11MessageMarkdown {
+  type: OB11MessageDataType.markdown
+  data: {
+    data: string
+  }
+}
+
+export interface OB11MessageForward {
+  type: OB11MessageDataType.forward
+  data: {
+    id: string
+  }
+}
+
 export type OB11MessageData =
   | OB11MessageText
   | OB11MessageFace
@@ -258,6 +273,8 @@ export type OB11MessageData =
   | OB11MessagePoke
   | OB11MessageDice
   | OB11MessageRPS
+  | OB11MessageMarkdown
+  | OB11MessageForward
 
 export interface OB11PostSendMsg {
   message_type?: 'private' | 'group'