mirror of
https://github.com/chrononeko/chronocat.git
synced 2024-11-25 18:03:40 +00:00
feat(event): support receive chronocat:poke
This commit is contained in:
parent
6748cf70c4
commit
af6a140498
@ -1,4 +1,10 @@
|
|||||||
import type { MarketFaceAssetRequest, Media, RedMessage } from '@chronocat/red'
|
import type {
|
||||||
|
JsonGrayTipBusi1061,
|
||||||
|
JsonGrayTipBusi1061ItemQq,
|
||||||
|
MarketFaceAssetRequest,
|
||||||
|
Media,
|
||||||
|
RedMessage,
|
||||||
|
} from '@chronocat/red'
|
||||||
import { AtType, ChatType, FaceType, MsgType, SendType } from '@chronocat/red'
|
import { AtType, ChatType, FaceType, MsgType, SendType } from '@chronocat/red'
|
||||||
import type {
|
import type {
|
||||||
Channel,
|
Channel,
|
||||||
@ -190,6 +196,15 @@ export const parseMessage = async (
|
|||||||
// 群主禁止群内临时通话
|
// 群主禁止群内临时通话
|
||||||
// 群主禁止群内发起新的群聊
|
// 群主禁止群内发起新的群聊
|
||||||
return undefined
|
return undefined
|
||||||
|
else if (
|
||||||
|
ntMsgTypes.msgType === MsgType.System && // 5
|
||||||
|
message.subMsgType === 12 && // 12
|
||||||
|
ntMsgTypes.sendType === SendType.System && // 3
|
||||||
|
message.elements[0]!.elementType === 8 && // 8
|
||||||
|
message.elements[0]!.grayTipElement!.subElementType === 17 && // 17
|
||||||
|
message.elements[0]!.grayTipElement!.jsonGrayTipElement!.busiId === '1061' // 1061
|
||||||
|
)
|
||||||
|
return await parsePokeMessage(ctx, config, event, message)
|
||||||
|
|
||||||
return undefined
|
return undefined
|
||||||
}
|
}
|
||||||
@ -355,6 +370,30 @@ async function parseGuildMemberAddedLegacyInviteMessage(
|
|||||||
return [event2, ...extraEvents]
|
return [event2, ...extraEvents]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function parsePokeMessage(
|
||||||
|
ctx: ChronocatContext,
|
||||||
|
_config: O.Intersect<ChronocatLogCurrentConfig, ChronocatSatoriEventsConfig>,
|
||||||
|
event: Event,
|
||||||
|
message: RedMessage,
|
||||||
|
) {
|
||||||
|
const json = JSON.parse(
|
||||||
|
message.elements[0]!.grayTipElement!.jsonGrayTipElement!.jsonStr,
|
||||||
|
) as JsonGrayTipBusi1061
|
||||||
|
|
||||||
|
const [operator, user] = json.items.filter((x) => x.type == 'qq') as [
|
||||||
|
JsonGrayTipBusi1061ItemQq,
|
||||||
|
JsonGrayTipBusi1061ItemQq,
|
||||||
|
]
|
||||||
|
|
||||||
|
event.type = 'message-created'
|
||||||
|
event.message = {
|
||||||
|
id: message.msgId,
|
||||||
|
content: `<${ctx.chronocat.platform}:poke user-id="${ctx.chronocat.uix.getUin(user.uid)}" operator-id="${ctx.chronocat.uix.getUin(operator.uid)}"/>`,
|
||||||
|
}
|
||||||
|
|
||||||
|
return [event]
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 解析消息元素。
|
* 解析消息元素。
|
||||||
*/
|
*/
|
||||||
|
@ -0,0 +1,145 @@
|
|||||||
|
{
|
||||||
|
"msgId": "1000000000000000000",
|
||||||
|
"msgRandom": "1000000000000000000",
|
||||||
|
"msgSeq": "100000",
|
||||||
|
"cntSeq": "0",
|
||||||
|
"chatType": 2,
|
||||||
|
"msgType": 5,
|
||||||
|
"subMsgType": 12,
|
||||||
|
"sendType": 3,
|
||||||
|
"senderUid": "",
|
||||||
|
"peerUid": "100000000",
|
||||||
|
"channelId": "",
|
||||||
|
"guildId": "",
|
||||||
|
"guildCode": "0",
|
||||||
|
"fromUid": "0",
|
||||||
|
"fromAppid": "0",
|
||||||
|
"msgTime": "1000000000",
|
||||||
|
"msgMeta": "0x",
|
||||||
|
"sendStatus": 2,
|
||||||
|
"sendRemarkName": "",
|
||||||
|
"sendMemberName": "",
|
||||||
|
"sendNickName": "",
|
||||||
|
"guildName": "",
|
||||||
|
"channelName": "",
|
||||||
|
"elements": [
|
||||||
|
{
|
||||||
|
"elementType": 8,
|
||||||
|
"elementId": "1000000000000000000",
|
||||||
|
"extBufForUI": "0x",
|
||||||
|
"textElement": null,
|
||||||
|
"faceElement": null,
|
||||||
|
"marketFaceElement": null,
|
||||||
|
"replyElement": null,
|
||||||
|
"picElement": null,
|
||||||
|
"pttElement": null,
|
||||||
|
"videoElement": null,
|
||||||
|
"grayTipElement": {
|
||||||
|
"subElementType": 17,
|
||||||
|
"revokeElement": null,
|
||||||
|
"proclamationElement": null,
|
||||||
|
"emojiReplyElement": null,
|
||||||
|
"groupElement": null,
|
||||||
|
"buddyElement": null,
|
||||||
|
"feedMsgElement": null,
|
||||||
|
"essenceElement": null,
|
||||||
|
"groupNotifyElement": null,
|
||||||
|
"buddyNotifyElement": null,
|
||||||
|
"xmlElement": null,
|
||||||
|
"fileReceiptElement": null,
|
||||||
|
"localGrayTipElement": null,
|
||||||
|
"blockGrayTipElement": null,
|
||||||
|
"aioOpGrayTipElement": null,
|
||||||
|
"jsonGrayTipElement": {
|
||||||
|
"busiId": "1061",
|
||||||
|
"jsonStr": "{\"align\":\"center\",\"items\":[{\"col\":\"1\",\"nm\":\"\",\"type\":\"qq\",\"uid\":\"u_0000000000000000000000\"},{\"jp\":\"https://zb.vip.qq.com/v2/pages/nudgeMall?_wv=2&actionId=0\",\"src\":\"http://tianquan.gtimg.cn/nudgeaction/item/0/expression.jpg\",\"type\":\"img\"},{\"txt\":\"戳了戳\",\"type\":\"nor\"},{\"col\":\"1\",\"nm\":\"\",\"tp\":\"0\",\"type\":\"qq\",\"uid\":\"u_0000000000000000000001\"},{\"txt\":\"\",\"type\":\"nor\"}]}\n",
|
||||||
|
"recentAbstract": "",
|
||||||
|
"isServer": true,
|
||||||
|
"xmlToJsonParam": {
|
||||||
|
"busiType": "12",
|
||||||
|
"busiId": "1061",
|
||||||
|
"c2cType": 0,
|
||||||
|
"serviceType": 0,
|
||||||
|
"ctrlFlag": 7,
|
||||||
|
"content": "<gtip align=\"center\"> <qq uin=\"u_0000000000000000000000\" col=\"1\" nm=\"\" /> <img src=\"http://tianquan.gtimg.cn/nudgeaction/item/0/expression.jpg\" jp=\"https://zb.vip.qq.com/v2/pages/nudgeMall?_wv=2&actionId=0\" /> <nor txt=\"戳了戳\"/> <qq uin=\"u_0000000000000000000001\" col=\"1\" nm=\"\" tp=\"0\"/> <nor txt=\"\"/> </gtip>",
|
||||||
|
"templId": "1132",
|
||||||
|
"seqId": "1000000000",
|
||||||
|
"templParam": {},
|
||||||
|
"pbReserv": null,
|
||||||
|
"members": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"walletGrayTipElement": null
|
||||||
|
},
|
||||||
|
"arkElement": null,
|
||||||
|
"fileElement": null,
|
||||||
|
"liveGiftElement": null,
|
||||||
|
"markdownElement": null,
|
||||||
|
"structLongMsgElement": null,
|
||||||
|
"multiForwardMsgElement": null,
|
||||||
|
"giphyElement": null,
|
||||||
|
"walletElement": null,
|
||||||
|
"inlineKeyboardElement": null,
|
||||||
|
"textGiftElement": null,
|
||||||
|
"calendarElement": null,
|
||||||
|
"yoloGameResultElement": null,
|
||||||
|
"avRecordElement": null,
|
||||||
|
"structMsgElement": null,
|
||||||
|
"faceBubbleElement": null,
|
||||||
|
"shareLocationElement": null,
|
||||||
|
"tofuRecordElement": null,
|
||||||
|
"taskTopMsgElement": null,
|
||||||
|
"recommendedMsgElement": null,
|
||||||
|
"actionBarElement": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"records": [],
|
||||||
|
"emojiLikesList": [],
|
||||||
|
"commentCnt": "0",
|
||||||
|
"directMsgFlag": 0,
|
||||||
|
"directMsgMembers": [],
|
||||||
|
"peerName": "",
|
||||||
|
"freqLimitInfo": null,
|
||||||
|
"editable": false,
|
||||||
|
"avatarMeta": "",
|
||||||
|
"avatarPendant": "",
|
||||||
|
"feedId": "",
|
||||||
|
"roleId": "0",
|
||||||
|
"timeStamp": "0",
|
||||||
|
"clientIdentityInfo": null,
|
||||||
|
"isImportMsg": false,
|
||||||
|
"atType": 0,
|
||||||
|
"roleType": 0,
|
||||||
|
"fromChannelRoleInfo": {
|
||||||
|
"roleId": "0",
|
||||||
|
"name": "",
|
||||||
|
"color": 0
|
||||||
|
},
|
||||||
|
"fromGuildRoleInfo": {
|
||||||
|
"roleId": "0",
|
||||||
|
"name": "",
|
||||||
|
"color": 0
|
||||||
|
},
|
||||||
|
"levelRoleInfo": {
|
||||||
|
"roleId": "0",
|
||||||
|
"name": "",
|
||||||
|
"color": 0
|
||||||
|
},
|
||||||
|
"recallTime": "0",
|
||||||
|
"isOnlineMsg": false,
|
||||||
|
"generalFlags": "0x",
|
||||||
|
"clientSeq": "0",
|
||||||
|
"fileGroupSize": null,
|
||||||
|
"foldingInfo": null,
|
||||||
|
"multiTransInfo": null,
|
||||||
|
"senderUin": "DO_NOT_USE_THIS_OR_YOU_WILL_BE_FIRED",
|
||||||
|
"peerUin": "DO_NOT_USE_THIS_OR_YOU_WILL_BE_FIRED",
|
||||||
|
"msgAttrs": {},
|
||||||
|
"anonymousExtInfo": null,
|
||||||
|
"nameType": 0,
|
||||||
|
"avatarFlag": 0,
|
||||||
|
"extInfoForUI": null,
|
||||||
|
"personalMedal": null,
|
||||||
|
"categoryManage": 0,
|
||||||
|
"msgEventInfo": null
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
import type { RedMessage } from '@chronocat/red'
|
||||||
|
import { readFile } from 'node:fs/promises'
|
||||||
|
import { join } from 'node:path'
|
||||||
|
import { buildParser } from '../../../../src/parser'
|
||||||
|
import { ctx, satoriConfig } from '../../../mocks'
|
||||||
|
|
||||||
|
test('Red 解析器应当正确解析 戳一戳消息', async () => {
|
||||||
|
const message = JSON.parse(
|
||||||
|
(await readFile(join(__dirname, 'data.json'))).toString('utf-8'),
|
||||||
|
) as RedMessage
|
||||||
|
|
||||||
|
const events = await buildParser(ctx, satoriConfig)(message)
|
||||||
|
|
||||||
|
expect(events).toBeTruthy() // 解析到的消息应该存在
|
||||||
|
expect(events).toHaveLength(1) // 应当解析到 1 条消息
|
||||||
|
|
||||||
|
const [event] = events!
|
||||||
|
expect(event).toMatchSnapshot()
|
||||||
|
})
|
@ -254,6 +254,17 @@ export interface RedMessage {
|
|||||||
clientSeq: string
|
clientSeq: string
|
||||||
nameType: number
|
nameType: number
|
||||||
avatarFlag: number
|
avatarFlag: number
|
||||||
|
freqLimitInfo: unknown
|
||||||
|
clientIdentityInfo: unknown
|
||||||
|
fileGroupSize: unknown
|
||||||
|
foldingInfo: unknown
|
||||||
|
multiTransInfo: unknown
|
||||||
|
msgAttrs: Record<string, unknown>
|
||||||
|
anonymousExtInfo: unknown
|
||||||
|
extInfoForUI: unknown
|
||||||
|
personalMedal: unknown
|
||||||
|
categoryManage: number
|
||||||
|
msgEventInfo: unknown
|
||||||
|
|
||||||
senderUin: string
|
senderUin: string
|
||||||
peerUin: string
|
peerUin: string
|
||||||
@ -289,6 +300,8 @@ export interface Element {
|
|||||||
shareLocationElement?: unknown
|
shareLocationElement?: unknown
|
||||||
tofuRecordElement?: unknown
|
tofuRecordElement?: unknown
|
||||||
taskTopMsgElement?: unknown
|
taskTopMsgElement?: unknown
|
||||||
|
recommendedMsgElement?: unknown
|
||||||
|
actionBarElement?: unknown
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface PicElement {
|
export interface PicElement {
|
||||||
@ -476,12 +489,57 @@ export interface GrayTipElement {
|
|||||||
blockGrayTipElement?: unknown
|
blockGrayTipElement?: unknown
|
||||||
aioOpGrayTipElement?: unknown
|
aioOpGrayTipElement?: unknown
|
||||||
jsonGrayTipElement?: JsonGrayTipElement
|
jsonGrayTipElement?: JsonGrayTipElement
|
||||||
|
walletGrayTipElement?: unknown
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface JsonGrayTipElement {
|
export interface JsonGrayTipElement {
|
||||||
busiId: string
|
busiId: string
|
||||||
jsonStr: string
|
jsonStr: string
|
||||||
|
recentAbstract: string
|
||||||
isServer: boolean
|
isServer: boolean
|
||||||
|
xmlToJsonParam: JsonGrayTipElementXmlToJsonParam
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface JsonGrayTipElementXmlToJsonParam {
|
||||||
|
busiType: string
|
||||||
|
busiId: string
|
||||||
|
c2cType: number
|
||||||
|
serviceType: number
|
||||||
|
ctrlFlag: number
|
||||||
|
content: string
|
||||||
|
templId: string
|
||||||
|
seqId: string
|
||||||
|
templParam: Record<string, unknown>
|
||||||
|
pbReserv: unknown
|
||||||
|
members: Record<string, unknown>
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface JsonGrayTipBusi1061 {
|
||||||
|
align: 'center'
|
||||||
|
items: JsonGrayTipBusi1061Item[]
|
||||||
|
}
|
||||||
|
|
||||||
|
export type JsonGrayTipBusi1061Item =
|
||||||
|
| JsonGrayTipBusi1061ItemNormal
|
||||||
|
| JsonGrayTipBusi1061ItemQq
|
||||||
|
| JsonGrayTipBusi1061ItemImage
|
||||||
|
|
||||||
|
export interface JsonGrayTipBusi1061ItemNormal {
|
||||||
|
type: 'nor'
|
||||||
|
txt: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface JsonGrayTipBusi1061ItemQq {
|
||||||
|
type: 'qq'
|
||||||
|
col: string // '1'
|
||||||
|
nm: string // ''
|
||||||
|
uid: string // 'u_0000000000000000000000'
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface JsonGrayTipBusi1061ItemImage {
|
||||||
|
type: 'img'
|
||||||
|
jp: string // 'https://zb.vip.qq.com/v2/pages/nudgeMall?_wv=2&actionId=0'
|
||||||
|
src: string // 'http://tianquan.gtimg.cn/nudgeaction/item/0/expression.jpg'
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface PttElement {
|
export interface PttElement {
|
||||||
|
Loading…
Reference in New Issue
Block a user