设为首页收藏本站

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 179|回复: 0

使用PHP调用微信API做通知类应用

[复制链接]
发表于 2014-3-10 11:31:00 | 显示全部楼层 |阅读模式
相比于最常用的短信和邮件的通知方式,微信有着无可比拟的优势:快速、免费,特别适合用在报警通知类应用上。
但是微信并没有提供现成的api接口来给好友发送信息,公众平台也只能被动回复。那么如何才能主动发信息呢?答案就在微信网页版。
仔细观察微信网页版和服务器请求的记录,发现完全就是以oauth授权方式运行,完全不用考虑cookie。据此,分析请求记录,就能模拟网页版登录微信,从而实现主动向用户发送消息的功能。
以下是用到的请求:
1. 获取uuid,从返回的数据中,找到uuid

  1. <P>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</P>
复制代码

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

  1. <P>https://login.weixin.qq.com/qrcode/$this->uuid?t=webwx</P>
复制代码

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

  1. <P>https://login.weixin.qq.com/cgi-bin/mmwebwx-bin/login?uuid=$this->uuid&tip=1</P>
复制代码

4. 访问令牌url,获取sid。从返回的头信息中,分析出Uin,sid和uuid,保存起来
xxxxxx
5. 初始化微信,从返回的数据中读取UserName
  1. $data = array(
  2. "BaseRequest"=>array(
  3. "DeviceID" => 'e538770852445779',
  4. "Sid" => $this->sid,
  5. "Skey" => "",
  6. "Uin" => $this->Uin,
  7. )
  8. );
  9. $this->post_contents('https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxinit', $this->encode($data));
复制代码

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":[]}}');
复制代码


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方式,
  1. $data = array(
  2. "BaseRequest" => array(
  3. "Uin"=> $this->Uin,
  4. "Sid"=> $this->sid,
  5. "Skey"=> $this->Skey,
  6. "DeviceID"=> $this->DeviceID,
  7. ),
  8. "Msg" => array(
  9. "FromUserName" => $this->FromUserName,
  10. "ToUserName" => $name,
  11. "Type" => 1,
  12. "Content" => $content,
  13. "ClientMsgId" => $this->ClientMsgId,
  14. "LocalID" => $this->ClientMsgId,
  15. ),
  16. );
  17. $str = $this->encode($data);
  18. son_decode($this->post_contents('https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxsendmsg?sid=' . urlencode($this->sid) . '&r=' .$this->ClientMsgId, $str), true);
复制代码

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);



发送消息的经典过程为:
  • 初始化对象,设置Uin,sid,uuid
  • 更新Skey
  • 发送信息
但是微信网页版长时间不登录会失效,所以还需要写个任务去ping
  1. $data = '{"BaseRequest":{"Uin":'.$this->Uin.',"Sid":"'.$this->sid.'"},"SyncKey":{"Count":0,"List":[]}}';
  2. $ret = json_decode($this->post_contents('https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxsync?sid=' . urlencode($this->sid), $data, 30), true);
复制代码

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比较特殊,还需要用特别的函数来实现
  1. protected function encode($data){
  2. if(!is_array($data)){
  3. return $this->encode_str($data);
  4. }
  5. $ds = array();
  6. foreach($data as $k => $v){
  7. $ds [] = ""$k":" . $this->encode($v);
  8. }
  9. return '{' . join(',', $ds) . '}';
  10. }

  11. protected function encode_str($str){
  12. if(preg_match('|^\d+$|', $str)){
  13. return $str;
  14. }
  15. return '"' . str_replace('"', '"', iconv('GBK', 'UTF-8', $str)) . '"';
  16. }
复制代码

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('"', '\"', iconv('GBK', 'UTF-8', $str)) . '"';
}



您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|小黑屋|BC Morning Website ( Best Deal Inc. 001 )  

GMT-8, 2025-12-12 20:57 , Processed in 0.014812 second(s), 16 queries .

Supported by Best Deal Online X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表