微信登录原理

微信机器人原理:

$self->_login()
$self->_init();
$self->_get_chatroom();
$self->_update_chatroom_member();
$self->update_friend();


安装路径:
/usr/local/share/perl5/Weixin


my $client = Weixin::Client->new(debug=>0);
$client->load("ShowMsg");
$client->login();
$client->on_receive_msg = sub{
    my $msg = shift ;
    #打印收到的消息
    $client->call("ShowMsg",$msg);
    #对收到的消息,以相同的内容回复
    #$client->reply_msg($msg,$msg->{Content});
};
$client->on_send_msg = sub {
    my ($msg,$is_success,$status) = @_;    
    #打印发送的消息
    $client->call("ShowMsg",$msg);
};
$client->run();


1.问下 微信的$client->on_receive_msg = sub{
    my $msg = shift ; 这个$msg 最初的来源在哪里的
最初的接收的消息 
灰灰(308165330)  10:41:33
Weixin/Message.pm line 73

Client/Private/_sync.pm  接收消息  异步方式

$self->asyn_http_post()
$self->http_post()
异步http请求,阻塞http请求 我封装了这两个

sub asyn_http_get {
    my $self = shift;
    my $callback = pop;
    my $ua = $self->{asyn_ua};
    $ua->get(@_,sub{
        my $response = shift;
        $self->{cookie_jar}->save;
        print $response->content(),"
" if $self->{debug};
        $callback->($response);
    });
}
sub http_post{
    my $self = shift;
    my $ua = $self->{ua};
    my $res = $ua->post(@_);
    $self->{cookie_jar}->save;
    return (defined $res and $res->is_success)?$res->content:undef;
}


Client/Private/_send_text_msg.pm 发送消息
发异步请求 就是使用 Weixin::UserAgent 这个异步请求的类
这个异步请求的类 又是封装了 AnyEvent::HTTTP 这个模块 这个模块又是基于AnyEvent的异步来实现http起步请求的

my $client = Weixin::Client->new(debug=>0); 调用Weixin::Client 类的new方法如下,传入参数为debug=>0
sub new{
    my $class = shift;
    my %p = @_;
    my $agent = 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062'; 
    my $tmpdir = File::Spec->tmpdir();
    my $cookie_filename = $p{login_file} || "$tmpdir/weixin_client_login.dat";
    my $self = {
        cookie_jar              => HTTP::Cookies->new(hide_cookie2=>1,file=>$cookie_filename,autosave=>1),
        debug                   => $p{debug},
        _token                  => {},
        _watchers               => {},
        _intervals              => {},
        _synccheck_error_count  => 0,
        _synccheck_running      => 0,
        _sync_running           => 0,
        _sync_interval          => 1,
        _synccheck_interval     => 1,
        _send_msg_interval      => 4,
        _last_sync_time         => undef,
        _last_synccheck_time    => undef,
        _send_message_queue     => Weixin::Message::Queue->new,
        _receive_message_queue  => Weixin::Message::Queue->new,       
        _data       => {
            user                => {},  
            friend              => [],
            chatroom            => [],
        },
        on_run                  => undef,
        on_receive_msg          => undef,
        on_send_msg             => undef,
        is_stop                 => 0,
        plugin_num              => 0,
        plugins                 => {},
        ua_retry_times          => 5,
        tmpdir                  => $tmpdir,
        client_version          => $VERSION,
    };
    $self->{ua} = LWP::UserAgent->new(
        cookie_jar      =>  $self->{cookie_jar},
        agent           =>  $agent,
        timeout         =>  300,
        ssl_opts        =>  {verify_hostname => 0},
    );
    $self->{asyn_ua} = Weixin::UserAgent->new(
        cookie_jar  =>  $self->{cookie_jar},
        agent       =>  $agent,
        request_timeout =>  300,
        inactivity_timeout  =>  300,
    );

    if($self->{debug}){
        $self->{ua}->add_handler(request_send => sub {
            my($request, $ua, $h) = @_;
            print $request->as_string;
            return;
        });
        $self->{ua}->add_handler(
            response_header => sub { my($response, $ua, $h) = @_;
            print $response->as_string;
            return;
            
        });
        $self->{ua}->add_handler(
            response_done => sub { my($response, $ua, $h) = @_;
            print substr($response->content,0,1000),"
" if $response->header("content-type")=~/^text/;
            return;
        });
    }
    bless $self,$class;
    $self->prepare();
    return $self;
}



登录、获取好友信息等这些http请求是阻塞的,必须等待执行返回


接收消息、发送消息这些http请求是异步的 不需要阻塞在那里




这里传入的:
$class is Weixin::Client

%p is debug0


返回的对象:
$self is ------
$VAR1 = bless( {
                 'ua' => bless( {
                                  'max_redirect' => 7,
                                  'protocols_forbidden' => undef,
                                  'show_progress' => undef,
                                  'handlers' => {
                                                  'request_prepare' => bless( [
                                                                                {
                                                                                  'owner' => 'LWP::UserAgent::cookie_jar',
                                                                                  'callback' => sub { "DUMMY" },
                                                                                  'line' => '/usr/share/perl5/LWP/UserAgent.pm:630'
                                                                                }
                                                                              ], 'HTTP::Config' ),
                                                  'response_header' => bless( [
                                                                                {
                                                                                  'owner' => 'LWP::UserAgent::parse_head',
                                                                                  'callback' => sub { "DUMMY" },
                                                                                  'm_media_type' => 'html',
                                                                                  'line' => '/usr/share/perl5/LWP/UserAgent.pm:609'
                                                                                }
                                                                              ], 'HTTP::Config' ),
                                                  'response_done' => bless( [
                                                                              {
                                                                                'owner' => 'LWP::UserAgent::cookie_jar',
                                                                                'callback' => sub { "DUMMY" },
                                                                                'line' => '/usr/share/perl5/LWP/UserAgent.pm:633'
                                                                              }
                                                                            ], 'HTTP::Config' )
                                                },
                                  'no_proxy' => [],
                                  'protocols_allowed' => undef,
                                  'use_eval' => 1,
                                  'requests_redirectable' => [
                                                               'GET',
                                                               'HEAD'
                                                             ],
                                  'timeout' => 300,
                                  'cookie_jar' => bless( {
                                                           'autosave' => 1,
                                                           'COOKIES' => {
                                                                          'wx.qq.com' => {
                                                                                           '/' => {
                                                                                                    'wxuin' => [
                                                                                                                 '0',
                                                                                                                 '1284510822',
                                                                                                                 undef,
                                                                                                                 1,
                                                                                                                 '',
                                                                                                                 1452669645,
                                                                                                                 ''
                                                                                                               ],
                                                                                                    'webwxuvid' => [
                                                                                                                     '0',
                                                                                                                     '9ee169770fb187e18f67d0876923a8c8e8fdf604d9850d7de806072c57af7ed9e9cd9c8adf120369fc1514659d14ec90',
                                                                                                                     undef,
                                                                                                                     1,
                                                                                                                     '',
                                                                                                                     1767754495,
                                                                                                                     ''
                                                                                                                   ],
                                                                                                    'wxloadtime' => [
                                                                                                                      '0',
                                                                                                                      '1452394495_expired',
                                                                                                                      undef,
                                                                                                                      1,
                                                                                                                      '',
                                                                                                                      1452437951,
                                                                                                                      ''
                                                                                                                    ],
                                                                                                    'mm_lang' => [
                                                                                                                   '0',
                                                                                                                   'zh_CN',
                                                                                                                   undef,
                                                                                                                   1,
                                                                                                                   '',
                                                                                                                   1452799407,
                                                                                                                   ''
                                                                                                                 ],
                                                                                                    'wxpluginkey' => [
                                                                                                                       '0',
                                                                                                                       '1452396606',
                                                                                                                       undef,
                                                                                                                       1,
                                                                                                                       '',
                                                                                                                       1452453645,
                                                                                                                       ''
                                                                                                                     ]
                                                                                                  }
                                                                                         }
                                                                        },
                                                           'file' => '/tmp/weixin_client_login.dat',
                                                           'hide_cookie2' => 1
                                                         }, 'HTTP::Cookies' ),
                                  'def_headers' => bless( {
                                                            'user-agent' => 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062'
                                                          }, 'HTTP::Headers' ),
                                  'proxy' => {},
                                  'max_size' => undef
                                }, 'LWP::UserAgent' ),
                 'is_stop' => 0,
                 '_send_message_queue' => bless( {
                                                   'callback_for_get_bak' => sub { "DUMMY" },
                                                   'callback_for_get' => $VAR1->{'_send_message_queue'}{'callback_for_get_bak'},
                                                   'queue' => []
                                                 }, 'Weixin::Message::Queue' ),
                 '_send_msg_interval' => 4,
                 'tmpdir' => '/tmp',
                 'plugins' => {},
                 'on_receive_msg' => undef,
                 '_data' => {
                              'friend' => [],
                              'user' => {},
                              'chatroom' => []
                            },
                 '_last_sync_time' => undef,
                 '_sync_running' => 0,
                 'asyn_ua' => bless( {
                                       'inactivity_timeout' => 300,
                                       'max_redirects' => 5,
                                       'agent' => 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062',
                                       'cookie_jar' => $VAR1->{'ua'}{'cookie_jar'},
                                       'request_timeout' => 300
                                     }, 'Weixin::UserAgent' ),
                 '_token' => {},
                 '_last_synccheck_time' => undef,
                 '_synccheck_interval' => 1,
                 'plugin_num' => 0,
                 'on_send_msg' => undef,
                 'debug' => 0,
                 '_watchers' => {},
                 '_synccheck_error_count' => 0,
                 '_intervals' => {},
                 '_receive_message_queue' => bless( {
                                                      'callback_for_get_bak' => sub { "DUMMY" },
                                                      'callback_for_get' => $VAR1->{'_receive_message_queue'}{'callback_for_get_bak'},
                                                      'queue' => []
                                                    }, 'Weixin::Message::Queue' ),
                 '_synccheck_running' => 0,
                 'ua_retry_times' => 5,
                 'on_run' => undef,
                 '_sync_interval' => 1,
                 'cookie_jar' => $VAR1->{'ua'}{'cookie_jar'},
                 'client_version' => '2.0'
               }, 'Weixin::Client' );
			   
			   
			   
			   
			   load 方法:
			   sub load {
    my $self = shift;
    my @module_name = @_;
    for my $module_name (@module_name){
        my $module_function = undef;
        if(substr($module_name,0,1) eq '+'){
            substr($module_name,0,1) = "";
            $module = $module_name;
        }
		
		第一个参数为对象:
		
$msg is ------
$VAR1 = bless( {
                 'ToUin' => 1284510822,
                 'MsgClass' => 'recv',
                 'CreateTime' => 1452758596,
                 'ToNickName' => '我',
                 'FromId' => '@2c33cb9d541cc8e0cd7c5ec018b56cda185aa0174f181f9d4e0136b286035a02',
                 'FromRemarkName' => undef,
                 'ToRemarkName' => undef,
                 'Type' => 'friend_message',
                 'MsgType' => 'text',
                 'FromNickName' => undef,
                 'FromUin' => undef,
                 'Content' => '你也147258369',
                 'TTL' => 5,
                 'ToId' => '@355da879478ba362e808fa906075a50823712e71e19f4a06ceba0ff4c56d238f',
                 'MsgId' => '800096966135914975'
               }, 'Weixin::Message::Recv' ); 
			   
			   
			   
			   
接收消息的类:
Weixin::Message::Recv 这个类 来自于:

Weixin::Message::Recv


jrhmpt01:/usr/local/share/perl5/Weixin# vim Message.pm 


sub _mk_ro_accessors {
    my $self = shift;  ### 第一个参数$self对象
    my $msg =shift;    ###
    my $msg_pkg = shift;
    no strict 'refs';
    for my $field (keys %$msg){
        *{__PACKAGE__ . "::${msg_pkg}::$field"} = sub{
            my $obj = shift;
            my $pkg = ref $obj; ##获得类名字
            die "the value of "$field" in $pkg is read-only
" if @_!=0;
            return $obj->{$field};
        };
    }
    return bless $msg,__PACKAGE__."::$msg_pkg";
}

这里的当前包是Weixin::Message




1.登录接口:
https://login.weixin.qq.com/cgi-bin/mmwebwx-bin/login?loginicon=true&uuid=4fbNLiMKhA==&tip=0&r=-1570013618&_=1453268946261

微信登录接口:
 my $api = 'https://login.weixin.qq.com/cgi-bin/mmwebwx-bin/login';

 _login.pm  方法:

package Weixin::Client;
use Weixin::Client::Private::_get_qrcode_uuid;
use Weixin::Client::Private::_get_qrcode_image;
use Weixin::Client::Private::_is_need_login;

1.1获取 uuid
_get_qrcode_uuid 方法:

https://login.weixin.qq.com/jslogin?appid=wx782c26e4c19acffb&redirect_uri=https%3A%2F%2Fwx.qq.com%2Fcgi-bin%2Fmmwebwx-bin%2Fwebwxnewloginpage&fun=new&lang=zh_CN&_=1453269277552

响应:
window.QRLogin.code = 200; window.QRLogin.uuid = "4dyqQzTV_g==";
			   
1.2  获取二维码

https://login.weixin.qq.com/qrcode/Ab3x-F9bqw==

返回2维码

1.3

https://wx.qq.com/?&lang=zh_CN

返回帮助信息




2 _init

https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxinit?r=-1571406762&lang=zh_CN&pass_ticket=gII3G4F43MHyoE3NXEpQGjnL%252FO4Kh9oT7L9qOJyNBqYicc6NB%252FJzkt%252F0GHZFtdRm

返回群好友信息

3._get_chatroom();

https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxbatchgetcontact?type=ex&r=1453270436253&lang=zh_CN&pass_ticket=gII3G4F43MHyoE3NXEpQGjnL%252FO4Kh9oT7L9qOJyNBqYicc6NB%252FJzkt%252F0GHZFtdRm

返回聊天群及成员

4._update_chatroom_member

https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxbatchgetcontact


5._update_friend
https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxgetcontact?lang=zh_CN&pass_ticket=gII3G4F43MHyoE3NXEpQGjnL%252FO4Kh9oT7L9qOJyNBqYicc6NB%252FJzkt%252F0GHZFtdRm&r=1453270435381&seq=0&skey=@crypt_597aeefd_52e341350b71c7dae5c660c45c50eb31

https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxgetcontact


获取好友信息

3.
收消息:
Client/Private/_sync.pm  接收消息  异步方式

sub _sync {
    my $self = shift;
    return if $self->{_synccheck_running} 
如果 $self->{_synccheck_running} 就直接return 什么也不干


my $callback = sub{
        $self->{_sync_running} = 0;
        my $response = shift;
        print $response->content(),"
" if $self->{debug};
        my $d = $self->json_decode($response->content());
        #return if $d->{BaseResponse}{Ret}!=0;
        $self->_parse_sync_data($d);

    };
 my $response = shift;
 
 https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxsync?sid=g+05x/2cwXtfEmV5&skey=@crypt_597aeefd_52e341350b71c7dae5c660c45c50eb31&lang=zh_CN
 
 
 接收消息:
 "AddMsgCount": 1,
"AddMsgList": [{
"MsgId": "8442920128804454773",
"FromUserName": "@78a7a53674f57a5a6070221eeb8fcf706a7aaf965ce2d205b1ec8d76597953c7",
"ToUserName": "@c2afb19006a336777800351b8f1a5142c5dde8dfd2f68b86b6cb196a76dddac1",
"MsgType": 1,
"Content": "kjk7787czcb<br/>",

4.发消息
_send_text_msg.pm

https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxsendmsg

https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxsendmsg?lang=zh_CN

post 发送消息:
{"BaseRequest":{"Uin":1284510822,"Sid":"g+05x/2cwXtfEmV5","Skey":"@crypt_597aeefd_52e341350b71c7dae5c660c45c50eb31"
,"DeviceID":"e200795958639167"},"Msg":{"Type":1,"Content":"xxxxxxx","FromUserName":"@c2afb19006a336777800351b8f1a5142c5dde8dfd2f68b86b6cb196a76dddac1"
,"ToUserName":"@@b866ff46bfe180745fea6a005cfeb9cad0ac90ae8e80acaca7f1553b6e5c3739","LocalID":"14532728152810691"
,"ClientMsgId":"14532728152810691"}}

原文地址:https://www.cnblogs.com/hzcya1995/p/13351078.html