kt-template-online-api/src/qqbot/event/qqbot-event-normalizer.ts

88 lines
2.3 KiB
TypeScript

import type {
QqbotMessageType,
QqbotNormalizedMessage,
QqbotOneBotEvent,
} from '../qqbot.types';
import { toStringId } from '../qqbot.utils';
export function isOneBotMessageEvent(
payload: QqbotOneBotEvent,
): payload is QqbotOneBotEvent & { message_type: string } {
return (
payload?.post_type === 'message' &&
!!normalizeMessageType(payload.message_type)
);
}
export function normalizeOneBotMessage(
payload: QqbotOneBotEvent,
): QqbotNormalizedMessage {
const messageType = normalizeMessageType(payload.message_type) || 'private';
const channelId =
toStringId(payload.channel_id) || toStringId(payload.guild_id) || undefined;
const groupId = toStringId(payload.group_id) || undefined;
const userId = toStringId(payload.user_id);
const targetId =
messageType === 'group'
? groupId || ''
: messageType === 'channel'
? channelId || ''
: userId;
const messageText = extractMessageText(payload);
return {
channelId,
eventTime: payload.time
? new Date(Number(payload.time) * 1000)
: new Date(),
groupId,
messageId:
toStringId(payload.message_id) ||
`${payload.time || Date.now()}-${targetId}-${userId}`,
messageText,
messageType,
rawEvent: payload,
rawMessage: payload.raw_message || messageText,
selfId: toStringId(payload.self_id),
senderNickname:
payload.sender?.card ||
payload.sender?.nickname ||
payload.sender?.user_id ||
'',
targetId,
userId,
};
}
export function buildDedupeKey(message: QqbotNormalizedMessage) {
return [
message.selfId,
message.messageType,
message.targetId,
message.userId,
message.messageId,
].join(':');
}
function extractMessageText(payload: QqbotOneBotEvent) {
if (payload.raw_message) return payload.raw_message;
if (typeof payload.message === 'string') return payload.message;
if (!Array.isArray(payload.message)) return '';
return payload.message
.filter((segment) => segment?.type === 'text')
.map((segment) => segment?.data?.text || '')
.join('')
.trim();
}
function normalizeMessageType(messageType?: string): QqbotMessageType | null {
if (messageType === 'private' || messageType === 'group') {
return messageType;
}
if (messageType === 'channel' || messageType === 'guild') {
return 'channel';
}
return null;
}