消息回复实现方案

更新时间: 2024/03/15 18:26:22

若您需要实现简单的回复功能,可以参考我们在 UIKit 上使用的回复逻辑,以实现简单的类微信的消息回复功能。

方案介绍

在回复的消息中通过扩展参数,保留被回复消息的相关内容。在消息体 NIMMessage 中可以通过 ext 来获取和设置消息体中的远程传输的扩展参数,回复消息的内容就以 Object 形式保存在该消息体中,数据格式如下:

extObj.yxReplyMsg = {
        idClient:  "消息ID",//被回复消息本地产生的唯一ID
        scene:  "p2p",//被回复消息的会话类型,p2p代表单聊,team代表群聊
        from: "fromAccount",//被回复消息的发送者账号
        to: "sessionId",//会话ID
        idServer: serverId //被回复消息的serverID,服务端产生的消息唯一ID
        time:1683361848167,//被回复消息的发送时间,数据类型为Number
}

在发送一条回复消息时,会将上述被回复消息的内容,设置到该消息的 ext 中。

实现流程

  1. 创建一条文本消息。

    store.MsgStore.sendTextMsgActive({
        sence:'p2p',
        to,
        body: '这是一条文本消息'
    })
    
  2. 在文本消息中插入被回复消息内容。

    let options: ISendTextMsgOptions = {
        scene,
        to,
        ext: this._formatExtField(`${scene}-${to}`, ext),
        body,
        // @ts-ignore
        teamSpecializationInfo: {
        needACK: true,
        },
        onSendBefore: (msg) => {
        this.addMsg(msg.sessionId, [msg])
        },
    }
    private _formatExtField(
        sessionId: string,
        ext?: Record<string, unknown>
    ): string | undefined {
        const extObj = ext || {}
        // 有回复消息的情况,需要把回复消息的信息放到 ext 中
        const replyMsg = this.replyMsgs.get(sessionId)
        if (replyMsg) {
        extObj.yxReplyMsg = {
            idClient: replyMsg.idClient,
            scene: replyMsg.scene,
            from: replyMsg.from,
            to: replyMsg.to,
            idServer: replyMsg.idServer,
            time: replyMsg.time,
        }
        }
        return Object.keys(extObj).length === 0 ? undefined : JSON.stringify(extObj)
    }
    

    上述示例中回复消息的 key 值,已经在常量中定义,可以直接使用。

  3. 发送消息。

    this.nim.sendTextMsg(options)
    
  4. 对接收到的消息进行解析,根据 idClient 或者 idserver 来判断是否包含回复内容。

    msgs.forEach((msg) => {
        if (msg.ext) {
            try {
            const { yxReplyMsg } = JSON.parse(msg.ext)
            if (yxReplyMsg) {
                const replyMsg = msgs.find(
                (item) => item.idClient === yxReplyMsg.idClient
                )
                if (replyMsg) {
                replyMsgsMap[msg.idClient] = replyMsg
                } else {
                replyMsgsMap[msg.idClient] = 'noFind'
                const { scene, from, to, idServer, time } = yxReplyMsg
                if (scene && from && to && idServer && time) {
                    reqMsgs.push({ scene, from, to, idServer, time })
                    idClients[idServer] = msg.idClient
                }
                }
            }
            } catch {}
        }
        })
    
  5. 通过获取到消息的 idClient或者 idserver(服务端产生的唯一ID)来查询被回复的消息。

    const idClients: Record<string, string> = {}
        msgs.forEach((msg) => {
        if (msg.ext) {
            try {
            const { yxReplyMsg } = JSON.parse(msg.ext)
            if (yxReplyMsg) {
                const replyMsg = msgs.find(
                (item) => item.idClient === yxReplyMsg.idClient
                )
                if (replyMsg) {
                replyMsgsMap[msg.idClient] = replyMsg
                } else {
                replyMsgsMap[msg.idClient] = 'noFind'
                const { scene, from, to, idServer, time } = yxReplyMsg
                if (scene && from && to && idServer && time) {
                    reqMsgs.push({ scene, from, to, idServer, time })
                    idClients[idServer] = msg.idClient
                }
                }
            }
            } catch {}
        }
        })
        if (reqMsgs.length > 0) {
        store.msgStore.getMsgByIdServerActive({ reqMsgs }).then((res) => {
            res.forEach((item) => {
            if (item.idServer) {
                replyMsgsMap[idClients[item.idServer]] = item
            }
            })
            setReplyMsgsMap({ ...replyMsgsMap })
        })
        } else {
        setReplyMsgsMap({ ...replyMsgsMap })
        }
    
此文档是否对你有帮助?
有帮助
去反馈
  • 方案介绍
  • 实现流程