Add emoji like event handling to core and onebot

Introduces a typed event emitter for app events in napcat-core, specifically for emoji like events in groups. OlPushService now emits 'event:emoji_like' when a group reaction is detected. napcat-onebot listens for this event and emits corresponding OneBot events. Refactors and adds missing type definitions and improves method formatting for consistency.
This commit is contained in:
手瓜一十雪
2025-11-15 10:45:02 +08:00
parent b7eadae081
commit e282cbdaba
6 changed files with 124 additions and 41 deletions

View File

@@ -32,6 +32,7 @@ import { proxiedListenerOf } from 'napcat-common/src/proxy-handler';
import { NTQQPacketApi } from './apis/packet';
import { NativePacketHandler } from './packet/handler/client';
import { container, ReceiverServiceRegistry } from './packet/handler/serviceRegister';
import { appEvent } from './packet/handler/eventList';
export * from './wrapper';
export * from './types/index';
export * from './services/index';
@@ -93,6 +94,7 @@ export function getMajorPath (QQVersion: string): string {
export class NapCatCore {
readonly context: InstanceContext;
readonly eventWrapper: NTEventWrapper;
event = appEvent;
NapCatDataPath: string = '';
NapCatTempPath: string = '';
apis: StableNTApiWrapper;

View File

@@ -0,0 +1,6 @@
import { TypedEventEmitter } from "./typeEvent";
export interface AppEvents {
'event:emoji_like': { groupId: string; senderUin: string; emojiId: string, msgSeq: string, isAdd: boolean,count:number };
}
export const appEvent = new TypedEventEmitter<AppEvents>();

View File

@@ -0,0 +1,22 @@
import { EventEmitter } from 'node:events';
export class TypedEventEmitter<E extends Record<string, any>> {
private emitter = new EventEmitter();
on<K extends keyof E>(event: K, listener: (payload: E[K]) => void) {
this.emitter.on(event as string, listener);
return () => this.off(event, listener);
}
once<K extends keyof E>(event: K, listener: (payload: E[K]) => void) {
this.emitter.once(event as string, listener);
}
off<K extends keyof E>(event: K, listener: (payload: E[K]) => void) {
this.emitter.off(event as string, listener);
}
emit<K extends keyof E>(event: K, payload: E[K]) {
this.emitter.emit(event as string, payload);
}
}

View File

@@ -1,8 +1,38 @@
import { NapProtoMsg } from "napcat-protobuf";
import { appEvent } from "../packet/handler/eventList";
import { ReceiveService, ServiceBase } from "../packet/handler/serviceRegister";
import { GroupReactNotify, PushMsg } from "../packet/transformer/proto";
// @ReceiveService('trpc.msg.olpush.OlPushService.MsgPush')
// export class OlPushService extends ServiceBase {
// async handler(seq: number, hex_data: string) {
// console.log(`OlPushService handler called with seq: ${seq} and data: ${hex_data}`);
// }
// }
@ReceiveService('trpc.msg.olpush.OlPushService.MsgPush')
export class OlPushService extends ServiceBase {
async handler(_seq: number, hex_data: string) {
const data = new NapProtoMsg(PushMsg).decode(Buffer.from(hex_data, 'hex'));
if (data.message.contentHead.type === 732 && data.message.contentHead.subType === 16) {
const pbNotify = data.message.body?.msgContent?.slice(7);
if (!pbNotify) {
return;
}
// 开始解析Notify
const notify = new NapProtoMsg(GroupReactNotify).decode(pbNotify);
if ((notify.field13 ?? 0) === 35) {
// Group React Notify
const groupCode = notify.groupUin?.toString() ?? '';
const operatorUid = notify.groupReactionData?.data?.data?.groupReactionDataContent?.operatorUid ?? '';
const type = notify.groupReactionData?.data?.data?.groupReactionDataContent?.type ?? 0;
const seq = notify.groupReactionData?.data?.data?.groupReactionTarget?.seq?.toString() ?? '';
const code = notify.groupReactionData?.data?.data?.groupReactionDataContent?.code ?? '';
const count = notify.groupReactionData?.data?.data?.groupReactionDataContent?.count ?? 0;
const senderUin = await this.core.apis.UserApi.getUinByUidV2(operatorUid);
appEvent.emit('event:emoji_like', {
groupId: groupCode,
senderUin: senderUin,
emojiId: code,
msgSeq: seq,
isAdd: type === 1,
count: count
});
}
}
}
}