puppet-wechat icon indicating copy to clipboard operation
puppet-wechat copied to clipboard

fix recalled message (from @wxul)

Open huan opened this issue 6 years ago • 3 comments

Author: @wxul

最近使用发现撤回消息不会被触发, 在分析源码和进行调试后发现有以下几个问题并提交此PR修复: MessageType.Recalled will not be triggered. After analyzing the source code and debugging, I found the following problems and submitted this PR to fix:

  1. 撤回消息的xml中多了一些<br/>导致 xml2json 解析失败 (The <br/> tag in message text causing xml2json parsing to fail.)

src/wechaty-bro.js

      var content = utilFactory.htmlDecode(m.MMActualContent)
      content = utilFactory.encodeEmoji(content)
      // remove <br/> here
      content = content.replace(/<br.*?\/>/g, '')
      var revokemsg = utilFactory.xml2json(content).revokemsg
  1. 撤回消息会被当成 MessageType.Text 类型 (WebMessageType.RECALLED message will be converted to MessageType.Text)

src/pure-function-helpers/web-message-type.ts

    // add recall type
    case WebMessageType.RECALLED:
      return MessageType.Recalled
  1. 撤回消息之后, 触发的message事件中收到的消息是MessageType.Recalled类型的源消息实例, 无法判断其原有类型 (When message triggered, the received message is revoked message and it's type was overridden by MessageType.Recalled.)

根据我的设想, MessageType.Recalled消息应该保存被撤销消息的id, 然后由用户去获取被撤销的消息实例 According to my assumption, user should get message ID from MessageType.Recalled message, then find the revoked message.

src/wechaty-bro.js old

      if (revokemsg.msgid) {
        var chatMsgs = chatFactory.getChatMessage(m.MMPeerUserName)
        var i = chatFactory._findMessageByMsgId(chatMsgs, revokemsg.msgid)
        if (i > -1) {
          m = chatMsgs[i]
          m.MsgType = confFactory.MSGTYPE_RECALLED
        } else {
          m.MsgId = revokemsg.msgid
          m.MMActualContent = m.Content = revokemsg.replacemsg.replace(/"/g, '')
        }
        WechatyBro.emit('message', m)
      }

new

      if (revokemsg.msgid) {
        // add recalled message
        m.MsgType = confFactory.MSGTYPE_RECALLED
        m.MMActualContent = JSON.stringify(revokemsg)
        chatFactory.addChatMessage(m)
      }

usage

bot.on('message', async function(message) {
  switch (message.type()) {
    case Message.Type.Recalled:
      console.log('Recalled', message.text()); // {"session":"7056706088@chatroom","oldmsgid":"1627228679","msgid":"176813759318050095","replacemsg":"\\"XXXXX\\" 撤回了一条消息"}
      try {
        let revokemsg = JSON.parse(message.text());
        let msgId = revokemsg.msgid;
        let msg = bot.Message.load(msgId);
        await msg.ready();

        console.log('Revoked message', msg.toString());
      } catch (error) {}
      break;
  }
});

END

PS: 我看源码的时间并不多, 对wechaty以及puppet的理解也仅限于业务接触到的地方, 如果有不合理的设计, 还望指正.

PS(from Google translate): I don't have much time to look at the source code. The understanding of wechaty and puppet is limited to the places where the business comes into contact. If there is an unreasonable design, I still want to correct me.

See Also

#81 #84 https://github.com/Chatie/wechaty/issues/1728

huan avatar Apr 15 '19 02:04 huan

@wxul Welcome to be a contributor of Chatie project!

I had just sent you an invitation to join our community, please check your email to accept the invitation.

You've invited Albert.Wu to Chatie! They'll be receiving an email shortly. They can also visit https://github.com/Chatie to accept the invitation.

@lijiarui

huan avatar Apr 15 '19 02:04 huan

@wxul Welcome to be a contributor of Chatie project!

I had just sent you an invitation to join our community, please check your email to accept the invitation.

You've invited Albert.Wu to Chatie! They'll be receiving an email shortly. They can also visit https://github.com/Chatie to accept the invitation.

@lijiarui

I am glad to contribute with this project, and this makes sense for my first submission of PR.

wxul avatar Apr 15 '19 03:04 wxul

@wxul Could you add my wechat: 13141321843

lijiarui avatar Apr 23 '19 13:04 lijiarui