Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix recalled message #81

Closed
wants to merge 0 commits into from
Closed

fix recalled message #81

wants to merge 0 commits into from

Conversation

wxul
Copy link
Member

@wxul wxul commented Apr 12, 2019

最近使用发现撤回消息不会被触发, 在分析源码和进行调试后发现有以下几个问题并提交此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.

@huan
Copy link
Member

huan commented Apr 13, 2019

@wxul Thanks, you did a great job!

The analysis looks good and the code basically should work.

This issue is related to wechaty/wechaty#1728, so please go to there and have a look, and also I'd like to invite @windmemory to review this PR for you.

@windmemory Would you like to review this PR so that we can make sure it will compatible with your PR at wechaty/wechaty#1735?

Thank you very much.

@huan huan requested review from windmemory and a team April 13, 2019 23:59
Copy link

@kis87988 kis87988 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR makes sense to me.


// add recalled message
m.MsgType = confFactory.MSGTYPE_RECALLED
m.MMActualContent = JSON.stringify(revokemsg)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From the design in wechaty/wechaty#1735, the content should be the recalled message id, so looks like here should be:

m.MMActualContent = revokemsg.msgid

Then using the toRecalled method on Message instance, the recalled message can be retrieved back.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I think so.

Please go to review interface and add your suggestions as a required change for this PR, thanks!

Copy link
Member

@windmemory windmemory left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please revise the code according to the comments in the code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants