Skip to content

Instantly share code, notes, and snippets.

@mornone
Forked from forecho/WxMockLogin.php
Created August 27, 2023 07:31
Show Gist options
  • Save mornone/c9ba97a6a8ef13e94730457963550f93 to your computer and use it in GitHub Desktop.
Save mornone/c9ba97a6a8ef13e94730457963550f93 to your computer and use it in GitHub Desktop.
微信公众平台模拟登录
<?php
/**
*微信公众平台模拟登录
*
*实现了公众平台上的操作<br>包括 实时消息获取 快速回复 用户管理 群发消息 获取用户基本信息
*@copyright Copyright info
*@author dml
*@version version
*@package defalut
*/
class WxMockLogin{
/**
*以键值对形式存储微信公众平台验证必需的cookie
*
*@var array
*/
public $cookie = array();
/**
*微信公众平台的必需字段字典,字典目的是过滤掉非微信平台必需的cookie
*
*@var array
*/
public $usedcookie = array('sig','cert','slave_sid','slave_user'); //登录需要用到的cookie
/**
*登录账号
*
*@var string
*/
protected $_username;
/**
*密码 MD5加密后
*
*@var string
*/
protected $_password;
/**
*验证码
*
*@var string
*/
protected $_verifyCode;
/**
*是否已经登录
*
*@var boolean
*/
protected $_islogin = false;
/**
*token 每次curl都要用到
*
*@var int|string
*/
public $_token;
/**
*crul资源指针
*
*@var resource
*/
protected $_curlRes;
/**
*微信登录url地址
*
*@var string
*/
protected $_urlLogin = 'https://mp.weixin.qq.com/cgi-bin/login?lang=zh_CN';
/**
*初始化
*
*@param string $username 用户名,非必需
*@param string $password 密码,非必需
*@param string $verifyCode 验证码,非必需
*@return void
*
*
*
*/
public function __construct($username='',$password='',$verifyCode='') {
$this->_username = $username;
$this->_loadCookie();
$this->_password = md5($password);
$this->_verifyCode = $verifyCode;
if($password != '' && $verifyCode != ''){
$this->login();
}
}
/**
*判断是否已经登录状态
*
*@return boolean 是否登录
*/
public function isLogin(){
return $this->_islogin;
}
/**
*获取地域信息
*
*@param int $id 地区编码(微信)
*@return string json格式字符串<br>
*<code>
* 返回格式:
*{"num":"34",
* "data":[
* {"id":"10012","name":"上海"}
* [,...]
* ]
*}
*</code>
*/
public function getregions($id){
$token = $this->_token;
$url = "https://mp.weixin.qq.com/cgi-bin/getregions?token=$token&id=$id&t=ajax-getregions&lang=zh_CN";
return $this->_curl($url);
}
/**
*根据关键字搜索消息列表
*
*@param string 搜索关键词
*@return string json格式字符串
*<code>
* 正确返回的格式:{"msg_item":[
* {"id":100001064,
* "type":1,
* "fakeid":"82487945",
* "nick_name":"Ero",
* "date_time":1382696544,
* "content":"我日",
* "source":"",
* "msg_status":4,
* "has_reply":0,
* "refuse_reason":""
* }
* [,...]
* ]
* }
* token或签名错误返回:'need login '+ 访问的url
*</code>
*/
public function searchmsgbykeyword($keyword = '日'){
$token = $this->_token;
$url = "https://mp.weixin.qq.com/cgi-bin/message?t=message/list&action=search&keyword=$keyword&count=20&token=$token&lang=zh_CN";
$result = $this->_curl($url);
if(preg_match('/登录超时/s',$result) == 1){
$this->_clearCookie();
$this->_islogin = false;
return 'need login '.$url;
}
//preg_match("/cgiData=\{(.*?)\};/s",$result,$match); //cigData
preg_match("/list : \((.*?)\).msg_item/",$result,$match);
return $match[1];
}
/**
*获取个人信息
*
*@param int $fakeid 用户fakeid
*@return string json格式字符串
*<code>
*{"base_resp":{"ret":0,"err_msg":"ok"},
* "contact_info":{ "fake_id":30312195,
* "nick_name":"李泽",
* "user_name":"llliiizzzeee",
* "signature":"专注社会化营销,玩微博的多聊聊:)",
* "city":"深圳",
* "province":"广东",
* "country":"中国",
* "gender":1,
* "remark_name":"",
* "group_id":0
* },
* "groups":{"groups":[
* {"id":0,"name":"未分组","cnt":6},
* {"id":1,"name":"黑名单","cnt":0},
* {"id":2,"name":"星标组","cnt":0},
* {"id":100,"name":"测试","cnt":1}
* ]
* }
*}
*</code>*/
public function getcontactinfo($fakeid){
$token = $this->_token;
$url = 'https://mp.weixin.qq.com/cgi-bin/getcontactinfo';
$data = array('lang'=>'zh_CN',
't'=>'ajax-getcontactinfo',
'token'=>$token,
'fakeid'=>$fakeid
);
$result = $this->_curl($url,$data);
return $result;
/*token:1426845324
lang:zh_CN
t:ajax-getcontactinfo
fakeid:2969320762*/
}
/**
*消息群发
*
*@param string $content 消息内容
*@param string $groupid 分组ID
*@param string $sex 性别 0:未知 1:男 2:女
*@param string $country 国家编码 通过$WxmockLogin->getregions(0)获取
*@param string $province 省份编码 通过$WxmockLogin->getregions()获取
*@param string $city 城市代码
*@param string $type 类型ID 1:文字 2:图片 3:语音 4:视频 10:图文消息 目前只支持文字
*@return string json格式字符串
*<code>
*
*
*</code>
*/
public function masssend($content, $groupid = '-1', $sex = '0', $country = '', $province = '', $city = '', $type = '1') {
$token = $this->_token;
$url = 'https://mp.weixin.qq.com/cgi-bin/masssend?t=ajax-response';
$data = array('type'=>$type,
'content'=>$content,
'error'=>'false',
'imgcode'=>'',
'needcomment'=>'0',
'groupid'=>$groupid,
'sex'=>$sex,//0:全部 1:男 2:女
'country'=>$country,
'city'=>$city,
'province'=>$province,
'synctxweibo'=>'0',
'synctxnews'=>'0',
'token'=>$token,
'ajax'=>'1'
);
/* return print_r($data,true);*/
$result = $this->_curl($url,$data);
return $result;
/* type:1
content:hi
error:false
imgcode:
needcomment:0
groupid:100
sex:0
country:
city:
province:
synctxweibo:0
synctxnews:0
token:1765302028
ajax:1*/
}
//5天消息烈性列表获取快速回复
public function singlesend($tofakeid,$content,$quickreplyid){
$token = $this->_token;
$url = "https://mp.weixin.qq.com/cgi-bin/singlesend";
$referer = "https://mp.weixin.qq.com/cgi-bin/message?t=message/list&token=$token&count=20&day=7";
$data = array('mask'=>'false',
'tofakeid'=>$tofakeid,
'imgcode'=>'',
'type'=>'1',
'content'=>$content,
'quickreplyid'=>$quickreplyid,
'token'=>$token,
'lang'=>'zh_CN',
't'=>'ajax-response'
);
$result = $this->_curl($url,$data,true,$referer);
if(preg_match('/登录超时/s',$result) == 1){
$this->_clearCookie();
$this->_islogin = false;
return 'need login '.$url.' '.print_r($data,true);
}
return $result;
/*mask:false
tofakeid:1638219980
imgcode:
type:1
content:你也好
quickreplyid:100001050
token:2123921385
lang:zh_CN
t:ajax-response*/
}
//主动针对某fake_id进行推送信息
public function sendMsgForFakeid($fake_id,$content){
$token = $this->_token;
$url = "https://mp.weixin.qq.com/cgi-bin/singlesend";
$referer="https://mp.weixin.qq.com/cgi-bin/singlesendpage?t=message/send&action=index&tofakeid=$fake_id&token=$token&lang=zh_CN";
$data = array('type'=>1,
'content'=>$content,
'tofakeid'=>$fake_id,
'imgcode'=>'',
'token'=>$token,
'lang'=>'zh_CN',
'random'=>1/rand(0,10000),
't'=>'ajax-response'
);
$result = $this->_curl($url,$data,true,$referer);
if(preg_match('/登录超时/s',$result) == 1){
$this->_clearCookie();
$this->_islogin = false;
return 'need login '.$url.' '.print_r($data,true);
}
return $result;
}
//改变分组
/*
contacttype 表示转去的目的组别
*/
public function changeGroup($fakeid,$contacttype){
$token = $this->_token;
$url = "https://mp.weixin.qq.com/cgi-bin/modifycontacts";
$referer = "https://mp.weixin.qq.com/cgi-bin/contactmanage?t=user/index&pagesize=10&pageidx=0&type=0&groupid=0&token=1954377267&lang=zh_CN";
$data = array('contacttype'=>$contacttype,'tofakeidlist'=>$fakeid,'token'=>$token,'lang'=>'zh_CN','random'=>1/rand(0,10000),'f'=>'json','ajax'=>1,'action'=>'modifycontacts','t'=>'ajax-putinto-group');
$result = $this->_curl($url,$data,true,$referer);
if(preg_match('/登录超时/s',$result) == 1){
$this->_clearCookie();
$this->_islogin = false;
return 'need login '.$url.' '.print_r($data,true);
}
return $result;
}
//修改备注
public function changeRemark($fakeid,$newRemark){
$token = $this->_token;
$url = "https://mp.weixin.qq.com/cgi-bin/modifycontacts";
$referer = "https://mp.weixin.qq.com/cgi-bin/contactmanage?t=user/index&pagesize=10&pageidx=0&type=0&groupid=1&token=$token&lang=zh_CN";
$data = array('remark'=>$newRemark,'tofakeuin'=>$fakeid,'token'=>$token,'lang'=>'zh_CN','random'=>1/rand(0,10000),'f'=>'json','ajax'=>1,'t'=>'ajax-response','action'=>'setremark');
$result = $this->_curl($url,$data,true,$referer);
if(preg_match('/登录超时/s',$result) == 1){
$this->_clearCookie();
$this->_islogin = false;
return 'need login '.$url.' '.print_r($data,true);
}
return $result;
}
//用户5天内消息获取
public function get5dayMsg($count=20,$day=7){
$token = $this->_token;
$url = "https://mp.weixin.qq.com/cgi-bin/message?t=message/list&count=$count&day=$day&token=$token&lang=zh_CN";
$result = $this->_curl($url);
if(preg_match('/登录超时/s',$result) == 1){
$this->_clearCookie();
$this->_islogin = false;
return 'need login '.$url;
}
//preg_match("/cgiData=\{(.*?)\};/s",$result,$match); //cigData
preg_match("/list : \((.*?)\).msg_item/",$result,$match);
return $match[1];
}
//获取用户(最近*个),最大1000 ?
public function getUserInfo($pagesize=10,$pageidx=0,$type=0,$groupid=0){
$token = $this->_token;
$url = "https://mp.weixin.qq.com/cgi-bin/contactmanage?t=user/index&pagesize=$pagesize&pageidx=$pageidx&type=$type&groupid=$groupid&token=$token&lang=zh_CN";
$result = $this->_curl($url);
if(preg_match('/登录超时/s',$result) == 1){
$this->_clearCookie();
$this->_islogin = false;
return 'need login '.$url;
}
//preg_match("/cgiData=\{(.*?)\};/s",$result,$match); //cigData
preg_match("/friendsList : \(\{(.*?)\}\).contacts/",$result,$match);
preg_match("/groupsList : \(\{(.*?)\}\).groups/",$result,$groups);
return '{'.$match[1].','.$groups[1].'}';
}
//过滤登录需要的cookie
protected function _loadCookie(){
foreach($_COOKIE as $key => $value){
if(in_array($key,$this->usedcookie)){
$this->cookie[$key] = $value;
}
if($key == 'token'){
$this->_token = $value;
}
}
}
//获取登录状态cookie
public function login() {
$postData = array('username'=>$this->_username,
'pwd'=>$this->_password,
'imgcode'=>$this->_verifyCode,
'f'=>'json'
);
$rtstring = $this->_curl($this->_urlLogin,$postData,true);
//cookie
preg_match_all("/Set-Cookie: ([\w=]*);/",$rtstring,$matches);
$this->_cookiepush($matches[1]);
//token
preg_match_all("/\r\n\r\n(.*)/s",$rtstring,$bodys);
$resArr = json_decode($bodys[1][0],true);
//正确返回结果的msg示例:cgi-bin/home?t=home/index&lang=zh_CN&token=2123921385
preg_match("/token=(\d*)/",$resArr['ErrMsg'],$token);
print_r($token);
$this->_cookiepush($token[0]);
$this->_token = $token[1];
$this->_islogin = true;
}
//$cookiestr 格式 sig=cookievalvalvalval 或者 array('sig=cookievalvalval','sig1=cookievalvalval'...)
protected function _cookiepush($cookies) {
if(is_array($cookies)) {
foreach($cookies as $cookie){
$kpos = strpos($cookie,'=');
if($kpos !== false) {
$key = substr($cookie,0,$kpos);
$value = substr($cookie,$kpos+1);
$this->cookie[$key] = $value;
setcookie($key,$value);
}
}
return true;
} elseif(is_string($cookies)) {
$kpos = strpos($cookies,'=');
if($kpos !== false) {
$key = substr($cookies,0,$kpos);
$value = substr($cookies,$kpos+1);
$this->cookie[$key] = $value;
setcookie($key,$value);
}
return true;
} else {
return false;
}
}
//清除cookie
protected function _clearCookie(){
foreach($this->usedcookie as $value){
setcookie ($value, "", time() - 3600);
}
}
//解析$_cookie生成可发送的cookie字符串
protected function _getCookieStr(){
$cookiestr = '';
foreach ($this->cookie as $key => $value) {
$cookiestr .= $key.'='.$value.'; ';
}
return $cookiestr;
}
//获取验证码,保存cookie.sig
public function getVerifyCode() {
$username = $this->_username;
$rtstring = $this->_curl("https://mp.weixin.qq.com/cgi-bin/verifycode?username=$username&r=".time(),'',true);
preg_match_all("/Set-Cookie: ([\w=]*)/",$rtstring,$matches);
$this->_cookiepush($matches[1][0]);
header('Content-Type:image/jpeg');
$st = curl_getinfo($this->_curlRes,CURLINFO_HEADER_SIZE);
echo substr($rtstring,$st);
//preg_match_all("/\r\n\r\n(.*)/s",$rtstring,$matches1);
//print_r($matches1);
//echo $matches1[1][0];
}
//curl操作,$url:请求地址 $data:post数据(数组或字符串) $return_herder:是否返回http响应头文件
protected function _curl($url,$data='',$return_header=false,$referer='https://mp.weixin.qq.com/') {
$headers_org = array('Origin:https://mp.weixin.qq.com','Host:mp.weixin.qq.com','Cookie:'.$this->_getCookieStr());
$user_agent = 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.76 Safari/537.36';
if($this->_curlRes){
curl_close($this->_curlRes);
}
$this->_curlRes = curl_init($url);
$ch = $this->_curlRes;
curl_setopt($ch,CURLOPT_HTTPHEADER, $headers_org); //设置请求头
curl_setopt($ch,CURLOPT_USERAGENT, $user_agent);
curl_setopt($ch, CURLOPT_REFERER, $referer);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 返回字符串,而非直接输出
curl_setopt($ch, CURLOPT_HEADER, $return_header); // 返回header部分
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 120); // 设置socket连接超时时间
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); //ssl
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); //ssl
//post数据
if (is_string($data) && $data !=''){
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
} else if (is_array($data)) {
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
}
set_time_limit(120); // 设置自己服务器超时时间
return curl_exec($ch);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment