File Coverage

blib/lib/Weixin/Message.pm
Criterion Covered Total %
statement 15 241 6.2
branch 0 108 0.0
condition 0 29 0.0
subroutine 5 23 21.7
pod 0 3 0.0
total 20 404 4.9


line stmt bran cond sub pod time code
1             package Weixin::Message;
2 1     1   4 use Weixin::Util;
  1         2  
  1         68  
3 1     1   3 use List::Util qw(first);
  1         1  
  1         66  
4 1     1   360 use Weixin::Message::Constant;
  1         2  
  1         24  
5 1     1   630 use Weixin::Client::Private::_send_text_msg;
  1         2  
  1         1062  
6              
7             sub _parse_send_status_data {
8 0     0     my $self = shift;
9 0           my $json = shift;
10 0 0         if(defined $json){
11 0           my $d = $self->json_decode($json);
12 0 0         return {is_success => 0,status=>"数据格式错误"} unless defined $d;
13 0 0         return {is_success => 0,status=>encode_utf8($d->{BaseRequest}{ErrMsg})} if $d->{BaseRequest}{Ret}!=0;
14 0           return {is_success => 1,status=>"发送成功"};
15             }
16             else{
17 0           return {is_success => 0,status=>"请求失败"};
18             }
19             }
20              
21             my %logout_code = qw(
22             1100 0
23             1101 1
24             1102 1
25             1205 1
26             );
27             sub _parse_synccheck_data {
28 0     0     my $self = shift;
29 0           my($retcode,$selector) = @_;
30 0 0   0     if(first {$retcode == $_} keys %logout_code){
  0            
31 0           $self->logout($logout_code{$retcode});
32 0           $self->stop();
33             }
34 0 0 0       if(defined $retcode and defined $selector and $retcode == 0 and $selector != 0){
    0 0        
    0 0        
      0        
      0        
35 0           $self->{_synccheck_error_count}=0;
36 0           $self->_sync();
37             }
38             elsif(defined $retcode and defined $selector and $retcode == 0){
39 0           $self->{_synccheck_error_count}=0;
40 0           $self->_synccheck();
41             }
42             elsif($self->{_synccheck_error_count} < 3){
43 0           $self->{_synccheck_error_count}++;
44 0     0     $self->timer(5,sub{$self->_sync();});
  0            
45             }
46             else {
47 0     0     $self->timer(2,sub{$self->_synccheck();});
  0            
48             }
49             }
50             sub _parse_sync_data {
51 0     0     my $self = shift;
52 0           my $d = shift;
53 0 0   0     if(first {$d->{BaseResponse}{Ret} == $_} keys %logout_code ){
  0 0          
54 0           $self->logout($logout_code{$d->{BaseResponse}{Ret}});
55 0           $self->stop();
56             }
57             elsif($d->{BaseResponse}{Ret} !=0){
58 0           console "收到无法识别消息,已将其忽略\n";
59 0           return;
60             }
61 0 0         $self->sync_key($d->{SyncKey}) if $d->{SyncKey}{Count}!=0;
62 0 0         $self->skey($d->{SKey}) if $d->{SKey};
63 0 0         if($d->{AddMsgCount} != 0){
64 0           my @key = qw(
65             CreateTime
66             FromId
67             ToId
68             Content
69             MsgType
70             MsgId
71             );
72 0           for (@{$d->{AddMsgList}}){
  0            
73 0           my $msg = {};
74 0           $_->{FromId} = $_->{FromUserName};delete $_->{FromUserName};
  0            
75 0           $_->{ToId} = $_->{ToUserName};delete $_->{ToUserName};
  0            
76 0           @{$msg}{@key} = map {$_=encode_utf8($_);$_} @{$_}{@key};
  0            
  0            
  0            
  0            
77 0           $self->_add_msg($msg);
78             }
79             }
80 0 0         if($d->{ModContactCount}!=0){
81 0           for(@{$d->{ModContactList}}){
  0            
82 0 0         if($self->is_chatroom($_->{UserName})){
83 0           $_->{ChatRoomId} = $_->{UserName};delete $_->{UserName};
  0            
84 0           $_->{OwnerId} = $_->{ChatRoomOwner};delete $_->{ChatRoomOwner};
  0            
85 0           $_->{ChatRoomName} = $_->{NickName};delete $_->{NickName};
  0            
86 0           my @chartroom_key = qw(ChatRoomUin MemberCount OwnerUin ChatRoomId ChatRoomName OwnerId);
87 0           my @member_key = qw(HeadImgUrl NickName PYInitial PYQuanPin Alias Province City Sex Id Uin Signature DisplayName RemarkName RemarkPYInitial RemarkPYQuanPin);
88              
89 0           my $chatroom = $self->search_chatroom(ChatRoomId => $_->{ChatRoomId}) ;
90 0           my $is_new_chatroom = 0;
91 0 0         unless(defined $chatroom){
92 0           $is_new_chatroom = 1;
93 0           $chatroom = {};
94             }
95 0           for my $k(@chartroom_key){
96 0 0         $chatroom->{$k} = encode_utf8($_->{$k}) if defined $_->{$k};
97             }
98 0 0         if($_->{MemberCount} != 0){
99 0           my %members ;
100 0           for my $m (@{$_->{MemberList}}){
  0            
101 0           $m->{Id} = $m->{UserName};delete $m->{UserName};
  0            
102 0           my $member = {};
103 0           for my $k(@member_key){
104 0 0         $member->{$k} = encode_utf8($m->{$k}) if defined $m->{$k};
105             }
106 0           $member->{$_} = $chatroom->{$_} for(grep {$_ ne "Member"} keys %$chatroom);
  0            
107 0           $members{ $member->{Id} } = $member;
108             }
109 0 0         if($is_new_chatroom){#new chatroom
110 0           $chatroom->{Member} = [values %members];
111 0           $self->add_chatroom($chatroom,1);
112             }
113             else{#chatroom modified
114 0           for(@{$chatroom->{Member}}){
  0            
115 0 0         next unless exists $members{$_->{Id}};
116 0           for my $k(keys %$_){
117 0 0         next if exists $members{$_->{Id}}{$k};
118 0           $members{$_->{Id}}{$k} = $_->{$k};
119             }
120             }
121 0           $chatroom->{Member} = [values %members];
122             }
123             }
124             }
125             else{
126 0           my @friend_key = qw(HeadImgUrl NickName PYInitial PYQuanPin Alias Province City Sex Id Uin Signature DisplayName RemarkName RemarkPYInitial RemarkPYQuanPin);
127 0           $_->{Id} = $_->{UserName};delete $_->{UserName};
  0            
128 0 0         $_->{Sex} = code2sex($_->{Sex}) if $_->{Sex};
129 0           my $friend = $self->search_friend(Id=>$_->{Id});
130 0           my $is_new_friend = 0;
131 0 0         unless(defined $friend){
132 0           $is_new_friend = 1;
133 0           $friend = {};
134             }
135 0           for my $k(@friend_key){
136 0 0         $friend->{$k} = encode_utf8($_->{$k}) if defined $_->{$k};
137             }
138 0 0         $self->add_friend($friend) if $is_new_friend;
139             }
140             }
141             }
142 0 0         if($d->{DelContactCount}!=0){
143 0           for(@{$d->{DelContactList}}){
  0            
144 0 0         if($self->is_chatroom($_->{UserName})){
145 0           $_->{ChatRoomId} = $_->{UserName};delete $_->{UserName};
  0            
146 0           $self->del_chatroom($_->{ChatRoomId});
147             }
148             else{
149 0           $_->{Id} = $_->{UserName};delete $_->{UserName};
  0            
150 0           $self->del_friend($_->{Id});
151             }
152             }
153             }
154 0 0         if($d->{ModChatRoomMemberCount}!=0){
155            
156             }
157 0 0         if($d->{ContinueFlag}!=0){
158 0           $self->_sync();
159             }
160             else{
161 0           $self->_synccheck();
162             }
163            
164             }
165              
166             sub _add_msg{
167 0     0     my $self = shift;
168 0           my $msg = shift;
169 0           $msg->{TTL} = 5;
170 0 0         if($msg->{MsgType} eq MM_DATA_TEXT){
    0          
    0          
    0          
    0          
171 0           $msg->{MsgType} = "text";
172 0 0         if($msg->{FromId} eq $self->{_data}{user}{Id}){
    0          
173 0           $msg->{MsgClass} = "send";
174             }
175             elsif($msg->{ToId} eq $self->{_data}{user}{Id}){
176 0           $msg->{MsgClass} = "recv";
177             }
178            
179 0 0         if($msg->{MsgClass} eq "send"){
    0          
180 0 0         $msg->{Type} = $self->is_chatroom($msg->{ToId})?"chatroom_message":"friend_message";
181 0 0         if($msg->{Type} eq "friend_message"){
    0          
182 0   0       my $friend = $self->search_friend(Id=>$msg->{ToId}) || {};
183 0           $msg->{FromNickName} = "我";
184 0           $msg->{FromRemarkName} = "我";
185 0           $msg->{FromUin} = $self->{_data}{user}{Uin};
186 0           $msg->{ToUin} = $friend->{Uin};
187 0           $msg->{ToNickName} = $friend->{NickName};
188 0           $msg->{ToRemarkName} = $friend->{RemarkName};
189             }
190             elsif($msg->{Type} eq "chatroom_message"){
191 0   0       my $chatroom = $self->search_chatroom(ChatRoomId=>$msg->{ToId}) || $self->get_chatroom($msg->{ToId}) || {};
192 0           $msg->{FromNickName} = "我";
193 0           $msg->{FromRemarkName} = undef;
194 0           $msg->{FromUin} = $self->{_data}{user}{Uin};
195 0           $msg->{ToUin} = $chatroom->{ChatRoomUin};
196 0           $msg->{ToNickName} = $chatroom->{ChatRoomName};
197 0           $msg->{ToRemarkName} = undef;
198             }
199 0           $msg = $self->_mk_ro_accessors($msg,"Send");
200             }
201             elsif($msg->{MsgClass} eq "recv"){
202 0 0         $msg->{Type} = $self->is_chatroom($msg->{FromId})?"chatroom_message":"friend_message";
203 0 0         if($msg->{Type} eq "friend_message"){
    0          
204 0   0       my $friend = $self->search_friend(Id=>$msg->{FromId}) || {};
205 0           $msg->{FromNickName} = $friend->{NickName};
206 0           $msg->{FromRemarkName} = $friend->{RemarkName};
207 0           $msg->{FromUin} = $friend->{Uin};;
208 0           $msg->{ToUin} = $self->{_data}{user}{Uin};
209 0           $msg->{ToNickName} = "我";
210 0           $msg->{ToRemarkName} = undef;
211             }
212             elsif($msg->{Type} eq "chatroom_message"){
213 0           my ($chatroom_member_id,$content) = $msg->{Content}=~/^(\@.+):(.*)/g;
214 0           $msg->{Content} = $content;
215 0   0       my $member = $self->search_chatroom_member(ChatRoomId=>$msg->{FromId},Id=>$chatroom_member_id) || $self->get_chatroom($msg->{FromId}) || {};
216 0           $msg->{FromNickName} = $member->{NickName};
217 0           $msg->{FromId} = $member->{Id};
218 0           $msg->{FromRemarkName} = undef;
219 0           $msg->{FromUin} = $member->{Uin};;
220 0           $msg->{ToUin} = $self->{_data}{user}{Uin};
221 0           $msg->{ToNickName} = "我";
222 0           $msg->{ToRemarkName} = undef;
223 0           $msg->{ChatRoomName} = $member->{ChatRoomName};
224 0           $msg->{ChatRoomUin} = $member->{ChatRoomUin};
225 0           $msg->{ChatRoomId} = $member->{ChatRoomId};
226             }
227 0           $msg = $self->_mk_ro_accessors($msg,"Recv");
228             }
229            
230 0           $self->{_receive_message_queue}->put($msg);
231             }
232             elsif($msg->{MsgType} eq MM_DATA_STATUSNOTIFY){
233             }
234             elsif($msg->{MsgType} eq MM_DATA_SYSNOTICE){
235            
236             }
237             elsif($msg->{MsgType} eq MM_DATA_APPMSG){
238            
239             }
240             elsif($msg->{MsgType} eq MM_DATA_EMOJI){
241              
242             }
243             }
244             sub _del_friend{
245 0     0     my $self = shift;
246             }
247             sub _mod_chatroom_member{
248 0     0     my $self = shift;
249             }
250             sub _mod_friend{
251 0     0     my $self = shift;
252             }
253             sub _mod_profile {
254 0     0     my $self = shift;
255             }
256              
257             sub _mk_ro_accessors {
258 0     0     my $self = shift;
259 0           my $msg =shift;
260 0           my $msg_pkg = shift;
261 1     1   6 no strict 'refs';
  1         1  
  1         526  
262 0           for my $field (keys %$msg){
263 0           *{__PACKAGE__ . "::${msg_pkg}::$field"} = sub{
264 0     0     my $obj = shift;
265 0           my $pkg = ref $obj;
266 0 0         die "the value of \"$field\" in $pkg is read-only\n" if @_!=0;
267 0           return $obj->{$field};
268 0           };
269             }
270 0           return bless $msg,__PACKAGE__."::$msg_pkg";
271             }
272              
273             sub send_friend_msg {
274 0     0 0   my $self = shift;
275 0           my ($friend,$content) = @_;
276 0 0 0       unless(defined $friend and $friend->{Id}){
277 0           console "send_friend_msg 参数无效\n";
278 0           return;
279             }
280 0 0         unless($content){
281 0           console "send_friend_msg 发送内容不能为空\n";
282 0           return ;
283             }
284 0           my $msg = $self->_create_text_msg($friend,$content,"friend_message");
285 0           $self->{_send_message_queue}->put($msg);
286             }
287              
288             sub send_chatroom_msg {
289 0     0 0   my $self = shift;
290 0           my ($chatroom,$content) = @_;
291 0 0 0       unless(defined $chatroom and $chatroom->{ChatRoomId}){
292 0           console "send_chatroom_msg 参数无效\n";
293 0           return;
294             }
295 0 0         unless($content){
296 0           console "send_chatroom_msg 发送内容不能为空\n";
297 0           return ;
298             }
299 0           my $msg = $self->_create_text_msg($chatroom,$content,"chatroom_message");
300 0           $self->{_send_message_queue}->put($msg);
301             }
302              
303             sub reply_msg {
304 0     0 0   my $self = shift;
305 0           my $msg = shift;
306 0           my $content = shift;
307 0 0         return if $msg->{MsgClass} ne "recv";
308 0 0         if($msg->{Type} eq "chatroom_message"){
    0          
309 0           my $chatroom = $self->search_chatroom(Id=>$msg->{ChatRoomId});
310 0           $self->send_chatroom_msg($chatroom,$content);
311             }
312             elsif($msg->{Type} eq "friend_message"){
313 0           my $friend = $self->search_friend(Id=>$msg->{FromId});
314 0           $self->send_friend_msg($friend,$content);
315             }
316             }
317              
318             sub _create_text_msg{
319 0     0     my $self = shift;
320 0           my ($obj,$content,$type)= @_;
321 0           my $to_id;
322             my $to_uin;
323 0           my $to_nickname;
324 0           my $remark_name;
325 0 0         if($type eq "chatroom_message"){
    0          
326 0           $to_id = $obj->{ChatRoomId};
327 0           $to_uin = $obj->{ChatRoomUin};
328 0           $to_nickname = $obj->{ChatRoomName};
329             }
330             elsif($type eq "friend_message"){
331 0           $to_id = $obj->{Id};
332 0           $to_uin = $obj->{Uin};
333 0           $to_nickname = $obj->{NickName};
334 0           $remark_name = $obj->{RemarkName};
335             }
336 0           my $t = $self->now();
337 0           my $msg = {
338             CreateTime => time(),
339             MsgId => $t,
340             Content => $content,
341             FromId => $self->user->{Id},
342             FromNickName=> "我",
343             FromRemarkName => undef,
344             FromUin => $self->user->{Uin},
345             ToId => $to_id,
346             ToNickName => $to_nickname,
347             ToRemarkName=> $remark_name,
348             ToUin => $to_uin,
349             MsgType => "text",
350             MsgClass => "send",
351             Type => $type,
352             TTL => 5,
353             };
354 0           return $self->_mk_ro_accessors($msg,"Send");
355             }
356              
357             1;