Commit d55e635b by HanSon

修改类名与格式

1 parent 34f1e2ce
......@@ -8,10 +8,10 @@
require_once __DIR__ . './../vendor/autoload.php';
use Hanson\Vbot\Foundation\Robot;
use Hanson\Vbot\Foundation\Vbot;
use Hanson\Vbot\Message\Entity\Text;
$robot = new Robot([
$robot = new Vbot([
'tmp' => __DIR__ . '/./../tmp/',
]);
......@@ -19,12 +19,14 @@ $flag = false;
$robot->server->setCustomerHandler(function() use (&$flag){
$contact = contact()->getUsernameById('matts8023');
if(!$flag){
Text::send('custom', contact()->getUsernameById('L907159127'));
Text::send($contact, '来轰炸吧');
$flag = true;
}
Text::send('测试' . \Carbon\Carbon::now()->toDateTimeString(), contact()->getUsernameById('L907159127'));
Text::send($contact, '测试' . \Carbon\Carbon::now()->toDateTimeString());
});
......
......@@ -8,10 +8,10 @@
require_once __DIR__ . './../vendor/autoload.php';
use Hanson\Vbot\Foundation\Robot;
use Hanson\Vbot\Foundation\Vbot;
use Hanson\Vbot\Message\Message;
$robot = new Robot([
$robot = new Vbot([
'tmp' => __DIR__ . '/./../tmp/',
'debug' => true
]);
......
......@@ -8,10 +8,10 @@
require_once __DIR__ . './../vendor/autoload.php';
use Hanson\Vbot\Foundation\Robot;
use Hanson\Vbot\Foundation\Vbot;
use Hanson\Vbot\Message\Message;
$robot = new Robot([
$robot = new Vbot([
'tmp' => __DIR__ . '/./../tmp/',
]);
......
......@@ -8,10 +8,10 @@
require_once __DIR__ . './../vendor/autoload.php';
use Hanson\Vbot\Foundation\Robot;
use Hanson\Vbot\Foundation\Vbot;
use Hanson\Vbot\Message\Entity\Text;
$robot = new Robot([
$robot = new Vbot([
'tmp' => __DIR__ . '/./../tmp/',
'debug' => true
]);
......
......@@ -8,10 +8,10 @@
require_once __DIR__ . './../vendor/autoload.php';
use Hanson\Vbot\Foundation\Robot;
use Hanson\Vbot\Foundation\Vbot;
use Hanson\Vbot\Message\Message;
$robot = new Robot([
$robot = new Vbot([
'tmp' => __DIR__ . '/./../tmp/',
'debug' => true
]);
......
......@@ -8,11 +8,11 @@
require_once __DIR__ . './../vendor/autoload.php';
use Hanson\Vbot\Foundation\Robot;
use Hanson\Vbot\Foundation\Vbot;
use Hanson\Vbot\Message\Message;
use Hanson\Vbot\Support\Console;
$robot = new Robot([
$robot = new Vbot([
'tmp' => __DIR__ . '/./../tmp/',
]);
......
......@@ -8,12 +8,12 @@
require_once __DIR__ . './../vendor/autoload.php';
use Hanson\Vbot\Foundation\Robot;
use Hanson\Vbot\Foundation\Vbot;
use Hanson\Vbot\Message\Message;
use Hanson\Vbot\Message\Image;
use Hanson\Vbot\Support\Console;
$robot = new Robot([
$robot = new Vbot([
'tmp' => __DIR__ . '/./../tmp/',
]);
......
......@@ -8,7 +8,7 @@
require_once __DIR__ . './../vendor/autoload.php';
use Hanson\Vbot\Foundation\Robot;
use Hanson\Vbot\Foundation\Vbot;
use Hanson\Vbot\Message\Entity\Message;
use Hanson\Vbot\Message\Entity\Image;
use Hanson\Vbot\Message\Entity\Text;
......@@ -25,7 +25,7 @@ use Hanson\Vbot\Message\Entity\Touch;
use Hanson\Vbot\Message\Entity\RequestFriend;
$path = __DIR__ . '/./../tmp/';
$robot = new Robot([
$robot = new Vbot([
'tmp' => $path,
'debug' => true
]);
......@@ -45,22 +45,22 @@ $robot->server->setMessageHandler(function ($message) use ($path) {
// }
// 文字信息
// if ($message instanceof Text) {
// // 联系人自动回复
// if ($message->fromType === 'Contact') {
//
// return http()->post('http://www.tuling123.com/openapi/api', [
// 'key' => '1dce02aef026258eff69635a06b0ab7d',
// 'info' => $message->content
// ], true)['text'];
// // 群组@我回复
// } elseif ($message->fromType === 'Group' && $message->isAt) {
// return http()->post('http://www.tuling123.com/openapi/api', [
// 'key' => '1dce02aef026258eff69635a06b0ab7d',
// 'info' => $message->content
// ], true)['text'];
// }
// }
if ($message instanceof Text) {
// 联系人自动回复
if ($message->fromType === 'Contact') {
return http()->post('http://www.tuling123.com/openapi/api', [
'key' => '1dce02aef026258eff69635a06b0ab7d',
'info' => $message->content
], true)['text'];
// 群组@我回复
} elseif ($message->fromType === 'Group' && $message->isAt) {
return http()->post('http://www.tuling123.com/openapi/api', [
'key' => '1dce02aef026258eff69635a06b0ab7d',
'info' => $message->content
], true)['text'];
}
}
// 图片信息 返回接收到的图片
// if ($message instanceof Image) {
......@@ -151,11 +151,11 @@ $robot->server->setMessageHandler(function ($message) use ($path) {
// return $reply;
// }
//
// // 手机点击聊天事件
// if($message instanceof Touch){
// print_r($message);
// Text::send($message->to['UserName'], "我点击了此群");
// }
// 手机点击聊天事件
if($message instanceof Touch){
print_r($message);
Text::send($message->to['UserName'], "我点击了此群");
}
return false;
......
......@@ -8,11 +8,11 @@
require_once __DIR__ . './../vendor/autoload.php';
use Hanson\Vbot\Foundation\Robot;
use Hanson\Vbot\Foundation\Vbot;
use Hanson\Vbot\Message\Message;
use Hanson\Vbot\Support\Console;
$robot = new Robot([
$robot = new Vbot([
'tmp' => __DIR__ . '/./../tmp/',
]);
......
......@@ -8,7 +8,7 @@
require_once __DIR__ . './../vendor/autoload.php';
use Hanson\Vbot\Foundation\Robot;
use Hanson\Vbot\Foundation\Vbot;
use Hanson\Vbot\Message\Message;
use Hanson\Vbot\Message\Image;
use Hanson\Vbot\Message\Entity\Text;
......@@ -16,7 +16,7 @@ use Hanson\Vbot\Message\Emoticon;
use Hanson\Vbot\Message\Video;
$path = __DIR__ . '/./../tmp/';
$robot = new Robot([
$robot = new Vbot([
'tmp' => $path,
'debug' => true
]);
......
......@@ -8,10 +8,10 @@
require_once __DIR__ . './../vendor/autoload.php';
use Hanson\Vbot\Foundation\Robot;
use Hanson\Vbot\Foundation\Vbot;
use Hanson\Vbot\Message\Message;
$robot = new Robot([
$robot = new Vbot([
'tmp' => __DIR__ . '/./../tmp/',
]);
......
......@@ -9,22 +9,10 @@
namespace Hanson\Vbot\Collections;
use Illuminate\Support\Collection;
class Account
{
/**
* @var Group
*/
static $group;
/**
* @var Contact
*/
static $contact;
/**
* @var Account
*/
static $instance = null;
......@@ -36,10 +24,8 @@ class Account
*/
public static function getInstance()
{
if(static::$instance === null){
if (static::$instance === null) {
static::$instance = new Account();
static::$group = group();
static::$contact = contact();
}
return static::$instance;
......@@ -53,11 +39,11 @@ class Account
*/
public function getAccount($username)
{
$account = static::$group->get($username, null);
$account = group()->get($username, null);
$account = $account ? : static::$contact->get($username, null);
$account = $account ?: contact()->get($username, null);
return $account ? : member()->get($username, []);
return $account ?: member()->get($username, []);
}
}
\ No newline at end of file
......@@ -34,19 +34,6 @@ class Contact extends Collection
}
/**
* 根据username获取联系人
*
* @param $id
* @return array
*/
public function getContactByUsername($id)
{
$contact = $this->get($id);
return $contact ?? [];
}
/**
* 根据微信号获取联系人
*
* @param $id
......@@ -54,13 +41,11 @@ class Contact extends Collection
*/
public function getContactById($id)
{
$contact = $this->filter(function($item, $key) use ($id){
return $this->filter(function($item, $key) use ($id){
if($item['Alias'] === $id){
return true;
}
})->first();
return $contact;
}
/**
......@@ -71,13 +56,11 @@ class Contact extends Collection
*/
public function getUsernameById($id)
{
$contact = $this->search(function($item, $key) use ($id){
return $this->search(function($item, $key) use ($id){
if($item['Alias'] === $id){
return true;
}
});
return $contact;
}
}
\ No newline at end of file
......@@ -51,7 +51,7 @@ class ContactFactory
if(official()->isOfficial($contact['VerifyFlag'])){ #公众号
Official::getInstance()->put($contact['UserName'], $contact);
}elseif (in_array($contact['UserName'], static::SPECIAL_USERS)){ # 特殊账户
SpecialAccount::getInstance()->put($contact['UserName'], $contact);
Special::getInstance()->put($contact['UserName'], $contact);
}elseif (strstr($contact['UserName'], '@@') !== false){ # 群聊
group()->put($contact['UserName'], $contact);
}else{
......@@ -64,8 +64,8 @@ class ContactFactory
file_put_contents(server()->config['tmp'] . 'contact.json', json_encode(contact()->all()));
file_put_contents(server()->config['tmp'] . 'member.json', json_encode(member()->all()));
file_put_contents(server()->config['tmp'] . 'group.json', json_encode(group()->all()));
file_put_contents(server()->config['tmp'] . 'OfficialAccount.json', json_encode(Official::getInstance()->all()));
file_put_contents(server()->config['tmp'] . 'SpecialAccount.json', json_encode(SpecialAccount::getInstance()->all()));
file_put_contents(server()->config['tmp'] . 'official.json', json_encode(Official::getInstance()->all()));
file_put_contents(server()->config['tmp'] . 'special.json', json_encode(Special::getInstance()->all()));
}
}
......
......@@ -46,7 +46,6 @@ class Group extends Collection
*
* @param $name
* @param bool $blur
* @param bool $onlyUsername
* @return static
*/
public function getGroupsByNickname($name, $blur = false)
......
......@@ -33,17 +33,4 @@ class Member extends Collection
return static::$instance;
}
/**
* 根据username获取群成员
*
* @param $id
* @return array
*/
public function getMemberByUsername($id)
{
$member = $this->get($id);
return $member ?? null;
}
}
\ No newline at end of file
......@@ -11,7 +11,7 @@ namespace Hanson\Vbot\Collections;
use Illuminate\Support\Collection;
class SpecialAccount extends Collection
class Special extends Collection
{
static $instance = null;
......@@ -19,12 +19,12 @@ class SpecialAccount extends Collection
/**
* create a single instance
*
* @return SpecialAccount
* @return Special
*/
public static function getInstance()
{
if(static::$instance === null){
static::$instance = new SpecialAccount();
static::$instance = new Special();
}
return static::$instance;
......
......@@ -12,6 +12,7 @@ namespace Hanson\Vbot\Core;
use Hanson\Vbot\Message\Entity\Emoticon;
use Hanson\Vbot\Message\Entity\Image;
use Hanson\Vbot\Message\Entity\Location;
use Hanson\Vbot\Message\Entity\Message;
use Hanson\Vbot\Message\Entity\Recall;
use Hanson\Vbot\Message\Entity\Recommend;
use Hanson\Vbot\Message\Entity\RedPacket;
......@@ -22,7 +23,6 @@ use Hanson\Vbot\Message\Entity\Touch;
use Hanson\Vbot\Message\Entity\Transfer;
use Hanson\Vbot\Message\Entity\Video;
use Hanson\Vbot\Message\Entity\Voice;
use Hanson\Vbot\Support\Console;
class MessageFactory
{
......@@ -36,7 +36,7 @@ class MessageFactory
/**
* 处理消息类型
* @param $msg
* @return Touch
* @return Message
*/
private function handleMessageByType($msg)
{
......@@ -65,9 +65,9 @@ class MessageFactory
// else if(str_contains($msg['Content'], '好友') || str_contains($msg['Content'], 'friend')){
// print_r($msg);
// }
else{
print_r($msg);
}
// else{
// print_r($msg);
// }
break;
case 49:
if($msg['Status'] == 3 && $msg['FileName'] === '微信转账'){
......
......@@ -125,6 +125,7 @@ class MessageHandler
$content = $this->messageFactory->make($selector, $msg);
if($content){
$this->addToMessageCollection($content);
if($this->handler){
$reply = call_user_func_array($this->handler, [$content]);
if($reply){
if($reply instanceof Image){
......@@ -141,6 +142,7 @@ class MessageHandler
}
}
}
}
/**
* @param $message Message
......
......@@ -9,8 +9,6 @@
namespace Hanson\Vbot\Core;
use Hanson\Vbot\Collections\Contact;
class Myself
{
......@@ -26,7 +24,7 @@ class Myself
public static function getInstance()
{
if(!static::$instance){
if (!static::$instance) {
static::$instance = new Myself();
}
......@@ -39,7 +37,7 @@ class Myself
$this->nickname = $user['NickName'];
$this->username = $user['UserName'];
$this->sex = $user['Sex'];
$this->uin= $user['Uin'];
$this->uin = $user['Uin'];
}
}
\ No newline at end of file
......@@ -15,7 +15,6 @@ use Hanson\Vbot\Collections\Account;
use Hanson\Vbot\Collections\ContactFactory;
use Hanson\Vbot\Collections\Group;
use Hanson\Vbot\Support\Console;
use Hanson\Vbot\Support\ObjectAble;
use Symfony\Component\DomCrawler\Crawler;
class Server
......@@ -84,12 +83,12 @@ class Server
{
$this->prepare();
$this->init();
Console::log('[INFO] init success!');
Console::log('[INFO] 初始化成功');
$this->statusNotify();
Console::log('[INFO] begin to init contacts');
Console::log('[INFO] 开始初始化联系人');
$this->initContact();
Console::log('[INFO] init contacts success!');
Console::log('[INFO] 初始化联系人成功');
MessageHandler::getInstance()->listen();
}
......@@ -98,11 +97,11 @@ class Server
{
$this->getUuid();
$this->generateQrCode();
Console::log('[INFO] please scan qrcode to login');
Console::log('[INFO] 请扫描二维码登录');
$this->waitForLogin();
$this->login();
Console::log('[INFO] login success!');
Console::log('[INFO] 登录成功');
}
/**
......@@ -123,7 +122,7 @@ class Server
preg_match('/window.QRLogin.code = (\d+); window.QRLogin.uuid = \"(\S+?)\"/', $content, $matches);
if(!$matches){
throw new \Exception('fail to get uuid');
throw new \Exception('[ERROR] 获取UUID失败');
}
$this->uuid = $matches[2];
......@@ -167,7 +166,7 @@ class Server
$code = $matches[1];
switch($code){
case '201':
Console::log('[INFO] please confirm to login');
Console::log('[INFO] 请点击确认登录微信');
$tip = 0;
break;
case '200':
......@@ -178,7 +177,6 @@ class Server
'wx2.qq.com' => ['file.wx2.qq.com', 'webpush.wx2.qq.com'],
'wx.qq.com' => ['file.wx.qq.com', 'webpush.wx.qq.com'],
'wx8.qq.com' => ['file.wx8.qq.com', 'webpush.wx8.qq.com'],
// 'qq.com' => ['file.wx.qq.com', 'webpush.wx.qq.com'],
'web2.wechat.com' => ['file.web2.wechat.com', 'webpushweb2.wechat.com'],
'wechat.com' => ['file.web.wechat.com', 'webpushweb.web.wechat.com'],
];
......@@ -195,13 +193,13 @@ class Server
Console::log('url is:'. $this->baseUri);
return;
case '408':
Console::log('[ERROR] login timeout. please try 1 second later.');
Console::log('[ERROR] 登录超时,请重试');
$tip = 1;
$retryTime -= 1;
sleep(1);
break;
default:
Console::log("[ERROR] login fail. exception code:$code . please try 1 second later.");
Console::log("[ERROR] 登录失败,错误码:$code 。请重试");
$tip = 1;
$retryTime -= 1;
sleep(1);
......@@ -209,7 +207,7 @@ class Server
}
}
throw new \Exception('[ERROR] login fail!');
die('[ERROR] 登录超时,退出应用');
}
/**
......@@ -229,7 +227,7 @@ class Server
$this->passTicket = $data['pass_ticket'];
if(in_array('', [$this->skey, $this->sid, $this->uin, $this->passTicket])){
throw new \Exception('[ERROR] login fail!');
throw new \Exception('[ERROR] 登录失败');
}
$this->deviceId = 'e' .substr(mt_rand().mt_rand(), 1, 15);
......@@ -263,7 +261,7 @@ class Server
// print_r($this->baseRequest);
Console::log('init URL:'. $url);
throw new \Exception('[ERROR] init fail!');
throw new \Exception('[ERROR] 初始化失败');
}
}
......
......@@ -19,7 +19,7 @@ use Pimple\Container;
* @package Hanson\Vbot\Foundation
* @property Server $server
*/
class Robot extends Container
class Vbot extends Container
{
/**
......
......@@ -13,10 +13,9 @@ use Carbon\Carbon;
use Hanson\Vbot\Core\Server;
use Hanson\Vbot\Collections\Contact;
use Hanson\Vbot\Collections\Official;
use Hanson\Vbot\Collections\SpecialAccount;
use Hanson\Vbot\Collections\Special;
use Hanson\Vbot\Support\FileManager;
use Hanson\Vbot\Support\Console;
use Hanson\Vbot\Support\ObjectAble;
class Message
{
......@@ -81,11 +80,11 @@ class Message
$this->fromType = 'Self';
} elseif (substr($this->msg['FromUserName'], 0, 2) === '@@') { # group
$this->fromType = 'Group';
} elseif (contact()->getContactByUsername($this->msg['FromUserName'])) {
} elseif (contact()->get($this->msg['FromUserName'])) {
$this->fromType = 'Contact';
} elseif (Official::getInstance()->get($this->msg['FromUserName'])) {
$this->fromType = 'Official';
} elseif (SpecialAccount::getInstance()->get($this->msg['FromUserName'], false)) {
} elseif (Special::getInstance()->get($this->msg['FromUserName'], false)) {
$this->fromType = 'Special';
} else {
$this->fromType = 'Unknown';
......
<?php
/**
* Created by PhpStorm.
* User: HanSon
* Date: 2016/12/7
* Time: 16:12
*/
namespace Hanson\Vbot;
use Endroid\QrCode\QrCode;
use GuzzleHttp\Client;
use Masterminds\HTML5\Exception;
use Symfony\Component\DomCrawler\Crawler;
class Robot
{
private $client;
public $tmpPath;
public $debug;
private $uuid;
private $baseUri = 'https://wx2.qq.com/cgi-bin/mmwebwx-bin';
private $baseHost = 'wx2.qq.com';
private $redirectUri;
private $skey;
private $sid;
private $uin;
private $passTicket;
private $deviceId;
private $baseRequest;
private $syncKey;
private $myAccount;
private $syncKeyStr;
private $memberList;
private $contactList;
private $publicList;
private $specialList;
private $groupList;
private $accountInfo = [
'groupMember' => [],
'normalMember' => []
];
private $groupMembers;
private $encryChatRoomId;
private $syncHost;
public function __construct(Array $option = [])
{
$this->client = new Client([
'cookies' => true
]);
$this->handleOption($option);
}
/**
* 处理option
*
* @param $option
*/
private function handleOption($option)
{
$this->tmpPath = $option['tmp'] ?? sys_get_temp_dir();
$this->debug = $option['debug'] ?? true;
}
public function run()
{
$this->getUuid();
$this->generateQrCode();
$this->log('[INFO] 请用微信扫码');
if($this->waitForLogin() !== 200){
die('[ERROR] 微信登录失败');
}
if(!$this->login()){
die('[ERROR] 登录失败');
}
$this->log('[INFO] 登录成功');
if(!$this->init()){
die('[INFO] 微信初始化失败');
}
$this->log('[INFO] 微信初始化成功');
$this->statusNotify();
$this->getContact();
$this->log('[INFO] 获取 ' . count($this->contactList) . ' 个联系人');
$this->log('[INFO] 开始获取信息');
$this->processMsg();
}
/**
* 获取UUID
* @throws \Exception
*/
public function getUuid()
{
$content = $this->client->get('https://login.weixin.qq.com/jslogin', [
'query' => [
'appid' => 'wx782c26e4c19acffb',
'fun' => 'new',
'lang' => 'zh_CN',
'_' => time() * 1000 . random_int(1, 999)
]
])->getBody()->getContents();
preg_match('/window.QRLogin.code = (\d+); window.QRLogin.uuid = \"(\S+?)\"/', $content, $matches);
if(!$matches){
throw new \Exception('获取UUID失败');
}
$this->uuid = $matches[2];
}
/**
* 生成登录二维码
*/
public function generateQrCode()
{
$url = 'https://login.weixin.qq.com/l/' . $this->uuid;
$qrCode = new QrCode($url);
$file = $this->tmpPath . 'login_qr_code.png';
$qrCode->save($file);
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
system($file);
}
}
/**
* 等待登录
*
* @return int
*/
public function waitForLogin(): int
{
$urlTemplate = 'https://login.weixin.qq.com/cgi-bin/mmwebwx-bin/login?tip=%s&uuid=%s&_=%s';
$retryTime = 10;
$tip = 1;
$code = 0;
while($retryTime > 0){
$url = sprintf($urlTemplate, $tip, $this->uuid, time());
$content = $this->client->get($url, ['query' => []])->getBody()->getContents();
preg_match('/window.code=(\d+);/', $content, $matches);
$code = $matches[1];
switch($code){
case '201':
$this->log('[INFO] 请点击确认进行登录');
$tip = 0;
break;
case '200':
preg_match('/window.redirect_uri="(\S+?)";/', $content, $matches);
$this->redirectUri = $matches[1] . '&fun=new';
return $code;
case '408':
$this->log('[ERROR] 微信登录超时。将在 1 秒后重试');
$tip = 1;
$retryTime -= 1;
sleep(1);
break;
default:
$this->log("[ERROR] 微信登录异常。异常码:$code 。1 秒后重试");
$tip = 1;
$retryTime -= 1;
sleep(1);
break;
}
}
return $code;
}
/**
* 登录
*
* @return bool
*/
public function login()
{
$content = $this->client->get($this->redirectUri)->getBody()->getContents();
$crawler = new Crawler($content);
$this->skey = $crawler->filter('error skey')->text();
$this->sid = $crawler->filter('error wxsid')->text();
$this->uin = $crawler->filter('error wxuin')->text();
$this->passTicket = $crawler->filter('error pass_ticket')->text();
if(in_array('', [$this->skey, $this->sid, $this->uin, $this->passTicket])){
return false;
}
$this->deviceId = 'e' . strval(random_int(100000000000000, 999999999999999));
$this->baseRequest = [
'Uin' => $this->uin,
'Sid' => $this->sid,
'Skey' => $this->skey,
'DeviceID' => $this->deviceId
];
return true;
}
/**
* 初始化
*
* @return bool
*/
public function init()
{
$url = sprintf($this->baseUri . '/webwxinit?r=%i&lang=en_US&pass_ticket=%s', time(), $this->passTicket);
$content = $this->client->post($url, [
'json' => [
'BaseRequest' => $this->baseRequest
]
])->getBody()->getContents();
$result = json_decode($content, true);
$this->generateSyncKey($result);
$this->myAccount = $result['User'];
return $result['BaseResponse']['Ret'] == 0;
}
public function generateSyncKey($result)
{
$this->syncKey = $result['SyncKey'];
$syncKey = [];
foreach ($this->syncKey['List'] as $item) {
$syncKey[] = $item['Key'] . '_' . $item['Val'];
}
$this->syncKeyStr = implode('|', $syncKey);
}
public function statusNotify()
{
$url = sprintf($this->baseUri . '/webwxstatusnotify?lang=zh_CN&pass_ticket=%s', $this->passTicket);
$content = $this->client->post($url, [
'json' => [
'BaseRequest' => $this->baseRequest,
'Code' => 3,
'FromUserName' => $this->myAccount['UserName'],
'ToUserName' => $this->myAccount['UserName'],
'ClientMsgId' => time()
]
])->getBody()->getContents();
$this->debug($content);
return json_decode($content)->BaseResponse->Ret == 0;
}
public function getContact()
{
$url = sprintf($this->baseUri . '/webwxgetcontact?pass_ticket=%s&skey=%s&r=%s', $this->passTicket, $this->skey, time());
$content = $this->client->post($url, ['json' => []])->getBody()->getContents();
if($this->debug){
file_put_contents($this->tmpPath . 'contacts.json', $content);
}
$result = json_decode($content, true);
$this->memberList = $result['MemberList'];
$specialUsers = ['newsapp', 'fmessage', 'filehelper', 'weibo', 'qqmail',
'fmessage', 'tmessage', 'qmessage', 'qqsync', 'floatbottle',
'lbsapp', 'shakeapp', 'medianote', 'qqfriend', 'readerapp',
'blogapp', 'facebookapp', 'masssendapp', 'meishiapp',
'feedsapp', 'voip', 'blogappweixin', 'weixin', 'brandsessionholder',
'weixinreminder', 'wxid_novlwrv3lqwv11', 'gh_22b87fa7cb3c',
'officialaccounts', 'notification_messages', 'wxid_novlwrv3lqwv11',
'gh_22b87fa7cb3c', 'wxitil', 'userexperience_alarm', 'notification_messages'];
foreach ($this->memberList as $contact) {
if($contact['VerifyFlag'] & 8 != 0){ #公众号
$this->publicList[] = $contact;
$this->accountInfo['normalMember'][$contact['UserName']] = ['type' => 'public', 'info' => $contact];
}elseif (in_array($contact['UserName'], $specialUsers)){ # 特殊账户
$this->specialList[] = $contact;
$this->accountInfo['normalMember'][$contact['UserName']] = ['type' => 'special', 'info' => $contact];
}elseif (strstr($contact['UserName'], '@@') !== false){ # 群聊
$this->groupList[] = $contact;
$this->accountInfo['normalMember'][$contact['UserName']] = ['type' => 'group', 'info' => $contact];
}elseif ($contact['UserName'] === $this->myAccount['UserName']){ # 自己
$this->accountInfo['normalMember'][$contact['UserName']] = ['type' => 'self', 'info' => $contact];
}else{
$this->contactList[] = $contact;
$this->accountInfo['normalMember'][$contact['UserName']] = ['type' => 'contact', 'info' => $contact];
}
}
$this->getBatchGroupMembers();
foreach ($this->groupMembers as $key => $group) {
foreach ($group as $member) {
if(!in_array($member['UserName'], $this->accountInfo)){
$this->accountInfo['groupMember'][$member['UserName']] = ['type' => 'group_member', 'info' => $member, 'group' => $group];
}
}
}
if($this->debug){
file_put_contents($this->tmpPath . 'contact_list.json', json_encode($this->contactList));
file_put_contents($this->tmpPath . 'special_list.json', json_encode($this->specialList));
file_put_contents($this->tmpPath . 'group_list.json', json_encode($this->groupList));
file_put_contents($this->tmpPath . 'public_list.json', json_encode($this->publicList));
file_put_contents($this->tmpPath . 'member_list.json', json_encode($this->memberList));
file_put_contents($this->tmpPath . 'group_users.json', json_encode($this->groupMembers));
file_put_contents($this->tmpPath . 'account_info.json', json_encode($this->accountInfo));
}
return true;
}
public function getBatchGroupMembers()
{
$url = sprintf($this->baseUri . '/webwxbatchgetcontact?type=ex&r=%s&pass_ticket=%s', time(), $this->passTicket);
$list = [];
foreach ($this->groupList as $group) {
$list[] = ['UserName' => $group['UserName'], 'EncryChatRoomId' => ''];
}
$content = $this->client->post($url, [
'json' => [
'BaseRequest' => $this->baseRequest,
'Count' => count($this->groupList),
'List' => $list
]
])->getBody()->getContents();
$result = json_decode($content, true);
$groupMembers = [];
$encry = [];
foreach ($result['ContactList'] as $group) {
$gid = $group['UserName'];
$members = $group['MemberList'];
$groupMembers[$gid] = $members;
$encry[$gid] = $group['EncryChatRoomId'];
}
$this->groupMembers = $groupMembers;
$this->encryChatRoomId = $encry;
}
# 消息处理(第二期再分开到另一个类)
public function processMsg()
{
$this->testSyncCheck();
while (true){
list($retCode, $selector) = $this->syncCheck();
if(in_array($retCode, ['1100', '1101'])){ # 微信客户端上登出或者其他设备登录
break;
}elseif ($retCode == '0'){
// if($selector == 2){
// $msg = $this->sync();
// if($msg !== null){
// $this->handleMsg($msg);
// }
// }
$msg = $this->sync();
$this->log('[MSG]' . json_encode($msg));
}
}
}
/**
* 测试域名同步
*
* @return bool
*/
public function testSyncCheck()
{
foreach (['webpush.', 'webpush2.'] as $host) {
$this->syncHost = $host . $this->baseHost;
$retCode = $this->syncCheck()[0];
if($retCode == 0){
return true;
}
return false;
}
}
public function syncCheck()
{
$url = 'https://' . $this->syncHost . '/cgi-bin/mmwebwx-bin/synccheck?' . http_build_query([
'r' => time(),
'sid' => $this->sid,
'uin' => $this->uin,
'skey' => $this->skey,
'deviceid' => $this->deviceId,
'synckey' => $this->syncKeyStr,
'_' => time()
]);
try{
$content = $this->client->get($url, [
'connect_timeout' => 60
])->getBody()->getContents();
preg_match('/window.synccheck=\{retcode:"(\d+)",selector:"(\d+)"\}/', $content, $matches);
return [$matches[1], $matches[2]];
}catch (Exception $e){
return [-1, -1];
}
}
public function sync()
{
$url = sprintf($this->baseUri . '/webwxsync?sid=%s&skey=%s&lang=en_US&pass_ticket=%s', $this->sid, $this->skey, $this->passTicket);
try{
$content = $this->client->post($url, [
'json' => [
'BaseRequest' => $this->baseRequest,
'SyncKey' => $this->syncKey,
'rr' => ~time()
],
'connect_timeout' => 60
])->getBody()->getContents();
$result = json_decode($content, true);
if($result['BaseResponse']['Ret'] == 0){
$this->generateSyncKey($result);
}
return $result;
}catch (\Exception $e){
return null;
}
}
public function handleMsg($message)
{
foreach ($message['AddMsgList'] as $msg) {
$user = ['id' => $msg['FromUserName'], 'name' => 'unknown'];
if($msg['MsgType'] == 51){
$msgTypeId = 0;
$user['name'] = 'system';
}elseif ($msg['MsgType'] == 37){
$msgTypeId = 37;
continue;
}elseif ($msg['FromUserName'] === $this->myAccount['UserName']){
$msgTypeId = 1;
$user['name'] = 'self';
}elseif ($msg['ToUserName'] === 'filehelper'){
$msgTypeId = 2;
$user['name'] = 'file_helper';
}elseif (substr($msg['FromUserName'], 0, 2) === '@@'){
$msgTypeId = 3;
$user['name'] = $this->getContactPreferName($this->getContactName($user['id']));
}elseif ($this->isBelong($msg['FromUserName'], $this->contactList)){
$msgTypeId = 4;
$user['name'] = $this->getContactPreferName($this->getContactName($user['id']));
}elseif($this->isBelong($msg['FromUserName'], $this->publicList)){
$msgTypeId = 5;
$user['name'] = $this->getContactPreferName($this->getContactName($user['id']));
}elseif($this->isBelong($msg['FromUserName'], $this->specialList)){
$msgTypeId = 6;
$user['name'] = $this->getContactPreferName($this->getContactName($user['id']));
}else{
$msgTypeId = 99;
}
$user['name'] = html_entity_decode($user['name']);
if($this->debug && $msgTypeId !== 0){
$this->log("[MSG] {$user['name']} :");
}
}
}
/**
* 获取联系人名称数组
*
* @param $uid
* @return array|null
*/
public function getContactName($uid)
{
$info = $this->getContactInfo($uid);
if($info === null){
return null;
}
$name = [];
$info = $info['info'];
if($info['RemarkName']){
$name['remarkName'] = $info['RemarkName'];
}
if($info['NickName']){
$name['nickname'] = $info['NickName'];
}
if($info['DisplayName']){
$name['displayName'] = $info['DisplayName'];
}
return count($name) === 0 ? null : $name;
}
/**
* 根据ID获取用户信息
*
* @param $uid
* @return null
*/
public function getContactInfo($uid)
{
return $this->accountInfo['normalMember'][$uid] ?? null;
}
/**
* 根据优先级获取用户名称
*
* @param $name
* @return null
*/
public function getContactPreferName($name)
{
if(!$name){
return null;
}
return $name['remarkName'] ?? $name['nickname'] ?? $name['displayName'] ?? null;
}
/**
* 是否联系人
*
* @param $uid
* @param $list
* @return bool
*/
public function isBelong($uid, $list)
{
foreach ($list as $contact) {
if($uid === $contact['UserName']){
return true;
}
}
return false;
}
public function extractMsgContent($msgTypeId, $msg)
{
$content = html_entity_decode($msg['Content']);
$msgContent = [];
if($msgTypeId === 0){
return ['type' => 11, 'data' => ''];
}elseif($msgTypeId === 2){
return ['type' => 0, 'data' => str_replace('<br/>', '\n', $content)];
}elseif ($msgTypeId === 3){
$spilt = explode('<br/>', $content, 2);
$uid = substr($spilt[0], 0, -1);
$content = str_replace('<br/>', '', $content);
$name = $this->getContactPreferName($this->getContactName($uid));
$name = $name ?? $this->getGroupMemberPreferName($this->getGroupMemberName($msg['FromUserName'], $uid)) ?? 'unknown';
$msgContent['user'] = ['id' => $uid, 'name' => $name];
}
$msgPrefix = isset($msgContent['user']) ? $msgContent['user']['name'] . ':' : '';
if($msg['MsgType'] == 1){
if(strstr($content, 'http://weixin.qq.com/cgi-bin/redirectforward?args=') !== false){
}
}
}
public function getGroupMemberPreferName($name)
{
if(!$name){
return null;
}
return $name['remarkName'] ?? $name['displayName'] ?? $name['nickname'] ?? null;
}
/**
* 获取群聊用户名称
*
* @param $gid
* @param $uid
* @return array|null
*/
public function getGroupMemberName($gid, $uid)
{
if(!isset($this->groupMembers)){
return null;
}
$group = $this->groupMembers[$gid];
foreach ($group as $member) {
if($member['UserName'] === $uid){
$name = [];
if($member['RemarkName']){
$name['remarkName'] = $member['RemarkName'];
}
if($member['NickName']){
$name['nickname'] = $member['NickName'];
}
if($member['DisplayName']){
$name['displayName'] = $member['DisplayName'];
}
return $name;
}
}
return null;
}
private function debug($content)
{
file_put_contents($this->tmpPath . 'debug.json', $content);
}
private function log($msg)
{
echo $msg . PHP_EOL;
}
public function __get($value)
{
return $this->$value;
}
}
\ No newline at end of file
<?php
/**
* Created by PhpStorm.
* User: HanSon
* Date: 2017/1/13
* Time: 17:23
*/
namespace Hanson\Vbot\Support;
trait ObjectAble
{
public function toObject(Array $array)
{
return json_decode(json_encode($array));
}
}
\ No newline at end of file
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!