使用PHP调用微信API,使用微信做通知类应用的方法

相比于最常用的短信和邮件的通知方式,微信有着无可比拟的优势:快速、免费,特别适合用在报警通知类应用上。

但是微信并没有提供现成的api接口来给好友发送信息,公众平台也只能被动回复。那么如何才能主动发信息呢?答案就在微信网页版。

仔细观察微信网页版和服务器请求的记录,发现完全就是以oauth授权方式运行,完全不用考虑cookie。据此,分析请求记录,就能模拟网页版登录微信,从而实现主动向用户发送消息的功能。

以下是用到的请求:

1. 获取uuid,从返回的数据中,找到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

2. 获取二维码图片,然后使用微信扫描

https://login.weixin.qq.com/qrcode/$this->uuid?t=webwx

3. 获取令牌,轮询,直到从返回的数据中找到window.redirect_uri=xxxx的代码,xxx就是令牌url

https://login.weixin.qq.com/cgi-bin/mmwebwx-bin/login?uuid=$this->uuid&tip=1

4. 访问令牌url,获取sid。从返回的头信息中,分析出Uin,sid和uuid,保存起来

xxxxxx

5. 初始化微信,从返回的数据中读取UserName

1
2
3
4
5
6
7
8
9
$data = array (
     "BaseRequest" => array (
         "DeviceID"  => 'e538770852445779' ,
         "Sid"   => $this ->sid,
         "Skey"  => "" ,
         "Uin"   => $this ->Uin,
     )
);
$this ->post_contents( 'https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxinit' , $this ->encode( $data ));

6. 获取Skey

1
$this ->post_contents( 'https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxsync?sid=' . urlencode( $this ->sid), '{"BaseRequest":{"Uin":' . $this ->Uin. ',"Sid":"' . $this ->sid. '"},"SyncKey":{"Count":0,"List":[]}}' );

7. 发送消息,POST方式,

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
$data = array (
     "BaseRequest" => array (
         "Uin" => $this ->Uin,
         "Sid" => $this ->sid,
         "Skey" => $this ->Skey,
         "DeviceID" => $this ->DeviceID,
     ),
     "Msg" => array (
         "FromUserName" => $this ->FromUserName,
         "ToUserName" => $name ,
         "Type" => 1,
         "Content" => $content ,
         "ClientMsgId" => $this ->ClientMsgId,
         "LocalID" => $this ->ClientMsgId,
     ),
);
$str = $this ->encode( $data );
son_decode( $this ->post_contents( 'https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxsendmsg?sid=' . urlencode( $this ->sid) . '&r=' . $this ->ClientMsgId, $str ), true);

发送消息的经典过程为:

  1. 初始化对象,设置Uin,sid,uuid
  2. 更新Skey
  3. 发送信息

但是微信网页版长时间不登录会失效,所以还需要写个任务去ping

1
2
$data = '{"BaseRequest":{"Uin":' . $this ->Uin. ',"Sid":"' . $this ->sid. '"},"SyncKey":{"Count":0,"List":[]}}' ;
         $ret = json_decode( $this ->post_contents( 'https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxsync?sid=' . urlencode( $this ->sid), $data , 30), true);

微信的数据都是以json格式传输的,但是他这个json比较特殊,还需要用特别的函数来实现

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
protected function encode( $data ){
     if (! is_array ( $data )){
         return $this ->encode_str( $data );
     }
     $ds = array ();
     foreach ( $data as $k => $v ){
         $ds [] = "\"$k\":" . $this ->encode( $v );
     }
     return '{' . join( ',' , $ds ) . '}' ;
}
 
protected function encode_str( $str ){
     if (preg_match( '|^\d+$|' , $str )){
         return $str ;
     }
     return '"' . str_replace ( '"' , '\"' , i

你可能感兴趣的:(微信,通知类应用)