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(wechaty-bro): resolved emit RECALLED type msg (fix #8) #744

Merged
merged 6 commits into from
Sep 3, 2017

Conversation

binsee
Copy link

@binsee binsee commented Aug 18, 2017

fix #8

image

@binsee
Copy link
Author

binsee commented Aug 18, 2017

There is a small problem with this way, after the recall message, the web page displays a blank message.
But does not affect the use.

@coveralls
Copy link

coveralls commented Aug 18, 2017

Coverage Status

Coverage remained the same at 54.688% when pulling 6976262 on binsee:fix-recalled into d3aa251 on Chatie:master.

@coveralls
Copy link

coveralls commented Aug 18, 2017

Coverage Status

Coverage decreased (-0.09%) to 54.599% when pulling 4a7dff8 on binsee:fix-recalled into d3aa251 on Chatie:master.

Copy link
Member

@huan huan left a comment

Choose a reason for hiding this comment

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

Your implement is clean and straight forward, Awesome job!

And the message usage is what I thought it should be: a message with RECALLED MsgType set.

I leave some questions & suggestions in the review message, please let me know what you think.

Thanks!

@@ -76,6 +76,7 @@
glueToAngular()
connectSocket()
hookEvents()
hookProcess()
Copy link
Member

Choose a reason for hiding this comment

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

I'd like to suggest we name this function to hookRecalledMsgProcess because that would look more straight forward than hookProcess.

Copy link
Author

Choose a reason for hiding this comment

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

I use hookProcess because I think in the future may add other hooks. But for now, the term is not clear, I will modify it.


function hookProcess() {
var chatFactory = WechatyBro.glue.chatFactory
var rootScope = WechatyBro.glue.rootScope
Copy link
Member

Choose a reason for hiding this comment

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

rootScope is not needed at here.

Copy link
Author

Choose a reason for hiding this comment

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

i will remove it.

// hook chatFactory._recalledMsgProcess, resolve emit RECALLED type msg
chatFactory.__recalledMsgProcess = chatFactory._recalledMsgProcess
chatFactory._recalledMsgProcess = function (msg) {
var _this = this
Copy link
Member

Choose a reason for hiding this comment

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

What's the reason that you save this to _this?

IMHO, It seems not necessary to do that inside this function?

chatFactory.__recalledMsgProcess = chatFactory._recalledMsgProcess
chatFactory._recalledMsgProcess = function (msg) {
var _this = this
_this.__recalledMsgProcess(msg)
Copy link
Member

Choose a reason for hiding this comment

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

How about use chatFactory at here instead of this?

Like: chatFactory.__recalledMsgProcess and __recalledMsgProcess.addChatMessage

Copy link
Author

Choose a reason for hiding this comment

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

I modified it, it can work:

    chatFactory._recalledMsgProcess = function (msg) {
      chatFactory.__recalledMsgProcess(msg)
      chatFactory.addChatMessage(msg)
    }

src/message.ts Outdated
* })
* ```
*/
public getRevokeId(): string {
Copy link
Member

Choose a reason for hiding this comment

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

Why we need to add this new method?

I did not think it's necessary.

Please correct me if I'm wrong.

Copy link
Author

Choose a reason for hiding this comment

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

RECALLED msg, content:

<sysmsg type="revokemsg"><revokemsg><session>binsee</session><oldmsgid>1056815127</oldmsgid><msgid>6991717488370193149</msgid><replacemsg><![CDATA["杉木" 撤回了一条消息]]></replacemsg></revokemsg></sysmsg>

use UtilLib.unescapeHtml(this.obj.content)

// the content has been formatted
<sysmsg type="revokemsg">
    <revokemsg>
        <session>binsee</session>
        <oldmsgid>1056815127</oldmsgid>
        <msgid>6991717488370193149</msgid>
        <replacemsg>
            <![CDATA["杉木" 撤回了一条消息]]>
        </replacemsg>
    </revokemsg>
</sysmsg>

We need to use getRevokeId () package to extract the code msgId

const ret = UtilLib.unescapeHtml(this.obj.content).match(/<msgid>(\w+)<\/msgid>/)

@binsee
Copy link
Author

binsee commented Aug 19, 2017

RECALLED msg, content:

&lt;sysmsg type="revokemsg"&gt;&lt;revokemsg&gt;&lt;session&gt;binsee&lt;/session&gt;&lt;oldmsgid&gt;1056815127&lt;/oldmsgid&gt;&lt;msgid&gt;6991717488370193149&lt;/msgid&gt;&lt;replacemsg&gt;&lt;![CDATA["杉木" 撤回了一条消息]]&gt;&lt;/replacemsg&gt;&lt;/revokemsg&gt;&lt;/sysmsg&gt;

use UtilLib.unescapeHtml(this.obj.content)

// the content has been formatted
<sysmsg type="revokemsg">
    <revokemsg>
        <session>binsee</session>
        <oldmsgid>1056815127</oldmsgid>
        <msgid>6991717488370193149</msgid>
        <replacemsg>
            <![CDATA["杉木" 撤回了一条消息]]>
        </replacemsg>
    </revokemsg>
</sysmsg>

We need to use getRevokeId () package to extract the code msgId

const ret = UtilLib.unescapeHtml(this.obj.content).match(/<msgid>(\w+)<\/msgid>/)

@huan
Copy link
Member

huan commented Aug 19, 2017

I see.

As my understanding now, the parameter of _recalledMsgProcess() is <sysmsg type="revokemsg">...</sysmsg>, right?

If so, I think the better design to do this might be(in wechaty-bro.js):

  1. find the original message for that msgid, then
  2. set the message with MsgType.RECALLED, then
  3. use WechatBro.emit() to emit that message again. (see: https://github.com/Chatie/wechaty/blob/master/src/puppet-web/wechaty-bro.js#L366)

The above design could let the end-user receive a message event, with the original message, but with MsgType.RECALLED set. (and no new method need to be introduced)

How about this idea, what do you think?

@huan huan changed the title fix(wechaty-bro): resolved emit RECALLED type msg fix(wechaty-bro): resolved emit RECALLED type msg (#8) Aug 19, 2017
@huan huan changed the title fix(wechaty-bro): resolved emit RECALLED type msg (#8) fix(wechaty-bro): resolved emit RECALLED type msg (fix #8) Aug 19, 2017
@binsee
Copy link
Author

binsee commented Aug 19, 2017

msg.content='&lt;sysmsg type="revokemsg"&gt;&lt;revokemsg&gt;&lt;session&gt;binsee&lt;/session&gt;&lt;oldmsgid&gt;1056815127&lt;/oldmsgid&gt;&lt;msgid&gt;6991717488370193149&lt;/msgid&gt;&lt;replacemsg&gt;&lt;![CDATA["杉木" 撤回了一条消息]]&gt;&lt;/replacemsg&gt;&lt;/revokemsg&gt;&lt;/sysmsg&gt;'

must use UtilLib.unescapeHtml(this.obj.content), return xml text, and use match to get msgId.
So, still need to use the new method.

@coveralls
Copy link

coveralls commented Aug 19, 2017

Coverage Status

Coverage decreased (-0.1%) to 54.545% when pulling 3a6d5b0 on binsee:fix-recalled into d3aa251 on Chatie:master.

@huan
Copy link
Member

huan commented Aug 19, 2017

Could you do those works in the browser, as my last suggestion?

@binsee
Copy link
Author

binsee commented Aug 19, 2017

Sorry, I read your reply repeatedly and found that I did not fully understand what you meant. I will think again and then update it

@coveralls
Copy link

Coverage Status

Coverage decreased (-0.008%) to 54.68% when pulling 3d66014 on binsee:fix-recalled into d3aa251 on Chatie:master.

@binsee
Copy link
Author

binsee commented Aug 19, 2017

In the wechaty-bro to achieve the RECALLED message handling, it looks good results.
But encountered a question that needs to be discussed:

The order in which the code is called will produce a different return effect. Which do we choose?

Description: dev_tag is my added field for debugging notes

Option 1

First chatFactory._recalledMsgProcess again WechatyBro.emit

Recalled the WebWxApp received the message, rawObj data:

msg.type() return MsgType.RECALLED
msg.content() return 杉木撤回了一条消息

msg.rawObj.MMRecall == true

{"MsgId":"3066610148686027451","FromUserName":"@d4d830178e30550380be2175c454951f","ToUserName":"@ae39ddd7f22214f8f330b68aaa8ec0190702c0c33467b2a23338a77221e6f431",
"MsgType":10002,
"Content":"接收到的消息内容","Status":3,"ImgStatus":1,"CreateTime":1503162116,"VoiceLength":0,"PlayLength":0,"FileName":"","FileSize":"","MediaId":"","Url":"","AppMsgType":0,"StatusNotifyCode":0,"StatusNotifyUserName":"","RecommendInfo":{"UserName":"","NickName":"","QQNum":0,"Province":"","City":"","Content":"","Signature":"","Alias":"","Scene":0,"VerifyFlag":0,"AttrStatus":0,"Sex":0,"Ticket":"","OpCode":0},"ForwardFlag":0,"AppInfo":{"AppID":"","Type":0},"HasProductId":0,"Ticket":"","ImgHeight":0,"ImgWidth":0,"SubMsgType":0,"NewMsgId":3066610148686027300,"OriContent":"","MMPeerUserName":"@d4d830178e30550380be2175c454951f",
"MMDigest":"杉木撤回了一条消息","MMIsSend":false,"MMIsChatRoom":false,"MMUnread":true,"LocalID":"3066610148686027451",
"ClientMsgId":"3066610148686027451",
"MMActualContent":"杉木撤回了一条消息",
"MMActualSender":"@d4d830178e30550380be2175c454951f","MMDigestTime":"1:01","MMDisplayTime":1503162116,"MMTime":"1:01","_h":0,
"MMRecall":true,
"dev_tag":"这是基于原先的消息体"}

Recalled the WebWxApp did not received the message, rawObj data:

msg.type() return MsgType.RECALLED
msg.content() return 杉木 撤回了一条消息

{"MsgId":"443731713080375307","FromUserName":"@d4d830178e30550380be2175c454951f","ToUserName":"@ae39ddd7f22214f8f330b68aaa8ec0190702c0c33467b2a23338a77221e6f431",
"MsgType":10002,
"Content":"杉木 撤回了一条消息","Status":4,"ImgStatus":1,"CreateTime":1503162122,"VoiceLength":0,"PlayLength":0,"FileName":"","FileSize":"","MediaId":"","Url":"","AppMsgType":0,"StatusNotifyCode":0,"StatusNotifyUserName":"","RecommendInfo":{"UserName":"","NickName":"","QQNum":0,"Province":"","City":"","Content":"","Signature":"","Alias":"","Scene":0,"VerifyFlag":0,"AttrStatus":0,"Sex":0,"Ticket":"","OpCode":0},"ForwardFlag":0,"AppInfo":{"AppID":"","Type":0},"HasProductId":0,"Ticket":"","ImgHeight":0,"ImgWidth":0,"SubMsgType":0,"NewMsgId":1357981904162237700,"OriContent":"","MMPeerUserName":"@d4d830178e30550380be2175c454951f",
"MMDigest":"","MMIsSend":false,"MMIsChatRoom":false,"MMUnread":true,"LocalID":"1357981904162237688",
"ClientMsgId":"1357981904162237688",
"MMActualContent":"杉木 撤回了一条消息",
"MMActualSender":"@d4d830178e30550380be2175c454951f","MMDigestTime":"1:02","MMDisplayTime":1503162116,"MMTime":"",
"dev_tag":"这是基于撤消操作消息体"}

Option 2

First WechatyBro.emit again chatFactory._recalledMsgProcess

Recalled the WebWxApp received the message, rawObj data:

msg.type() return MsgType.RECALLED
msg.content() return 接收到的消息内容

{"MsgId":"5026368840711665152","FromUserName":"@d4d830178e30550380be2175c454951f","ToUserName":"@ae39ddd7f22214f8f330b68aaa8ec0190702c0c33467b2a23338a77221e6f431",
"MsgType":10002,
"Content":"接收到的消息内容","Status":3,"ImgStatus":1,"CreateTime":1503162474,"VoiceLength":0,"PlayLength":0,"FileName":"","FileSize":"","MediaId":"","Url":"","AppMsgType":0,"StatusNotifyCode":0,"StatusNotifyUserName":"","RecommendInfo":{"UserName":"","NickName":"","QQNum":0,"Province":"","City":"","Content":"","Signature":"","Alias":"","Scene":0,"VerifyFlag":0,"AttrStatus":0,"Sex":0,"Ticket":"","OpCode":0},"ForwardFlag":0,"AppInfo":{"AppID":"","Type":0},"HasProductId":0,"Ticket":"","ImgHeight":0,"ImgWidth":0,"SubMsgType":0,"NewMsgId":5026368840711666000,"OriContent":"","MMPeerUserName":"@d4d830178e30550380be2175c454951f",
"MMDigest":"接收到的消息内容","MMIsSend":false,"MMIsChatRoom":false,"MMUnread":false,"LocalID":"5026368840711665152",
"ClientMsgId":"5026368840711665152",
"MMActualContent":"接收到的消息内容","MMActualSender":"@d4d830178e30550380be2175c454951f","MMDigestTime":"1:07","MMDisplayTime":1503162297,"MMTime":"","_index":33,"_h":56,"_calcing":false,"_offsetTop":1853,"$$hashKey":"0CO",
"dev_tag":"这是基于原先的消息体"}

Recalled the WebWxApp did not received the message, rawObj data:

msg.type() return MsgType.RECALLED
msg.content() return 杉木 撤回了一条消息

{"MsgId":"3684395441945462470","FromUserName":"@d4d830178e30550380be2175c454951f","ToUserName":"@ae39ddd7f22214f8f330b68aaa8ec0190702c0c33467b2a23338a77221e6f431",
"MsgType":10002,
"":"杉木 撤回了一条消息","Status":4,"ImgStatus":1,"CreateTime":1503162479,"VoiceLength":0,"PlayLength":0,"FileName":"","FileSize":"","MediaId":"","Url":"","AppMsgType":0,"StatusNotifyCode":0,"StatusNotifyUserName":"","RecommendInfo":{"UserName":"","NickName":"","QQNum":0,"Province":"","City":"","Content":"","Signature":"","Alias":"","Scene":0,"VerifyFlag":0,"AttrStatus":0,"Sex":0,"Ticket":"","OpCode":0},"ForwardFlag":0,"AppInfo":{"AppID":"","Type":0},"HasProductId":0,"Ticket":"","ImgHeight":0,"ImgWidth":0,"SubMsgType":0,"NewMsgId":8699756819766069000,"OriContent":"","MMPeerUserName":"@d4d830178e30550380be2175c454951f",
"MMDigest":"","MMIsSend":false,"MMIsChatRoom":false,"MMUnread":true,"LocalID":"8699756819766068805",
"ClientMsgId":"8699756819766068805",
"MMActualContent":"杉木 撤回了一条消息","MMActualSender":"@d4d830178e30550380be2175c454951f","MMDigestTime":"1:07","MMDisplayTime":1503162479,"MMTime":"1:07",
"dev_tag":"这是基于撤消操作消息体"}

I think Recalled type of message, using type () to judge, only through the msg.id to obtain the recalled msgId, do not deal with other information, or only as a reference.
Especially when the withdrawn message is not TEXT type.

I recommend choosing Option 1

@binsee
Copy link
Author

binsee commented Aug 19, 2017

I think the code is perfect, no need to change.
Please check the code, please tell me if there is a problem.

@huan
Copy link
Member

huan commented Aug 20, 2017

Yes, the code is very good, that's exactly what's I suggest. 👍

And about the two options, I would like to think it by intuition: when a message is revoked, the orignal message should be fired again, with the MsgType set to RECALLED.

In detail:

  1. When we received a normal message, let's say, an image. The on('message', cb) event will be fired, with a message of that image as the parameter of cb, and the message should be instance of MediaMessage.
  2. After a while, the sender decides to REVOKE that image. Then the on('message', cb) event will be fired again, for the revoked message. The message should be as same as the last message, except that the MsgType is set to RECALLED.

Copy link
Member

@huan huan left a comment

Choose a reason for hiding this comment

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

The code looks great to me.

I'll merge this PR after you get another two approvements from our contributors.

Thank you for implementing issue #8 !

Copy link
Member

@lijiarui lijiarui left a comment

Choose a reason for hiding this comment

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

Thanks!

@huan huan requested a review from hczhcz September 1, 2017 16:44
@binsee
Copy link
Author

binsee commented Sep 2, 2017

@hczhcz
Can I invite you to take the time to review this pr?
Thanks!

Copy link
Member

@hczhcz hczhcz left a comment

Choose a reason for hiding this comment

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

The code looks good to me.

@huan
Copy link
Member

huan commented Sep 3, 2017

Thanks all for reviewing the code!

@huan huan merged commit 174b677 into wechaty:master Sep 3, 2017
@binsee binsee deleted the fix-recalled branch September 3, 2017 15:47
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.

it seems RECALLED: 10002 message dose't trigger on('message') event
5 participants