mirror of
https://github.com/NapNeko/NapCatQQ.git
synced 2025-07-19 12:03:37 +00:00
refactor: type
This commit is contained in:
@@ -2,7 +2,7 @@ import winston, { format, transports } from 'winston';
|
||||
import { truncateString } from '@/common/helper';
|
||||
import path from 'node:path';
|
||||
import fs from 'node:fs';
|
||||
import { AtType, ChatType, ElementType, MessageElement, RawMessage, SelfInfo } from '@/core';
|
||||
import { NTMsgAtType, ChatType, ElementType, MessageElement, RawMessage, SelfInfo } from '@/core';
|
||||
|
||||
export enum LogLevel {
|
||||
DEBUG = 'debug',
|
||||
@@ -270,12 +270,12 @@ function msgElementToText(element: MessageElement, msg: RawMessage, recursiveLev
|
||||
}
|
||||
|
||||
function textElementToText(textElement: any): string {
|
||||
if (textElement.atType === AtType.notAt) {
|
||||
if (textElement.atType === NTMsgAtType.ATTYPEUNKNOWN) {
|
||||
const originalContentLines = textElement.content.split('\n');
|
||||
return `${originalContentLines[0]}${originalContentLines.length > 1 ? ' ...' : ''}`;
|
||||
} else if (textElement.atType === AtType.atAll) {
|
||||
} else if (textElement.atType === NTMsgAtType.ATTYPEALL) {
|
||||
return `@全体成员`;
|
||||
} else if (textElement.atType === AtType.atUser) {
|
||||
} else if (textElement.atType === NTMsgAtType.ATTYPEONE) {
|
||||
return `${textElement.content} (${textElement.atUid})`;
|
||||
}
|
||||
return '';
|
||||
|
348
src/core/entities/element.ts
Normal file
348
src/core/entities/element.ts
Normal file
@@ -0,0 +1,348 @@
|
||||
import { ElementType, FaceType, MessageElement, NTGrayTipElementSubTypeV2, PicSubType, PicType, TipAioOpGrayTipElement, TipGroupElement, viedo_type } from "./msg";
|
||||
|
||||
type ElementFullBase = Omit<MessageElement, 'elementType' | 'elementId' | 'extBufForUI'>;
|
||||
|
||||
export interface SendElementBase<ET extends ElementType> {
|
||||
elementType: ET;
|
||||
elementId: string;
|
||||
extBufForUI?: string;
|
||||
}
|
||||
|
||||
type ElementBase<
|
||||
K extends keyof ElementFullBase,
|
||||
S extends Partial<{ [P in K]: keyof NonNullable<ElementFullBase[P]> | Array<keyof NonNullable<ElementFullBase[P]>> }> = object
|
||||
> = {
|
||||
[P in K]:
|
||||
S[P] extends Array<infer U>
|
||||
? Pick<NonNullable<ElementFullBase[P]>, U & keyof NonNullable<ElementFullBase[P]>>
|
||||
: S[P] extends keyof NonNullable<ElementFullBase[P]>
|
||||
? Pick<NonNullable<ElementFullBase[P]>, S[P]>
|
||||
: NonNullable<ElementFullBase[P]>;
|
||||
};
|
||||
|
||||
export interface TextElement {
|
||||
content: string;
|
||||
atType: number;
|
||||
atUid: string;
|
||||
atTinyId: string;
|
||||
atNtUid: string;
|
||||
}
|
||||
|
||||
export interface FaceElement {
|
||||
faceIndex: number;
|
||||
faceType: FaceType;
|
||||
faceText?: string;
|
||||
packId?: string;
|
||||
stickerId?: string;
|
||||
sourceType?: number;
|
||||
stickerType?: number;
|
||||
resultId?: string;
|
||||
surpriseId?: string;
|
||||
randomType?: number;
|
||||
}
|
||||
|
||||
export interface GrayTipElement {
|
||||
subElementType: NTGrayTipElementSubTypeV2;
|
||||
revokeElement: {
|
||||
operatorRole: string;
|
||||
operatorUid: string;
|
||||
operatorNick: string;
|
||||
operatorRemark: string;
|
||||
operatorMemRemark?: string;
|
||||
wording: string; // 自定义的撤回提示语
|
||||
};
|
||||
aioOpGrayTipElement: TipAioOpGrayTipElement;
|
||||
groupElement: TipGroupElement;
|
||||
xmlElement: {
|
||||
content: string;
|
||||
templId: string;
|
||||
};
|
||||
jsonGrayTipElement: {
|
||||
busiId?: number;
|
||||
jsonStr: string;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
export interface ArkElement {
|
||||
bytesData: string;
|
||||
linkInfo: null;
|
||||
subElementType: null;
|
||||
}
|
||||
|
||||
export interface MarketFaceElement {
|
||||
emojiPackageId: number;
|
||||
faceName: string;
|
||||
emojiId: string;
|
||||
key: string;
|
||||
}
|
||||
|
||||
export interface VideoElement {
|
||||
filePath: string;
|
||||
fileName: string;
|
||||
videoMd5?: string;
|
||||
thumbMd5?: string;
|
||||
fileTime?: number; // second
|
||||
thumbSize?: number; // byte
|
||||
fileFormat?: viedo_type; // 2表示mp4 参考下面条目
|
||||
fileSize?: string; // byte
|
||||
thumbWidth?: number;
|
||||
thumbHeight?: number;
|
||||
busiType?: 0; //
|
||||
subBusiType?: 0; // 未知
|
||||
thumbPath?: Map<number, any>;
|
||||
transferStatus?: 0; // 未知
|
||||
progress?: 0; // 下载进度?
|
||||
invalidState?: 0; // 未知
|
||||
fileUuid?: string; // 可以用于下载链接?
|
||||
fileSubId?: string;
|
||||
fileBizId?: null;
|
||||
originVideoMd5?: string;
|
||||
import_rich_media_context?: null;
|
||||
sourceVideoCodecFormat?: number;
|
||||
}
|
||||
export interface PicElement {
|
||||
md5HexStr?: string;
|
||||
filePath?: string;
|
||||
fileSize: number | string;//number
|
||||
picWidth: number;
|
||||
picHeight: number;
|
||||
fileName: string;
|
||||
sourcePath: string;
|
||||
original: boolean;
|
||||
picType: PicType;
|
||||
picSubType?: PicSubType;
|
||||
fileUuid: string;
|
||||
fileSubId: string;
|
||||
thumbFileSize: number;
|
||||
summary: string;
|
||||
thumbPath: Map<number, string>;
|
||||
originImageMd5?: string;
|
||||
originImageUrl?: string;
|
||||
}
|
||||
export interface InlineKeyboardButton {
|
||||
id: string;
|
||||
label: string;
|
||||
visitedLabel: string;
|
||||
unsupportTips: string;
|
||||
data: string;
|
||||
specifyRoleIds: string[];
|
||||
specifyTinyids: string[];
|
||||
style: number;
|
||||
type: number;
|
||||
clickLimit: number;
|
||||
atBotShowChannelList: boolean;
|
||||
permissionType: number;
|
||||
}
|
||||
|
||||
// 非element
|
||||
interface InlineKeyboardRow {
|
||||
buttons: InlineKeyboardButton[];
|
||||
}
|
||||
|
||||
// 非element
|
||||
interface TofuElementContent {
|
||||
color: string;
|
||||
tittle: string;
|
||||
}
|
||||
|
||||
export interface ActionBarElement {
|
||||
rows: InlineKeyboardRow[];
|
||||
botAppid: string;
|
||||
}
|
||||
|
||||
export interface RecommendedMsgElement {
|
||||
rows: InlineKeyboardRow[];
|
||||
botAppid: string;
|
||||
}
|
||||
|
||||
export interface TofuRecordElement {
|
||||
type: number;
|
||||
busiid: string;
|
||||
busiuuid: string;
|
||||
descriptionContent: string;
|
||||
contentlist: TofuElementContent[],
|
||||
background: string;
|
||||
icon: string;
|
||||
uinlist: string[],
|
||||
uidlist: string[],
|
||||
busiExtra: string;
|
||||
updateTime: string;
|
||||
dependedmsgid: string;
|
||||
msgtime: string;
|
||||
onscreennotify: boolean;
|
||||
}
|
||||
|
||||
export interface FileElement {
|
||||
fileMd5?: string;
|
||||
fileName: string;
|
||||
filePath: string;
|
||||
fileSize: string;
|
||||
picHeight?: number;
|
||||
picWidth?: number;
|
||||
folderId?: string;
|
||||
picThumbPath?: Map<number, string>;
|
||||
file10MMd5?: string;
|
||||
fileSha?: string;
|
||||
fileSha3?: string;
|
||||
fileUuid?: string;
|
||||
fileSubId?: string;
|
||||
thumbFileSize?: number;
|
||||
fileBizId?: number;
|
||||
}
|
||||
|
||||
export interface ShareLocationElement {
|
||||
text: string;
|
||||
ext: string;
|
||||
}
|
||||
|
||||
export interface StructLongMsgElement {
|
||||
xmlContent: string;
|
||||
resId: string;
|
||||
}
|
||||
|
||||
export interface ReplyElement {
|
||||
sourceMsgIdInRecords?: string;
|
||||
replayMsgSeq: string;
|
||||
replayMsgId: string;
|
||||
senderUin: string;
|
||||
senderUidStr?: string;
|
||||
replyMsgTime?: string;
|
||||
replyMsgClientSeq?: string;
|
||||
}
|
||||
|
||||
export interface CalendarElement {
|
||||
summary: string;
|
||||
msg: string;
|
||||
expireTimeMs: string;
|
||||
schemaType: number;
|
||||
schema: string;
|
||||
}
|
||||
|
||||
export interface GiphyElement {
|
||||
id: string;
|
||||
isClip: boolean;
|
||||
width: number;
|
||||
height: number;
|
||||
}
|
||||
|
||||
export interface AvRecordElement {
|
||||
type: number;
|
||||
time: string;
|
||||
text: string;
|
||||
mainType: number;
|
||||
hasRead: boolean;
|
||||
extraType: number;
|
||||
}
|
||||
|
||||
// 非element
|
||||
interface YoloUserInfo {
|
||||
uid: string;
|
||||
result: number;
|
||||
rank: number;
|
||||
bizId: string;
|
||||
}
|
||||
|
||||
export interface YoloGameResultElement {
|
||||
UserInfo: YoloUserInfo[];
|
||||
}
|
||||
|
||||
export interface FaceBubbleElement {
|
||||
faceCount: number;
|
||||
faceSummary: string;
|
||||
faceFlag: number;
|
||||
content: string;
|
||||
oldVersionStr: string;
|
||||
faceType: number;
|
||||
others: string;
|
||||
yellowFaceInfo: {
|
||||
index: number;
|
||||
buf: string;
|
||||
compatibleText: string;
|
||||
text: string;
|
||||
};
|
||||
}
|
||||
|
||||
export interface TaskTopMsgElement {
|
||||
msgTitle: string;
|
||||
msgSummary: string;
|
||||
iconUrl: string;
|
||||
topMsgType: number;
|
||||
}
|
||||
|
||||
export interface PttElement {
|
||||
canConvert2Text: boolean;
|
||||
duration: number;
|
||||
fileBizId: null;
|
||||
fileId: number;
|
||||
fileName: string;
|
||||
filePath: string;
|
||||
fileSize: string;
|
||||
fileSubId: string;
|
||||
fileUuid: string; // FileId
|
||||
formatType: number; // Todo 已定义 但是未替换
|
||||
invalidState: number;
|
||||
md5HexStr: string;
|
||||
playState: number;
|
||||
progress: number; //进度
|
||||
text: string;
|
||||
transferStatus: number;
|
||||
translateStatus: number;
|
||||
voiceChangeType: number;
|
||||
voiceType: number;
|
||||
waveAmplitudes: number[];
|
||||
autoConvertText: number;
|
||||
}
|
||||
|
||||
export type SendRecommendedMsgElement = SendElementBase<ElementType.RECOMMENDEDMSG> & ElementBase<'recommendedMsgElement'>;
|
||||
|
||||
export type SendTaskTopMsgElement = SendElementBase<ElementType.TASKTOPMSG> & ElementBase<'taskTopMsgElement'>;
|
||||
|
||||
export type SendTofuRecordElement = SendElementBase<ElementType.TOFURECORD> & ElementBase<'tofuRecordElement'>;
|
||||
|
||||
export type SendFaceBubbleElement = SendElementBase<ElementType.FACEBUBBLE> & ElementBase<'faceBubbleElement'>;
|
||||
|
||||
export type SendAvRecordElement = SendElementBase<ElementType.AVRECORD> & ElementBase<'avRecordElement'>;
|
||||
|
||||
export type SendInlineKeyboardElement = SendElementBase<ElementType.INLINEKEYBOARD> & ElementBase<'inlineKeyboardElement'>;
|
||||
|
||||
export type SendYoloGameResultElement = SendElementBase<ElementType.YOLOGAMERESULT> & ElementBase<'yoloGameResultElement'>;
|
||||
|
||||
export type SendGiphyElement = SendElementBase<ElementType.GIPHY> & ElementBase<'giphyElement'>;
|
||||
|
||||
export type SendWalletElement = SendElementBase<ElementType.UNKNOWN> & ElementBase<'walletElement'>;
|
||||
|
||||
export type SendCalendarElement = SendElementBase<ElementType.CALENDAR> & ElementBase<'calendarElement'>;
|
||||
|
||||
export type SendLiveGiftElement = SendElementBase<ElementType.LIVEGIFT> & ElementBase<'liveGiftElement'>;
|
||||
|
||||
export type SendTextElement = SendElementBase<ElementType.TEXT> & ElementBase<'textElement'>;
|
||||
|
||||
export type SendReplyElement = SendElementBase<ElementType.REPLY> & ElementBase<'replyElement'>;
|
||||
|
||||
export type SendFaceElement = SendElementBase<ElementType.FACE> & ElementBase<'faceElement'>;
|
||||
|
||||
export type SendMarketFaceElement = SendElementBase<ElementType.MFACE> & ElementBase<'marketFaceElement'>;
|
||||
|
||||
export type SendStructLongMsgElement = SendElementBase<ElementType.STRUCTLONGMSG> & ElementBase<'structLongMsgElement'>;
|
||||
|
||||
export type SendPicElement = SendElementBase<ElementType.PIC> & ElementBase<'picElement'>;
|
||||
|
||||
export type SendPttElement = SendElementBase<ElementType.PTT> & ElementBase<'pttElement', {
|
||||
pttElement: ['fileName', 'filePath', 'md5HexStr', 'fileSize', 'duration', 'formatType', 'voiceType',
|
||||
'voiceChangeType', 'canConvert2Text', 'waveAmplitudes', 'fileSubId', 'playState', 'autoConvertText']
|
||||
}>;
|
||||
|
||||
export type SendFileElement = SendElementBase<ElementType.FILE> & ElementBase<'fileElement'>;
|
||||
|
||||
export type SendVideoElement = SendElementBase<ElementType.VIDEO> & ElementBase<'videoElement'>;
|
||||
|
||||
export type SendArkElement = SendElementBase<ElementType.ARK> & ElementBase<'arkElement'>;
|
||||
|
||||
export type SendMarkdownElement = SendElementBase<ElementType.MARKDOWN> & ElementBase<'markdownElement'>;
|
||||
|
||||
export type SendShareLocationElement = SendElementBase<ElementType.SHARELOCATION> & ElementBase<'shareLocationElement'>;
|
||||
|
||||
export type SendMessageElement = SendTextElement | SendPttElement |
|
||||
SendPicElement | SendReplyElement | SendFaceElement | SendMarketFaceElement | SendFileElement |
|
||||
SendVideoElement | SendArkElement | SendMarkdownElement | SendShareLocationElement;
|
@@ -6,3 +6,4 @@ export * from './cache';
|
||||
export * from './system';
|
||||
export * from './webapi';
|
||||
export * from './sign';
|
||||
export * from './element';
|
@@ -1,19 +1,22 @@
|
||||
import { GroupMemberRole } from '@/core';
|
||||
import { ActionBarElement, ArkElement, AvRecordElement, CalendarElement, FaceBubbleElement, FaceElement, FileElement, GiphyElement, GrayTipElement, MarketFaceElement, PicElement, PttElement, RecommendedMsgElement, ReplyElement, ShareLocationElement, StructLongMsgElement, TaskTopMsgElement, TextElement, TofuRecordElement, VideoElement, YoloGameResultElement } from './element';
|
||||
|
||||
// 表示对等方的信息
|
||||
export interface Peer {
|
||||
chatType: ChatType;
|
||||
peerUid: string; // 如果是群聊uid为群号,私聊uid就是加密的字符串
|
||||
guildId?: string;
|
||||
chatType: ChatType; // 聊天类型
|
||||
peerUid: string; // 对等方的唯一标识符
|
||||
guildId?: string; // 可选的频道ID
|
||||
}
|
||||
|
||||
// 表示被踢下线的信息
|
||||
export interface KickedOffLineInfo {
|
||||
appId: number;
|
||||
instanceId: number;
|
||||
sameDevice: boolean;
|
||||
tipsDesc: string;
|
||||
tipsTitle: string;
|
||||
kickedType: number;
|
||||
securityKickedType: number;
|
||||
appId: number; // 应用ID
|
||||
instanceId: number; // 实例ID
|
||||
sameDevice: boolean; // 是否为同一设备
|
||||
tipsDesc: string; // 提示描述
|
||||
tipsTitle: string; // 提示标题
|
||||
kickedType: number; // 被踢类型
|
||||
securityKickedType: number; // 安全踢出类型
|
||||
}
|
||||
|
||||
export interface GetFileListParam {
|
||||
@@ -60,69 +63,6 @@ export enum ElementType {
|
||||
ACTIONBAR = 44
|
||||
}
|
||||
|
||||
type ElementFullBase = Omit<MessageElement, 'elementType' | 'elementId' | 'extBufForUI'>;
|
||||
|
||||
type ElementBase<
|
||||
K extends keyof ElementFullBase,
|
||||
S extends Partial<{ [P in K]: keyof NonNullable<ElementFullBase[P]> | Array<keyof NonNullable<ElementFullBase[P]>> }> = object
|
||||
> = {
|
||||
[P in K]:
|
||||
S[P] extends Array<infer U>
|
||||
? Pick<NonNullable<ElementFullBase[P]>, U & keyof NonNullable<ElementFullBase[P]>>
|
||||
: S[P] extends keyof NonNullable<ElementFullBase[P]>
|
||||
? Pick<NonNullable<ElementFullBase[P]>, S[P]>
|
||||
: NonNullable<ElementFullBase[P]>;
|
||||
};
|
||||
|
||||
export interface SendElementBase<ET extends ElementType> {
|
||||
elementType: ET;
|
||||
elementId: string;
|
||||
extBufForUI?: string;
|
||||
}
|
||||
|
||||
export interface ActionBarElement {
|
||||
rows: InlineKeyboardRow[];
|
||||
botAppid: string;
|
||||
}
|
||||
|
||||
export interface RecommendedMsgElement {
|
||||
rows: InlineKeyboardRow[];
|
||||
botAppid: string;
|
||||
}
|
||||
|
||||
export type SendRecommendedMsgElement = SendElementBase<ElementType.RECOMMENDEDMSG> & ElementBase<'recommendedMsgElement'>;
|
||||
|
||||
export interface InlineKeyboardButton {
|
||||
id: string;
|
||||
label: string;
|
||||
visitedLabel: string;
|
||||
unsupportTips: string;
|
||||
data: string;
|
||||
specifyRoleIds: string[];
|
||||
specifyTinyids: string[];
|
||||
style: number;
|
||||
type: number;
|
||||
clickLimit: number;
|
||||
atBotShowChannelList: boolean;
|
||||
permissionType: number;
|
||||
}
|
||||
|
||||
export interface InlineKeyboardRow {
|
||||
buttons: InlineKeyboardButton[];
|
||||
}
|
||||
|
||||
export interface TofuElementContent {
|
||||
color: string;
|
||||
tittle: string;
|
||||
}
|
||||
|
||||
export interface TaskTopMsgElement {
|
||||
msgTitle: string;
|
||||
msgSummary: string;
|
||||
iconUrl: string;
|
||||
topMsgType: number;
|
||||
}
|
||||
|
||||
export enum NTMsgType {
|
||||
KMSGTYPEARKSTRUCT = 11,
|
||||
KMSGTYPEFACEBUBBLE = 24,
|
||||
@@ -147,109 +87,15 @@ export enum NTMsgType {
|
||||
KMSGTYPEWALLET = 10
|
||||
}
|
||||
|
||||
export type SendTaskTopMsgElement = SendElementBase<ElementType.TASKTOPMSG> & ElementBase<'taskTopMsgElement'>;
|
||||
|
||||
export interface TofuRecordElement {
|
||||
type: number;
|
||||
busiid: string;
|
||||
busiuuid: string;
|
||||
descriptionContent: string;
|
||||
contentlist: TofuElementContent[],
|
||||
background: string;
|
||||
icon: string;
|
||||
uinlist: string[],
|
||||
uidlist: string[],
|
||||
busiExtra: string;
|
||||
updateTime: string;
|
||||
dependedmsgid: string;
|
||||
msgtime: string;
|
||||
onscreennotify: boolean;
|
||||
}
|
||||
|
||||
export type SendTofuRecordElement = SendElementBase<ElementType.TOFURECORD> & ElementBase<'tofuRecordElement'>;
|
||||
|
||||
export interface FaceBubbleElement {
|
||||
faceCount: number;
|
||||
faceSummary: string;
|
||||
faceFlag: number;
|
||||
content: string;
|
||||
oldVersionStr: string;
|
||||
faceType: number;
|
||||
others: string;
|
||||
yellowFaceInfo: {
|
||||
index: number;
|
||||
buf: string;
|
||||
compatibleText: string;
|
||||
text: string;
|
||||
};
|
||||
}
|
||||
|
||||
export type SendFaceBubbleElement = SendElementBase<ElementType.FACEBUBBLE> & ElementBase<'faceBubbleElement'>;
|
||||
|
||||
export interface AvRecordElement {
|
||||
type: number;
|
||||
time: string;
|
||||
text: string;
|
||||
mainType: number;
|
||||
hasRead: boolean;
|
||||
extraType: number;
|
||||
}
|
||||
|
||||
export type SendAvRecordElement = SendElementBase<ElementType.AVRECORD> & ElementBase<'avRecordElement'>;
|
||||
|
||||
export interface YoloUserInfo {
|
||||
uid: string;
|
||||
result: number;
|
||||
rank: number;
|
||||
bizId: string;
|
||||
}
|
||||
|
||||
export type SendInlineKeyboardElement = SendElementBase<ElementType.INLINEKEYBOARD> & ElementBase<'inlineKeyboardElement'>;
|
||||
|
||||
export interface YoloGameResultElement {
|
||||
UserInfo: YoloUserInfo[];
|
||||
}
|
||||
|
||||
export type SendYoloGameResultElement = SendElementBase<ElementType.YOLOGAMERESULT> & ElementBase<'yoloGameResultElement'>;
|
||||
|
||||
export interface GiphyElement {
|
||||
id: string;
|
||||
isClip: boolean;
|
||||
width: number;
|
||||
height: number;
|
||||
}
|
||||
|
||||
export type SendGiphyElement = SendElementBase<ElementType.GIPHY> & ElementBase<'giphyElement'>;
|
||||
|
||||
export type SendWalletElement = SendElementBase<ElementType.UNKNOWN> & ElementBase<'walletElement'>;
|
||||
|
||||
export interface CalendarElement {
|
||||
summary: string;
|
||||
msg: string;
|
||||
expireTimeMs: string;
|
||||
schemaType: number;
|
||||
schema: string;
|
||||
}
|
||||
|
||||
export type SendCalendarElement = SendElementBase<ElementType.CALENDAR> & ElementBase<'calendarElement'>;
|
||||
|
||||
export type SendLiveGiftElement = SendElementBase<ElementType.LIVEGIFT> & ElementBase<'liveGiftElement'>;
|
||||
|
||||
export type SendTextElement = SendElementBase<ElementType.TEXT> & ElementBase<'textElement'>;
|
||||
|
||||
export type SendPttElement = SendElementBase<ElementType.PTT> & ElementBase<'pttElement', {
|
||||
pttElement: ['fileName', 'filePath', 'md5HexStr', 'fileSize', 'duration', 'formatType', 'voiceType',
|
||||
'voiceChangeType', 'canConvert2Text', 'waveAmplitudes', 'fileSubId', 'playState', 'autoConvertText']
|
||||
}>;
|
||||
|
||||
export enum PicType {
|
||||
gif = 2000,
|
||||
jpg = 1000
|
||||
}
|
||||
|
||||
export enum PicSubType {
|
||||
normal = 0, // 普通图片,大图
|
||||
face = 1 // 表情包小图
|
||||
Normal = 0, // 普通图片
|
||||
Face = 1 // 表情包小图
|
||||
//...待补全 其余见NT Android
|
||||
}
|
||||
|
||||
export enum NTMsgAtType {
|
||||
@@ -266,78 +112,6 @@ export enum NTMsgAtType {
|
||||
ATTYPEUNKNOWN = 0
|
||||
}
|
||||
|
||||
export type SendPicElement = SendElementBase<ElementType.PIC> & ElementBase<'picElement'>;
|
||||
|
||||
export interface ReplyElement {
|
||||
sourceMsgIdInRecords?: string;
|
||||
replayMsgSeq: string;
|
||||
replayMsgId: string;
|
||||
senderUin: string;
|
||||
senderUidStr?: string;
|
||||
replyMsgTime?: string;
|
||||
replyMsgClientSeq?: string;
|
||||
}
|
||||
|
||||
export type SendReplyElement = SendElementBase<ElementType.REPLY> & ElementBase<'replyElement'>;
|
||||
|
||||
export type SendFaceElement = SendElementBase<ElementType.FACE> & ElementBase<'faceElement'>;
|
||||
|
||||
export type SendMarketFaceElement = SendElementBase<ElementType.MFACE> & ElementBase<'marketFaceElement'>;
|
||||
|
||||
export type SendStructLongMsgElement = SendElementBase<ElementType.STRUCTLONGMSG> & ElementBase<'structLongMsgElement'>;
|
||||
|
||||
export interface StructLongMsgElement {
|
||||
xmlContent: string;
|
||||
resId: string;
|
||||
}
|
||||
|
||||
export type SendActionBarElement = SendElementBase<ElementType.ACTIONBAR> & ElementBase<'actionBarElement'>;
|
||||
|
||||
export interface ShareLocationElement {
|
||||
text: string;
|
||||
ext: string;
|
||||
}
|
||||
|
||||
export type SendShareLocationElement = SendElementBase<ElementType.SHARELOCATION> & ElementBase<'shareLocationElement'>;
|
||||
|
||||
export interface FileElement {
|
||||
fileMd5?: string;
|
||||
fileName: string;
|
||||
filePath: string;
|
||||
fileSize: string;
|
||||
picHeight?: number;
|
||||
picWidth?: number;
|
||||
folderId?: string;
|
||||
picThumbPath?: Map<number, string>;
|
||||
file10MMd5?: string;
|
||||
fileSha?: string;
|
||||
fileSha3?: string;
|
||||
fileUuid?: string;
|
||||
fileSubId?: string;
|
||||
thumbFileSize?: number;
|
||||
fileBizId?: number;
|
||||
}
|
||||
|
||||
export type SendFileElement = SendElementBase<ElementType.FILE> & ElementBase<'fileElement'>;
|
||||
|
||||
export type SendVideoElement = SendElementBase<ElementType.VIDEO> & ElementBase<'videoElement'>;
|
||||
|
||||
export type SendArkElement = SendElementBase<ElementType.ARK> & ElementBase<'arkElement'>;
|
||||
|
||||
export type SendMarkdownElement = SendElementBase<ElementType.MARKDOWN> & ElementBase<'markdownElement'>;
|
||||
|
||||
export type SendMessageElement = SendTextElement | SendPttElement |
|
||||
SendPicElement | SendReplyElement | SendFaceElement | SendMarketFaceElement | SendFileElement |
|
||||
SendVideoElement | SendArkElement | SendMarkdownElement | SendShareLocationElement;
|
||||
|
||||
export interface TextElement {
|
||||
content: string;
|
||||
atType: number;
|
||||
atUid: string;
|
||||
atTinyId: string;
|
||||
atNtUid: string;
|
||||
}
|
||||
|
||||
export interface MessageElement {
|
||||
elementType: ElementType,
|
||||
elementId: string,
|
||||
@@ -372,11 +146,6 @@ export interface MessageElement {
|
||||
actionBarElement?: ActionBarElement
|
||||
}
|
||||
|
||||
export enum AtType {
|
||||
notAt = 0,
|
||||
atAll = 1,
|
||||
atUser = 2
|
||||
}
|
||||
export enum MsgSourceType {
|
||||
K_DOWN_SOURCETYPE_AIOINNER = 1,
|
||||
K_DOWN_SOURCETYPE_BIGSCREEN = 2,
|
||||
@@ -428,59 +197,9 @@ export enum ChatType {
|
||||
KCHATTYPEWEIYUN = 40,
|
||||
}
|
||||
|
||||
export interface PttElement {
|
||||
canConvert2Text: boolean;
|
||||
duration: number; // 秒数
|
||||
fileBizId: null;
|
||||
fileId: number; // 0
|
||||
fileName: string; // "e4d09c784d5a2abcb2f9980bdc7acfe6.amr"
|
||||
filePath: string; // "/Users//Library/Containers/com.tencent.qq/Data/Library/Application Support/QQ/nt_qq_a6b15c9820595d25a56c1633ce19ad40/nt_data/Ptt/2023-11/Ori/e4d09c784d5a2abcb2f9980bdc7acfe6.amr"
|
||||
fileSize: string; // "4261"
|
||||
fileSubId: string; // "0"
|
||||
fileUuid: string; // "90j3z7rmRphDPrdVgP9udFBaYar#oK0TWZIV"
|
||||
formatType: number; // 1
|
||||
invalidState: number; // 0
|
||||
md5HexStr: string; // "e4d09c784d5a2abcb2f9980bdc7acfe6"
|
||||
playState: number; // 0
|
||||
progress: number; // 0
|
||||
text: string; // ""
|
||||
transferStatus: number; // 0
|
||||
translateStatus: number; // 0
|
||||
voiceChangeType: number; // 0
|
||||
voiceType: number; // 0
|
||||
waveAmplitudes: number[];
|
||||
autoConvertText: number;
|
||||
}
|
||||
|
||||
export interface ArkElement {
|
||||
bytesData: string;
|
||||
linkInfo: null;
|
||||
subElementType: null;
|
||||
}
|
||||
|
||||
export const IMAGE_HTTP_HOST = 'https://gchat.qpic.cn';
|
||||
export const IMAGE_HTTP_HOST_NT = 'https://multimedia.nt.qq.com.cn';
|
||||
|
||||
export interface PicElement {
|
||||
md5HexStr?: string;
|
||||
filePath?: string;
|
||||
fileSize: number | string;//number
|
||||
picWidth: number;
|
||||
picHeight: number;
|
||||
fileName: string;
|
||||
sourcePath: string;
|
||||
original: boolean;
|
||||
picType: PicType;
|
||||
picSubType?: PicSubType;
|
||||
fileUuid: string;
|
||||
fileSubId: string;
|
||||
thumbFileSize: number;
|
||||
summary: string;
|
||||
thumbPath: Map<number, string>;
|
||||
originImageMd5?: string;
|
||||
originImageUrl?: string; // http url, 没有host,host是https://gchat.qpic.cn/, 带download参数的是https://multimedia.nt.qq.com.cn
|
||||
}
|
||||
|
||||
export enum NTGrayTipElementSubTypeV2 {
|
||||
GRAYTIP_ELEMENT_SUBTYPE_AIOOP = 15,
|
||||
GRAYTIP_ELEMENT_SUBTYPE_BLOCK = 14,
|
||||
@@ -502,27 +221,6 @@ export enum NTGrayTipElementSubTypeV2 {
|
||||
GRAYTIP_ELEMENT_SUBTYPE_XMLMSG = 12,
|
||||
}
|
||||
|
||||
export interface GrayTipElement {
|
||||
subElementType: NTGrayTipElementSubTypeV2;
|
||||
revokeElement: {
|
||||
operatorRole: string;
|
||||
operatorUid: string;
|
||||
operatorNick: string;
|
||||
operatorRemark: string;
|
||||
operatorMemRemark?: string;
|
||||
wording: string; // 自定义的撤回提示语
|
||||
};
|
||||
aioOpGrayTipElement: TipAioOpGrayTipElement;
|
||||
groupElement: TipGroupElement;
|
||||
xmlElement: {
|
||||
content: string;
|
||||
templId: string;
|
||||
};
|
||||
jsonGrayTipElement: {
|
||||
busiId?: number;
|
||||
jsonStr: string;
|
||||
};
|
||||
}
|
||||
|
||||
export enum FaceType {
|
||||
normal = 1, // 小黄脸
|
||||
@@ -533,88 +231,9 @@ export enum FaceType {
|
||||
|
||||
export enum FaceIndex {
|
||||
dice = 358,
|
||||
RPS = 359 // 石头剪刀布
|
||||
rps = 359
|
||||
}
|
||||
|
||||
export interface FaceElement {
|
||||
faceIndex: number;
|
||||
faceType: FaceType;
|
||||
faceText?: string;
|
||||
packId?: string;
|
||||
stickerId?: string;
|
||||
sourceType?: number;
|
||||
stickerType?: number;
|
||||
resultId?: string;
|
||||
surpriseId?: string;
|
||||
randomType?: number;
|
||||
}
|
||||
|
||||
export interface MarketFaceElement {
|
||||
emojiPackageId: number;
|
||||
faceName: string;
|
||||
emojiId: string;
|
||||
key: string;
|
||||
}
|
||||
|
||||
export interface VideoElement {
|
||||
filePath: string;
|
||||
fileName: string;
|
||||
videoMd5?: string;
|
||||
thumbMd5?: string;
|
||||
fileTime?: number; // second
|
||||
thumbSize?: number; // byte
|
||||
fileFormat?: viedo_type; // 2表示mp4 参考下面条目
|
||||
fileSize?: string; // byte
|
||||
thumbWidth?: number;
|
||||
thumbHeight?: number;
|
||||
busiType?: 0; //
|
||||
subBusiType?: 0; // 未知
|
||||
thumbPath?: Map<number, any>;
|
||||
transferStatus?: 0; // 未知
|
||||
progress?: 0; // 下载进度?
|
||||
invalidState?: 0; // 未知
|
||||
fileUuid?: string; // 可以用于下载链接?
|
||||
fileSubId?: string;
|
||||
fileBizId?: null;
|
||||
originVideoMd5?: string;
|
||||
import_rich_media_context?: null;
|
||||
sourceVideoCodecFormat?: number;
|
||||
}
|
||||
|
||||
// export enum busiType{
|
||||
// public static final int CREATOR_SHARE_ADV_XWORLD = 21;
|
||||
// public static final int MINI_APP_MINI_GAME = 11;
|
||||
// public static final int OFFICIAL_ACCOUNT_ADV = 4;
|
||||
// public static final int OFFICIAL_ACCOUNT_ADV_GAME = 8;
|
||||
// public static final int OFFICIAL_ACCOUNT_ADV_SHOP = 9;
|
||||
// public static final int OFFICIAL_ACCOUNT_ADV_VIP = 7;
|
||||
// public static final int OFFICIAL_ACCOUNT_LAYER_MASK_ADV = 14;
|
||||
// public static final int OFFICIAL_ACCOUNT_SPORT = 13;
|
||||
// public static final int OFFICIAL_ACCOUNT_TIAN_QI = 10;
|
||||
// public static final int PC_QQTAB_ADV = 18;
|
||||
// public static final int QIQIAOBAN_SDK = 15;
|
||||
// public static final int QQ_CPS = 16;
|
||||
// public static final int QQ_WALLET_CPS = 17;
|
||||
// public static final int QZONE_FEEDS = 0;
|
||||
// public static final int QZONE_PHOTO_TAIL = 2;
|
||||
// public static final int QZONE_VIDEO_LAYER = 1;
|
||||
// public static final int REWARD_GIFT_ADV = 6;
|
||||
// public static final int REWARD_GROUPGIFT_ADV = 12;
|
||||
// public static final int REWARD_PERSONAL_ADV = 5;
|
||||
// public static final int WEISEE_OFFICIAL_ACCOUNT = 3;
|
||||
// public static final int X_WORLD_CREATOR_ADV = 20;
|
||||
// public static final int X_WORLD_QZONE_LAYER = 22;
|
||||
// public static final int X_WORLD_VIDEO_ADV = 19;
|
||||
|
||||
// }
|
||||
// export enum CategoryBusiType {
|
||||
// _KCateBusiTypeDefault = 0,
|
||||
// _kCateBusiTypeFaceCluster = 1,
|
||||
// _kCateBusiTypeLabelCluster = 4,
|
||||
// _kCateBusiTypeMonthCluster = 16,
|
||||
// _kCateBusiTypePoiCluster = 2,
|
||||
// _kCateBusiTypeYearCluster = 8,
|
||||
// }
|
||||
export enum viedo_type {
|
||||
VIDEO_FORMAT_AFS = 7,
|
||||
VIDEO_FORMAT_AVI = 1,
|
||||
@@ -734,96 +353,34 @@ export enum SendStatusType {
|
||||
KSEND_STATUS_SUCCESS_NOSEQ = 3
|
||||
}
|
||||
|
||||
// 原始消息
|
||||
export interface RawMessage {
|
||||
parentMsgPeer: Peer;
|
||||
|
||||
parentMsgIdList: string[];
|
||||
|
||||
/**
|
||||
* 扩展字段,与 Ob11 msg ID 有关
|
||||
*/
|
||||
|
||||
|
||||
id?: number;
|
||||
|
||||
guildId: string;
|
||||
|
||||
msgRandom: string;
|
||||
|
||||
msgId: string;
|
||||
|
||||
/**
|
||||
* 消息时间戳(秒)
|
||||
*/
|
||||
msgTime: string;
|
||||
|
||||
msgSeq: string;
|
||||
|
||||
msgType: NTMsgType;
|
||||
|
||||
subMsgType: number;
|
||||
|
||||
senderUid: string;
|
||||
|
||||
/**
|
||||
* 发送者 QQ 号
|
||||
*/
|
||||
senderUin: string;
|
||||
|
||||
/**
|
||||
* 群号 / 用户 UID
|
||||
*/
|
||||
peerUid: string;
|
||||
|
||||
/**
|
||||
* 群号 / 用户 QQ 号
|
||||
*/
|
||||
peerUin: string;
|
||||
|
||||
/**
|
||||
* 好友备注(如果是好友消息)
|
||||
*/
|
||||
remark?: string;
|
||||
|
||||
/**
|
||||
* 群名(如果是群消息)
|
||||
*/
|
||||
peerName: string;
|
||||
|
||||
/**
|
||||
* 发送者昵称(如果是好友消息)
|
||||
*/
|
||||
sendNickName: string;
|
||||
|
||||
/**
|
||||
* 发送者好友备注(如果是群消息并且有发送者好友)
|
||||
*/
|
||||
sendRemarkName: string;
|
||||
|
||||
/**
|
||||
* 发送者群名片(如果是群消息)
|
||||
*/
|
||||
sendMemberName?: string;
|
||||
|
||||
chatType: ChatType;
|
||||
|
||||
/**
|
||||
* 消息状态,别人发的 2 是已撤回,自己发的 2 是已发送
|
||||
*/
|
||||
sendStatus?: SendStatusType;
|
||||
|
||||
/**
|
||||
* 撤回时间,"0" 是没有撤回
|
||||
*/
|
||||
recallTime: string;
|
||||
|
||||
records: RawMessage[];
|
||||
|
||||
elements: MessageElement[];
|
||||
|
||||
sourceType: MsgSourceType;
|
||||
|
||||
isOnlineMsg: boolean;
|
||||
parentMsgPeer: Peer; // 父消息的Peer
|
||||
parentMsgIdList: string[];// 父消息 ID 列表
|
||||
id?: number;// 扩展字段,与 Ob11 msg ID 有关
|
||||
guildId: string;// 频道ID
|
||||
msgRandom: string;// 消息ID相关
|
||||
msgId: string;// 雪花ID
|
||||
msgTime: string;// 消息时间戳
|
||||
msgSeq: string;// 消息序列号
|
||||
msgType: NTMsgType;// 消息类型
|
||||
subMsgType: number;// 子消息类型
|
||||
senderUid: string;// 发送者 UID
|
||||
senderUin: string;// 发送者 QQ 号
|
||||
peerUid: string;// 群号 / 用户 UID
|
||||
peerUin: string;// 群号 / 用户 QQ 号
|
||||
remark?: string;// 备注
|
||||
peerName: string;// Peer名称
|
||||
sendNickName: string;// 发送者昵称
|
||||
sendRemarkName: string;// 发送者好友备注
|
||||
sendMemberName?: string;// 发送者群名片(如果是群消息)
|
||||
chatType: ChatType;// 会话类型
|
||||
sendStatus?: SendStatusType;// 消息状态
|
||||
recallTime: string;// 撤回时间,"0" 是没有撤回
|
||||
records: RawMessage[];// 消息记录
|
||||
elements: MessageElement[];// 消息元素
|
||||
sourceType: MsgSourceType;// 消息来源类型
|
||||
isOnlineMsg: boolean;// 是否为在线消息
|
||||
}
|
||||
export interface QueryMsgsParams {
|
||||
chatInfo: Peer;
|
||||
|
@@ -14,7 +14,7 @@ import {
|
||||
GroupFileExtra
|
||||
} from "@/core/packet/transformer/proto";
|
||||
import {
|
||||
AtType,
|
||||
NTMsgAtType,
|
||||
PicType,
|
||||
SendArkElement,
|
||||
SendFaceElement,
|
||||
@@ -82,7 +82,7 @@ export class PacketMsgAtElement extends PacketMsgTextElement {
|
||||
constructor(element: SendTextElement) {
|
||||
super(element);
|
||||
this.targetUid = element.textElement.atNtUid;
|
||||
this.atAll = element.textElement.atType === AtType.atAll;
|
||||
this.atAll = element.textElement.atType === NTMsgAtType.ATTYPEALL;
|
||||
}
|
||||
|
||||
buildElement(): NapProtoEncodeStructType<typeof Elem>[] {
|
||||
|
@@ -2,7 +2,7 @@ import { FileNapCatOneBotUUID } from '@/common/helper';
|
||||
import { MessageUnique } from '@/common/message-unique';
|
||||
import { pathToFileURL } from 'node:url';
|
||||
import {
|
||||
AtType,
|
||||
NTMsgAtType,
|
||||
ChatType,
|
||||
CustomMusicSignPostData,
|
||||
ElementType,
|
||||
@@ -61,7 +61,7 @@ export class OneBotMsgApi {
|
||||
|
||||
rawToOb11Converters: RawToOb11Converters = {
|
||||
textElement: async element => {
|
||||
if (element.atType === AtType.notAt) {
|
||||
if (element.atType === NTMsgAtType.ATTYPEUNKNOWN) {
|
||||
let text = element.content;
|
||||
if (!text.trim()) {
|
||||
return null;
|
||||
@@ -76,7 +76,7 @@ export class OneBotMsgApi {
|
||||
};
|
||||
} else {
|
||||
let qq: string = 'all';
|
||||
if (element.atType !== AtType.atAll) {
|
||||
if (element.atType !== NTMsgAtType.ATTYPEALL) {
|
||||
const { atNtUid /* content */ } = element;
|
||||
let atQQ = element.atUid;
|
||||
if (!atQQ || atQQ === '0') {
|
||||
@@ -151,9 +151,9 @@ export class OneBotMsgApi {
|
||||
result: element.resultId!,
|
||||
},
|
||||
};
|
||||
} else if (faceIndex === FaceIndex.RPS) {
|
||||
} else if (faceIndex === FaceIndex.rps) {
|
||||
return {
|
||||
type: OB11MessageDataType.RPS,
|
||||
type: OB11MessageDataType.rps,
|
||||
data: {
|
||||
result: element.resultId!,
|
||||
},
|
||||
@@ -400,7 +400,7 @@ export class OneBotMsgApi {
|
||||
elementId: '',
|
||||
textElement: {
|
||||
content: text,
|
||||
atType: AtType.notAt,
|
||||
atType: NTMsgAtType.ATTYPEUNKNOWN,
|
||||
atUid: '',
|
||||
atTinyId: '',
|
||||
atNtUid: '',
|
||||
@@ -408,7 +408,7 @@ export class OneBotMsgApi {
|
||||
}),
|
||||
|
||||
[OB11MessageDataType.at]: async ({ data: { qq: atQQ } }, context) => {
|
||||
function at(atUid: string, atNtUid: string, atType: AtType, atName: string): SendTextElement {
|
||||
function at(atUid: string, atNtUid: string, atType: NTMsgAtType, atName: string): SendTextElement {
|
||||
return {
|
||||
elementType: ElementType.TEXT,
|
||||
elementId: '',
|
||||
@@ -423,15 +423,15 @@ export class OneBotMsgApi {
|
||||
}
|
||||
|
||||
if (!context.peer || context.peer.chatType == ChatType.KCHATTYPEC2C) return undefined;
|
||||
if (atQQ === 'all') return at(atQQ, atQQ, AtType.atAll, '全体成员');
|
||||
if (atQQ === 'all') return at(atQQ, atQQ, NTMsgAtType.ATTYPEALL, '全体成员');
|
||||
const atMember = await this.core.apis.GroupApi.getGroupMember(context.peer.peerUid, atQQ);
|
||||
if (atMember) {
|
||||
return at(atQQ, atMember.uid, AtType.atUser, atMember.nick || atMember.cardName);
|
||||
return at(atQQ, atMember.uid, NTMsgAtType.ATTYPEONE, atMember.nick || atMember.cardName);
|
||||
}
|
||||
const uid = await this.core.apis.UserApi.getUidByUinV2(`${atQQ}`);
|
||||
if (!uid) throw new Error('Get Uid Error');
|
||||
const info = await this.core.apis.UserApi.getUserDetailInfo(uid);
|
||||
return at(atQQ, uid, AtType.atUser, info.nick || '');
|
||||
return at(atQQ, uid, NTMsgAtType.ATTYPEONE, info.nick || '');
|
||||
},
|
||||
|
||||
[OB11MessageDataType.reply]: async ({ data: { id } }) => {
|
||||
@@ -558,11 +558,11 @@ export class OneBotMsgApi {
|
||||
},
|
||||
}),
|
||||
|
||||
[OB11MessageDataType.RPS]: async () => ({
|
||||
[OB11MessageDataType.rps]: async () => ({
|
||||
elementType: ElementType.FACE,
|
||||
elementId: '',
|
||||
faceElement: {
|
||||
faceIndex: FaceIndex.RPS,
|
||||
faceIndex: FaceIndex.rps,
|
||||
faceText: '[包剪锤]',
|
||||
faceType: 3,
|
||||
packId: '1',
|
||||
@@ -640,7 +640,7 @@ export class OneBotMsgApi {
|
||||
|
||||
[OB11MessageDataType.poke]: async () => undefined,
|
||||
|
||||
[OB11MessageDataType.Location]: async () => ({
|
||||
[OB11MessageDataType.location]: async () => ({
|
||||
elementType: ElementType.SHARELOCATION,
|
||||
elementId: '',
|
||||
shareLocationElement: {
|
||||
|
@@ -1,91 +1,89 @@
|
||||
export interface OB11User {
|
||||
[key: string]: any;
|
||||
user_id: number;
|
||||
nickname: string;
|
||||
remark?: string;
|
||||
sex?: OB11UserSex;
|
||||
level?: number;
|
||||
age?: number;
|
||||
qid?: string;
|
||||
login_days?: number;
|
||||
categoryName?: string;
|
||||
categoryId?: number;
|
||||
user_id: number; // 用户ID
|
||||
nickname: string; // 昵称
|
||||
remark?: string; // 备注
|
||||
sex?: OB11UserSex; // 性别
|
||||
level?: number; // 等级
|
||||
age?: number; // 年龄
|
||||
qid?: string; // QID
|
||||
login_days?: number; // 登录天数
|
||||
categoryName?: string; // 分组名称
|
||||
categoryId?: number; // 分组ID 999为特别关心
|
||||
}
|
||||
|
||||
export enum OB11UserSex {
|
||||
male = 'male',
|
||||
female = 'female',
|
||||
unknown = 'unknown'
|
||||
male = 'male', // 男性
|
||||
female = 'female', // 女性
|
||||
unknown = 'unknown' // 未知
|
||||
}
|
||||
|
||||
export enum OB11GroupMemberRole {
|
||||
owner = 'owner',
|
||||
admin = 'admin',
|
||||
member = 'member',
|
||||
owner = 'owner', // 群主
|
||||
admin = 'admin', // 管理员
|
||||
member = 'member', // 成员
|
||||
}
|
||||
|
||||
export interface OB11GroupMember {
|
||||
group_id: number;
|
||||
user_id: number;
|
||||
nickname: string;
|
||||
card?: string;
|
||||
sex?: OB11UserSex;
|
||||
age?: number;
|
||||
join_time?: number;
|
||||
last_sent_time?: number;
|
||||
level?: string;
|
||||
qq_level?: number;
|
||||
role?: OB11GroupMemberRole;
|
||||
title?: string;
|
||||
area?: string;
|
||||
unfriendly?: boolean;
|
||||
title_expire_time?: number;
|
||||
card_changeable?: boolean;
|
||||
// 以下为gocq字段
|
||||
shut_up_timestamp?: number;
|
||||
// 以下为扩展字段
|
||||
is_robot?: boolean;
|
||||
qage?: number;
|
||||
group_id: number; // 群ID
|
||||
user_id: number; // 用户ID
|
||||
nickname: string; // 昵称
|
||||
card?: string; // 群名片
|
||||
sex?: OB11UserSex; // 性别
|
||||
age?: number; // 年龄
|
||||
join_time?: number; // 加入时间
|
||||
last_sent_time?: number; // 最后发言时间
|
||||
level?: string; // 群等级
|
||||
qq_level?: number; // QQ等级
|
||||
role?: OB11GroupMemberRole; // 群角色
|
||||
title?: string; // 头衔
|
||||
area?: string; // 地区
|
||||
unfriendly?: boolean; // 是否不友好
|
||||
title_expire_time?: number; // 头衔过期时间
|
||||
card_changeable?: boolean; // 名片是否可修改
|
||||
shut_up_timestamp?: number; // 禁言时间戳
|
||||
is_robot?: boolean; // 是否机器人
|
||||
qage?: number; // QQ年龄
|
||||
}
|
||||
|
||||
export interface OB11Group {
|
||||
group_id: number;
|
||||
group_name: string;
|
||||
member_count?: number;
|
||||
max_member_count?: number;
|
||||
group_id: number; // 群ID
|
||||
group_name: string; // 群名称
|
||||
member_count?: number; // 成员数量
|
||||
max_member_count?: number; // 最大成员数量
|
||||
}
|
||||
|
||||
export interface OB11Sender {
|
||||
user_id: number,
|
||||
nickname: string,
|
||||
sex?: OB11UserSex,
|
||||
age?: number,
|
||||
card?: string, // 群名片
|
||||
level?: string, // 群等级
|
||||
role?: OB11GroupMemberRole
|
||||
user_id: number; // 用户ID
|
||||
nickname: string; // 昵称
|
||||
sex?: OB11UserSex; // 性别
|
||||
age?: number; // 年龄
|
||||
card?: string; // 群名片
|
||||
level?: string; // 群等级
|
||||
role?: OB11GroupMemberRole; // 群角色
|
||||
}
|
||||
|
||||
export interface OB11GroupFile {
|
||||
group_id: number,
|
||||
file_id: string,
|
||||
file_name: string,
|
||||
busid: number,
|
||||
size: number,
|
||||
upload_time: number,
|
||||
dead_time: number,
|
||||
modify_time: number,
|
||||
download_times: number,
|
||||
uploader: number,
|
||||
uploader_name: string
|
||||
group_id: number; // 群ID
|
||||
file_id: string; // 文件ID
|
||||
file_name: string; // 文件名称
|
||||
busid: number; // 业务ID
|
||||
size: number; // 文件大小
|
||||
upload_time: number; // 上传时间
|
||||
dead_time: number; // 过期时间
|
||||
modify_time: number; // 修改时间
|
||||
download_times: number; // 下载次数
|
||||
uploader: number; // 上传者ID
|
||||
uploader_name: string; // 上传者名称
|
||||
}
|
||||
|
||||
export interface OB11GroupFileFolder {
|
||||
group_id: number,
|
||||
folder_id: string,
|
||||
folder: string,
|
||||
folder_name: string,
|
||||
create_time: number,
|
||||
creator: number,
|
||||
creator_name: string,
|
||||
total_file_count: number,
|
||||
group_id: number; // 群ID
|
||||
folder_id: string; // 文件夹ID
|
||||
folder: string; // 文件夹路径
|
||||
folder_name: string; // 文件夹名称
|
||||
create_time: number; // 创建时间
|
||||
creator: number; // 创建者ID
|
||||
creator_name: string; // 创建者名称
|
||||
total_file_count: number; // 文件总数
|
||||
}
|
@@ -2,46 +2,51 @@ import { OB11Sender } from './entity';
|
||||
import { EventType } from '@/onebot/event/OneBotEvent';
|
||||
import { CustomMusicSignPostData, IdMusicSignPostData, PicSubType, RawMessage } from '@/core';
|
||||
|
||||
// 消息类型枚举
|
||||
export enum OB11MessageType {
|
||||
private = 'private',
|
||||
group = 'group'
|
||||
}
|
||||
|
||||
// 消息接口定义
|
||||
export interface OB11Message {
|
||||
temp_source?: number;
|
||||
message_sent_type?: string;
|
||||
target_id?: number; // 自己发送的消息才有此字段
|
||||
self_id?: number,
|
||||
time: number,
|
||||
message_id: number,
|
||||
message_seq: number, // 和message_id一样
|
||||
real_id: number,
|
||||
user_id: number | string, // number
|
||||
group_id?: number | string, // number
|
||||
message_type: 'private' | 'group',
|
||||
sub_type?: 'friend' | 'group' | 'normal',
|
||||
sender: OB11Sender,
|
||||
message: OB11MessageData[] | string,
|
||||
message_format: 'array' | 'string',
|
||||
raw_message: string,
|
||||
font: number,
|
||||
post_type?: EventType,
|
||||
raw?: RawMessage
|
||||
self_id?: number;
|
||||
time: number;
|
||||
message_id: number;
|
||||
message_seq: number; // 和message_id一样
|
||||
real_id: number;
|
||||
user_id: number | string; // number
|
||||
group_id?: number | string; // number
|
||||
message_type: 'private' | 'group';
|
||||
sub_type?: 'friend' | 'group' | 'normal';
|
||||
sender: OB11Sender;
|
||||
message: OB11MessageData[] | string;
|
||||
message_format: 'array' | 'string';
|
||||
raw_message: string;
|
||||
font: number;
|
||||
post_type?: EventType;
|
||||
raw?: RawMessage;
|
||||
}
|
||||
|
||||
// 合并转发消息接口定义
|
||||
export interface OB11ForwardMessage extends OB11Message {
|
||||
content: OB11MessageData[] | string;
|
||||
}
|
||||
|
||||
// 返回数据接口定义
|
||||
export interface OB11Return<DataType> {
|
||||
status: string
|
||||
retcode: number
|
||||
data: DataType
|
||||
message: string,
|
||||
echo?: any, // ws调用api才有此字段
|
||||
wording?: string, // go-cqhttp字段,错误信息
|
||||
status: string;
|
||||
retcode: number;
|
||||
data: DataType;
|
||||
message: string;
|
||||
echo?: any; // ws调用api才有此字段
|
||||
wording?: string; // go-cqhttp字段,错误信息
|
||||
}
|
||||
|
||||
// 消息数据类型枚举
|
||||
export enum OB11MessageDataType {
|
||||
text = 'text',
|
||||
image = 'image',
|
||||
@@ -60,108 +65,123 @@ export enum OB11MessageDataType {
|
||||
xml = 'xml',
|
||||
poke = 'poke',
|
||||
dice = 'dice',
|
||||
RPS = 'rps',
|
||||
miniapp = 'miniapp',//json类
|
||||
rps = 'rps',
|
||||
miniapp = 'miniapp', // json类
|
||||
contact = 'contact',
|
||||
Location = 'location'
|
||||
location = 'location'
|
||||
}
|
||||
|
||||
// 商城表情消息接口定义
|
||||
export interface OB11MessageMFace {
|
||||
type: OB11MessageDataType.mface;
|
||||
data: {
|
||||
emoji_package_id: number
|
||||
emoji_id: string
|
||||
key: string
|
||||
summary: string
|
||||
emoji_package_id: number;
|
||||
emoji_id: string;
|
||||
key: string;
|
||||
summary: string;
|
||||
};
|
||||
}
|
||||
|
||||
// 纯文本消息接口定义
|
||||
export interface OB11MessageText {
|
||||
type: OB11MessageDataType.text,
|
||||
type: OB11MessageDataType.text;
|
||||
data: {
|
||||
text: string, // 纯文本
|
||||
}
|
||||
text: string; // 纯文本
|
||||
};
|
||||
}
|
||||
|
||||
// 联系人消息接口定义
|
||||
export interface OB11MessageContext {
|
||||
type: OB11MessageDataType.contact,
|
||||
type: OB11MessageDataType.contact;
|
||||
data: {
|
||||
type:"qq"|"group",
|
||||
id: string,
|
||||
}
|
||||
type: "qq" | "group";
|
||||
id: string;
|
||||
};
|
||||
}
|
||||
|
||||
// 文件消息基础接口定义
|
||||
export interface OB11MessageFileBase {
|
||||
data: {
|
||||
file_unique?: string,
|
||||
file_unique?: string;
|
||||
path?: string;
|
||||
thumb?: string;
|
||||
name?: string;
|
||||
file: string,
|
||||
file: string;
|
||||
url?: string;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
// 图片消息接口定义
|
||||
export interface OB11MessageImage extends OB11MessageFileBase {
|
||||
type: OB11MessageDataType.image
|
||||
type: OB11MessageDataType.image;
|
||||
data: OB11MessageFileBase['data'] & {
|
||||
summary?: string; // 图片摘要
|
||||
sub_type?: PicSubType
|
||||
},
|
||||
sub_type?: PicSubType;
|
||||
};
|
||||
}
|
||||
|
||||
// 语音消息接口定义
|
||||
export interface OB11MessageRecord extends OB11MessageFileBase {
|
||||
type: OB11MessageDataType.voice;
|
||||
}
|
||||
|
||||
// 文件消息接口定义
|
||||
export interface OB11MessageFile extends OB11MessageFileBase {
|
||||
type: OB11MessageDataType.file;
|
||||
}
|
||||
|
||||
// 视频消息接口定义
|
||||
export interface OB11MessageVideo extends OB11MessageFileBase {
|
||||
type: OB11MessageDataType.video;
|
||||
}
|
||||
|
||||
// @消息接口定义
|
||||
export interface OB11MessageAt {
|
||||
type: OB11MessageDataType.at;
|
||||
data: {
|
||||
qq: string, // `${number}` | 'all'
|
||||
name?: string
|
||||
qq: string; // `${number}` | 'all'
|
||||
name?: string;
|
||||
};
|
||||
}
|
||||
|
||||
// 回复消息接口定义
|
||||
export interface OB11MessageReply {
|
||||
type: OB11MessageDataType.reply;
|
||||
data: {
|
||||
id: string
|
||||
id: string;
|
||||
};
|
||||
}
|
||||
|
||||
// 表情消息接口定义
|
||||
export interface OB11MessageFace {
|
||||
type: OB11MessageDataType.face;
|
||||
data: {
|
||||
id: string
|
||||
id: string;
|
||||
};
|
||||
}
|
||||
|
||||
// 混合消息类型定义
|
||||
export type OB11MessageMixType = OB11MessageData[] | string | OB11MessageData;
|
||||
|
||||
// 合并转发消息节点接口定义
|
||||
export interface OB11MessageNode {
|
||||
type: OB11MessageDataType.node;
|
||||
data: {
|
||||
id?: string
|
||||
user_id?: number | string // number
|
||||
uin?: number | string // number, compatible with go-cqhttp
|
||||
nickname: string
|
||||
name?: string // compatible with go-cqhttp
|
||||
content: OB11MessageMixType
|
||||
source?: string,
|
||||
news?: { text: string }[],
|
||||
summary?: string,
|
||||
prompt?: string
|
||||
time?: string
|
||||
id?: string;
|
||||
user_id?: number | string; // number
|
||||
uin?: number | string; // number, compatible with go-cqhttp
|
||||
nickname: string;
|
||||
name?: string; // compatible with go-cqhttp
|
||||
content: OB11MessageMixType;
|
||||
source?: string;
|
||||
news?: { text: string }[];
|
||||
summary?: string;
|
||||
prompt?: string;
|
||||
time?: string;
|
||||
};
|
||||
}
|
||||
|
||||
// 合并转发消息节点纯文本接口定义
|
||||
export type OB11MessageNodePlain = OB11MessageNode & {
|
||||
data: {
|
||||
content?: Array<OB11MessageData>;
|
||||
@@ -169,73 +189,84 @@ export type OB11MessageNodePlain = OB11MessageNode & {
|
||||
};
|
||||
};
|
||||
|
||||
// 音乐消息接口定义
|
||||
export interface OB11MessageIdMusic {
|
||||
type: OB11MessageDataType.music;
|
||||
data: IdMusicSignPostData;
|
||||
}
|
||||
|
||||
// 自定义音乐消息接口定义
|
||||
export interface OB11MessageCustomMusic {
|
||||
type: OB11MessageDataType.music;
|
||||
data: Omit<CustomMusicSignPostData, 'singer'> & { content?: string };
|
||||
}
|
||||
|
||||
// JSON消息接口定义
|
||||
export interface OB11MessageJson {
|
||||
type: OB11MessageDataType.json;
|
||||
data: { config?: { token: string }, data: string | object };
|
||||
}
|
||||
|
||||
// 骰子消息接口定义
|
||||
export interface OB11MessageDice {
|
||||
type: OB11MessageDataType.dice,
|
||||
type: OB11MessageDataType.dice;
|
||||
data: {
|
||||
result: number /* intended */ | string /* in fact */
|
||||
}
|
||||
result: number /* intended */ | string /* in fact */;
|
||||
};
|
||||
}
|
||||
|
||||
// 猜拳消息接口定义
|
||||
export interface OB11MessageRPS {
|
||||
type: OB11MessageDataType.RPS,
|
||||
type: OB11MessageDataType.rps;
|
||||
data: {
|
||||
result: number | string
|
||||
}
|
||||
result: number | string;
|
||||
};
|
||||
}
|
||||
|
||||
// Markdown消息接口定义
|
||||
export interface OB11MessageMarkdown {
|
||||
type: OB11MessageDataType.markdown;
|
||||
data: {
|
||||
content: string
|
||||
content: string;
|
||||
};
|
||||
}
|
||||
|
||||
// 合并转发消息接口定义
|
||||
export interface OB11MessageForward {
|
||||
type: OB11MessageDataType.forward;
|
||||
data: {
|
||||
id: string,
|
||||
content: OB11Message[]
|
||||
id: string;
|
||||
content: OB11Message[];
|
||||
};
|
||||
}
|
||||
|
||||
// 消息数据类型定义
|
||||
export type OB11MessageData =
|
||||
OB11MessageText |
|
||||
OB11MessageFace | OB11MessageMFace |
|
||||
OB11MessageAt | OB11MessageReply |
|
||||
OB11MessageImage | OB11MessageRecord | OB11MessageFile | OB11MessageVideo |
|
||||
OB11MessageNode | OB11MessageIdMusic | OB11MessageCustomMusic | OB11MessageJson |
|
||||
OB11MessageDice | OB11MessageRPS | OB11MessageMarkdown | OB11MessageForward | OB11MessageContext
|
||||
OB11MessageDice | OB11MessageRPS | OB11MessageMarkdown | OB11MessageForward | OB11MessageContext;
|
||||
|
||||
// 发送消息接口定义
|
||||
export interface OB11PostSendMsg {
|
||||
message_type?: 'private' | 'group'
|
||||
user_id?: string,
|
||||
group_id?: string,
|
||||
message_type?: 'private' | 'group';
|
||||
user_id?: string;
|
||||
group_id?: string;
|
||||
message: OB11MessageMixType;
|
||||
messages?: OB11MessageMixType; // 兼容 go-cqhttp
|
||||
auto_escape?: boolean | string
|
||||
source?: string,
|
||||
news?: { text: string }[],
|
||||
summary?: string,
|
||||
prompt?: string
|
||||
time?: string
|
||||
auto_escape?: boolean | string;
|
||||
source?: string;
|
||||
news?: { text: string }[];
|
||||
summary?: string;
|
||||
prompt?: string;
|
||||
time?: string;
|
||||
}
|
||||
|
||||
// 上下文接口定义
|
||||
export interface OB11PostContext {
|
||||
message_type?: 'private' | 'group'
|
||||
user_id?: string,
|
||||
group_id?: string,
|
||||
message_type?: 'private' | 'group';
|
||||
user_id?: string;
|
||||
group_id?: string;
|
||||
}
|
Reference in New Issue
Block a user