import * as PUPPET from '@juzi/wechaty-puppet' import { WA_ERROR_TYPE } from '../../exception/error-type.js' import WAError from '../../exception/whatsapp-error.js' import { isRoomId } from '../miscellaneous.js' import { MessageAck, MessageTypes as WhatsAppMessageType, } from '../../schema/whatsapp-interface.js' import { SpecialSystemType, type WhatsAppMessagePayload, } from '../../schema/whatsapp-type.js' export function parserMessageRawPayload (messagePayload: WhatsAppMessagePayload): PUPPET.payloads.Message { const talkerId = messagePayload.author || messagePayload.from let listenerId: string | undefined let roomId: string | undefined if (typeof messagePayload.id.remote === 'object') { const { _serialized } = messagePayload.id.remote roomId = isRoomId(_serialized) ? _serialized : undefined listenerId = isRoomId(_serialized) ? undefined : messagePayload.to } else { roomId = isRoomId(messagePayload.id.remote) ? messagePayload.id.remote : undefined listenerId = isRoomId(messagePayload.id.remote) ? undefined : messagePayload.to } if (!talkerId) { throw WAError(WA_ERROR_TYPE.ERR_MSG_NOT_FOUND, 'empty talkerIdId!') } if (!roomId && !listenerId) { throw WAError(WA_ERROR_TYPE.ERR_MSG_NOT_FOUND, 'empty roomId and empty listenerId!') } const readList = roomId ? undefined : [MessageAck.ACK_READ, MessageAck.ACK_PLAYED].includes(messagePayload.ack) ? [listenerId] : [] return { /** * @deprecated `fromId` is deprecated, use `talkerId` instead. * `fromId` will be removed in v2.0 */ fromId: talkerId, talkerId, // eslint-disable-next-line sort-keys id: messagePayload.id.id, mentionIdList: messagePayload.mentionedIds, roomId, text: messagePayload.body, timestamp: messagePayload.timestamp, /** * @deprecated `toId` is deprecated, use `listenerId` instead. * `toId` will be removed in v2.0 */ toId: listenerId, // eslint-disable-next-line sort-keys listenerId, quoteId: messagePayload.hasQuotedMsg ? messagePayload._data?.quotedStanzaID : undefined, type: getMessageType(messagePayload), readList, } as PUPPET.payloads.Message } function getMessageType (messagePayload: WhatsAppMessagePayload): PUPPET.types.Message { let type: PUPPET.types.Message = PUPPET.types.Message.Unknown // @ts-ignore if (messagePayload.type === 'notification') { type = PUPPET.types.Message.Text } switch (messagePayload.type) { case WhatsAppMessageType.TEXT: if (messagePayload.isStatus) { type = PUPPET.types.Message.Post } else { type = PUPPET.types.Message.Text } break case WhatsAppMessageType.STICKER: type = PUPPET.types.Message.Emoticon break case WhatsAppMessageType.VOICE: type = PUPPET.types.Message.Audio break case WhatsAppMessageType.IMAGE: if (messagePayload.isStatus) { type = PUPPET.types.Message.Post } else { type = PUPPET.types.Message.Image } break case WhatsAppMessageType.AUDIO: type = PUPPET.types.Message.Audio break case WhatsAppMessageType.VIDEO: if (messagePayload.isStatus) { type = PUPPET.types.Message.Post } else { type = PUPPET.types.Message.Video } break case WhatsAppMessageType.CONTACT_CARD: type = PUPPET.types.Message.Contact break case WhatsAppMessageType.DOCUMENT: type = PUPPET.types.Message.Attachment break case WhatsAppMessageType.LOCATION: type = PUPPET.types.Message.Location break case WhatsAppMessageType.REVOKED: type = PUPPET.types.Message.Recalled break case WhatsAppMessageType.PRODUCT: type = PUPPET.types.Message.MiniProgram break case SpecialSystemType: type = PUPPET.types.Message.System } return type }