feat(event): support receive chronocat:poke

This commit is contained in:
Il Harper 2024-07-15 03:21:03 +08:00
parent 6748cf70c4
commit af6a140498
No known key found for this signature in database
GPG Key ID: 4B71FCA698E7E8EC
4 changed files with 262 additions and 1 deletions

View File

@ -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 type {
Channel,
@ -190,6 +196,15 @@ export const parseMessage = async (
// 群主禁止群内临时通话
// 群主禁止群内发起新的群聊
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
}
@ -355,6 +370,30 @@ async function parseGuildMemberAddedLegacyInviteMessage(
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]
}
/**
*
*/

View File

@ -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&amp;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
}

View File

@ -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()
})

View File

@ -254,6 +254,17 @@ export interface RedMessage {
clientSeq: string
nameType: 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
peerUin: string
@ -289,6 +300,8 @@ export interface Element {
shareLocationElement?: unknown
tofuRecordElement?: unknown
taskTopMsgElement?: unknown
recommendedMsgElement?: unknown
actionBarElement?: unknown
}
export interface PicElement {
@ -476,12 +489,57 @@ export interface GrayTipElement {
blockGrayTipElement?: unknown
aioOpGrayTipElement?: unknown
jsonGrayTipElement?: JsonGrayTipElement
walletGrayTipElement?: unknown
}
export interface JsonGrayTipElement {
busiId: string
jsonStr: string
recentAbstract: string
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 {