Commit b3bfcfae by HanSon Committed by GitHub

Merge pull request #50 from HanSon/dev

🎲 优化群控功能
2 parents db06d623 cdd3479a
......@@ -31,13 +31,22 @@ PS:运行后二维码将保存于设置的缓存目录,命名为qr.png,控
**请在terminal运行!请在terminal运行!请在terminal运行!**
## 体验
<img src="https://ws2.sinaimg.cn/large/685b97a1gy1fdordpa0cgj20e80e811z.jpg" height="320">
扫码后,验证输入“上山打老虎”即可自动加为好友并且拉入vbot群。
vbot并非24小时执行,有时会因为开发调试等原因暂停功能。如果碰巧遇到关闭情况,可加Q群 492548647 了解开放时间。执行后发送“拉我”即可自动邀请进群。
vbot示例源码为 https://github.com/HanSon/vbot/blob/master/example/index.php
## 文档
详细文档在[wiki](https://github.com/HanSon/vbot/wiki)
### 例子
[所有类型例子](https://github.com/HanSon/vbot/blob/master/example/index.php)
### 小DEMO
[红包提醒](https://github.com/HanSon/vbot/blob/master/example/hongbao.php)
......
......@@ -35,7 +35,8 @@ $robot = new Vbot([
]);
// 图灵自动回复
function reply($str){
function reply($str)
{
return http()->post('http://www.tuling123.com/openapi/api', [
'key' => '1dce02aef026258eff69635a06b0ab7d',
'info' => $str
......@@ -43,153 +44,244 @@ function reply($str){
}
// 设置管理员
function isAdmin($message)
{
$adminAlias = 'hanson1994';
if (in_array($message->fromType, ['Contact', 'Group'])) {
if ($message->fromType === 'Contact') {
return $message->from['Alias'] === $adminAlias;
} else {
return isset($message->sender['Alias']) && $message->sender['Alias'] === $adminAlias;
}
}
return false;
}
$groupMap = [
[
'nickname' => 'vbot 测试群',
'id' => 1
]
];
$robot->server->setOnceHandler(function () use ($groupMap) {
group()->each(function ($group, $key) use ($groupMap) {
foreach ($groupMap as $map) {
if ($group['NickName'] === $map['nickname']) {
$group['id'] = $map['id'];
$groupMap[$key] = $map['id'];
group()->setMap($key, $map['id']);
}
}
return $group;
});
});
$robot->server->setMessageHandler(function ($message) use ($path) {
/** @var $message Message */
// 位置信息 返回位置文字
if ($message instanceof Location) {
/** @var $message Location */
Text::send('地图链接:'.$message->from['UserName'], $message->url);
return '位置:'.$message;
Text::send('地图链接:' . $message->from['UserName'], $message->url);
return '位置:' . $message;
}
// 文字信息
if ($message instanceof Text) {
/** @var $message Text */
if (str_contains($message->content, 'vbot') && !$message->isAt) {
return "你好,我叫vbot,我爸是HanSon\n我的项目地址是 https://github.com/HanSon/vbot \n欢迎来给我star!";
}
// 联系人自动回复
if ($message->fromType === 'Contact') {
if ($message->content === '拉我') {
$username = group()->getUsernameById(1);
group()->addMember($username, $message->from['UserName']);
}
if($message->content === '测试'){
$username = group()->getUsernameById(1);
print_r($username);
print_r(group()->get($username));
}
return reply($message->content);
// 群组@我回复
} elseif ($message->fromType === 'Group' && $message->isAt) {
} elseif ($message->fromType === 'Group') {
if (str_contains($message->content, '设置群名称') && isAdmin($message)) {
group()->setGroupName($message->from['UserName'], str_replace('设置群名称', '', $message->content));
}
if (str_contains($message->content, '搜人') && isAdmin($message)) {
$nickname = str_replace('搜人', '', $message->content);
$members = group()->getMembersByNickname($message->from['UserName'], $nickname, true);
$result = '搜索结果 数量:' . count($members) . "\n";
foreach ($members as $member) {
$result .= $member['NickName'] . ' ' . $member['UserName'] . "\n";
}
return $result;
}
if (str_contains($message->content, '踢人') && isAdmin($message)) {
$username = str_replace('踢人', '', $message->content);
group()->deleteMember($message->from['UserName'], $username);
}
if (str_contains($message->content, '踢我') && $message->isAt) {
Text::send($message->from['UserName'], '拜拜 ' . $message->sender['NickName']);
group()->deleteMember($message->from['UserName'], $message->sender['UserName']);
return 'vbot 从未见过这么犯贱的人';
}
if ($message->isAt) {
return reply($message->content);
}
}
}
// 图片信息 返回接收到的图片
if ($message instanceof Image) {
return $message;
// return $message;
}
// 视频信息 返回接收到的视频
if ($message instanceof Video) {
return $message;
// return $message;
}
// 表情信息 返回接收到的表情
if ($message instanceof Emoticon) {
return $message;
Emoticon::sendRandom($message->from['UserName']);
}
// 语音消息
if($message instanceof Voice){
if ($message instanceof Voice) {
/** @var $message Voice */
return '收到一条语音并下载在' . $message::getPath($message::$folder) . "/{$message->msg['MsgId']}.mp3";
// return '收到一条语音并下载在' . $message::getPath($message::$folder) . "/{$message->msg['MsgId']}.mp3";
}
// 撤回信息
if ($message instanceof Recall && $message->msg['FromUserName'] !== myself()->username) {
/** @var $message Recall */
if($message->origin instanceof Image){
if ($message->origin instanceof Image) {
Text::send($message->msg['FromUserName'], "{$message->nickname} 撤回了一张照片");
Image::sendByMsgId($message->msg['FromUserName'], $message->origin->msg['MsgId']);
}elseif($message->origin instanceof Emoticon){
} elseif ($message->origin instanceof Emoticon) {
Text::send($message->msg['FromUserName'], "{$message->nickname} 撤回了一个表情");
Emoticon::sendByMsgId($message->msg['FromUserName'], $message->origin->msg['MsgId']);
}elseif($message->origin instanceof Video){
} elseif ($message->origin instanceof Video) {
Text::send($message->msg['FromUserName'], "{$message->nickname} 撤回了一个视频");
Video::sendByMsgId($message->msg['FromUserName'], $message->origin->msg['MsgId']);
}elseif($message->origin instanceof Voice){
} elseif ($message->origin instanceof Voice) {
Text::send($message->msg['FromUserName'], "{$message->nickname} 撤回了一条语音");
}else{
} else {
Text::send($message->msg['FromUserName'], "{$message->nickname} 撤回了一条信息 \"{$message->origin->msg['Content']}\"");
}
}
// 红包信息
if($message instanceof RedPacket){
if ($message instanceof RedPacket) {
// do something to notify if you want ...
return $message->content . ' 来自 ' .$message->from['NickName'];
return $message->content . ' 来自 ' . $message->from['NickName'];
}
// 转账信息
if($message instanceof Transfer){
if ($message instanceof Transfer) {
/** @var $message Transfer */
return $message->content . ' 收到金额 ' . $message->fee;
}
// 推荐名片信息
if($message instanceof Recommend){
if ($message instanceof Recommend) {
/** @var $message Recommend */
if($message->isOfficial){
if ($message->isOfficial) {
return $message->from['NickName'] . ' 向你推荐了公众号 ' . $message->province . $message->city .
" {$message->info['NickName']} 公众号信息: {$message->description}";
}else{
} else {
return $message->from['NickName'] . ' 向你推荐了 ' . $message->province . $message->city .
" {$message->info['NickName']} 头像链接: {$message->bigAvatar}";
}
}
// 请求添加信息
if($message instanceof RequestFriend){
if ($message instanceof RequestFriend) {
/** @var $message RequestFriend */
$groupUsername = group()->getGroupsByNickname('芬芬', true)->first()['UserName'];
Text::send($groupUsername, "{$message->info['NickName']} 请求添加好友 \"{$message->info['Content']}\"");
if($message->info['Content'] === '上山打老虎'){
if ($message->info['Content'] === '上山打老虎') {
Text::send($groupUsername, '暗号正确');
$message->verifyUser($message::VIA);
}else{
} else {
Text::send($groupUsername, '暗号错误');
}
}
// 分享信息
if($message instanceof Share){
if ($message instanceof Share) {
/** @var $message Share */
$reply = "收到分享\n标题:{$message->title}\n描述:{$message->description}\n链接:{$message->url}";
if($message->app){
if ($message->app) {
$reply .= "\n来源APP:{$message->app}";
}
return $reply;
}
// 分享小程序信息
if($message instanceof Mina){
if ($message instanceof Mina) {
/** @var $message Mina */
$reply = "收到小程序\n小程序名词:{$message->title}\n链接:{$message->url}";
return $reply;
}
// 公众号推送信息
if($message instanceof Official){
if ($message instanceof Official) {
/** @var $message Official */
$reply = "收到公众号推送\n标题:{$message->title}\n描述:{$message->description}\n链接:{$message->url}\n来源公众号名称:{$message->app}";
return $reply;
}
// 手机点击聊天事件
if($message instanceof Touch){
Text::send($message->msg['ToUserName'], "我点击了此聊天");
if ($message instanceof Touch) {
// Text::send($message->msg['ToUserName'], "我点击了此聊天");
}
// 新增好友
if($message instanceof \Hanson\Vbot\Message\Entity\NewFriend){
\Hanson\Vbot\Support\Console::log('新加好友:' . $message->from['NickName']);
if ($message instanceof \Hanson\Vbot\Message\Entity\NewFriend) {
\Hanson\Vbot\Support\Console::debug('新加好友:' . $message->from['NickName']);
Text::send($message->from['UserName'], "客官,等你很久了!感谢跟 vbot 交朋友,如果可以帮我点个star,谢谢了!https://github.com/HanSon/vbot");
group()->addMember(group()->getUsernameById(1), $message->from['UserName']);
return '现在拉你进去vbot的测试群,进去后为了避免轰炸记得设置免骚扰哦!如果被不小心踢出群,跟我说声“拉我”我就会拉你进群的了。';
}
// 群组变动
if($message instanceof GroupChange){
if ($message instanceof GroupChange) {
/** @var $message GroupChange */
if($message->action === 'ADD'){
\Hanson\Vbot\Support\Console::log('新人进群');
return $message->content;
}elseif($message->action === 'REMOVE'){
\Hanson\Vbot\Support\Console::log('群主踢人了');
return $message->content;
}elseif($message->action === 'RENAME'){
\Hanson\Vbot\Support\Console::log($message->from['NickName'].' 改名为 '.$message->rename);
if ($message->action === 'ADD') {
\Hanson\Vbot\Support\Console::debug('新人进群');
return '欢迎新人 ' . $message->nickname;
} elseif ($message->action === 'REMOVE') {
\Hanson\Vbot\Support\Console::debug('群主踢人了');
return $message->content;
} elseif ($message->action === 'RENAME') {
// \Hanson\Vbot\Support\Console::log($message->from['NickName'] . ' 改名为 ' . $message->rename);
if (group()->getUsernameById(1) == $message->from['UserName'] && $message->rename !== 'vbot 测试群') {
group()->setGroupName($message->from['UserName'], 'vbot 测试群');
return '行不改名,坐不改姓!';
}
} elseif ($message->action === 'BE_REMOVE') {
\Hanson\Vbot\Support\Console::debug('你被踢出了群 ' . $message->group['NickName']);
} elseif ($message->action === 'INVITE') {
\Hanson\Vbot\Support\Console::debug('你被邀请进群 ' . $message->from['NickName']);
}
}
......@@ -197,11 +289,11 @@ $robot->server->setMessageHandler(function ($message) use ($path) {
});
$robot->server->setExitHandler(function(){
$robot->server->setExitHandler(function () {
\Hanson\Vbot\Support\Console::log('其他设备登录');
});
$robot->server->setExceptionHandler(function(){
$robot->server->setExceptionHandler(function () {
\Hanson\Vbot\Support\Console::log('异常退出');
});
......
......@@ -26,7 +26,7 @@ class Contact extends Collection
*/
public static function getInstance()
{
if(static::$instance === null){
if (static::$instance === null) {
static::$instance = new Contact();
}
......@@ -41,8 +41,8 @@ class Contact extends Collection
*/
public function getContactById($id)
{
return $this->filter(function($item, $key) use ($id){
if($item['Alias'] === $id){
return $this->filter(function ($item, $key) use ($id) {
if ($item['Alias'] === $id) {
return true;
}
})->first();
......@@ -56,22 +56,23 @@ class Contact extends Collection
*/
public function getUsernameById($id)
{
return $this->search(function($item, $key) use ($id){
if($item['Alias'] === $id){
return $this->search(function ($item, $key) use ($id) {
if ($item['Alias'] === $id) {
return true;
}
});
}
/**
* 根据通讯录中的备注获取通讯对象
*
* @param $id
* @return mixed
*/
public function getUsernameByRemarkName( $id)
public function getUsernameByRemarkName($id)
{
return $this->search(function($item, $key) use ($id){
if($item['RemarkName'] === $id){
return $this->search(function ($item, $key) use ($id) {
if ($item['RemarkName'] === $id) {
return true;
}
});
......@@ -81,12 +82,15 @@ class Contact extends Collection
* 根据通讯录中的昵称获取通讯对象
*
* @param $nickname
* @param bool $blur
* @return mixed
*/
public function getUsernameByNickname($nickname)
public function getUsernameByNickname($nickname, $blur = false)
{
return $this->search(function($item, $key) use ($nickname){
if($item['NickName'] === $nickname){
return $this->search(function ($item, $key) use ($nickname, $blur) {
if ($blur && str_contains($item['NickName'], $nickname)) {
return true;
} elseif (!$blur && $item['NickName'] === $nickname) {
return true;
}
});
......@@ -113,7 +117,7 @@ class Contact extends Collection
$result = http()->json($url, [
'UserName' => $username,
'CmdId' => 3,
'OP' => (int) $isStick,
'OP' => (int)$isStick,
'BaseRequest' => server()->baseRequest
], true);
......
......@@ -34,11 +34,11 @@ class ContactFactory
$this->makeContactList();
$contact = contact()->get(myself()->username);
myself()->alias = isset($contact['Alias']) ? $contact['Alias'] : myself()->nickname ? : myself()->username;
myself()->alias = isset($contact['Alias']) ? $contact['Alias'] : myself()->nickname ?: myself()->username;
$this->getBatchGroupMembers();
if(server()->config['debug']){
if (server()->config['debug']) {
FileManager::download('contact.json', json_encode(contact()->all()));
FileManager::download('member.json', json_encode(member()->all()));
FileManager::download('group.json', json_encode(group()->all()));
......@@ -56,23 +56,23 @@ class ContactFactory
$url = sprintf(server()->baseUri . '/webwxgetcontact?pass_ticket=%s&skey=%s&r=%s&seq=%s', server()->passTicket, server()->skey, time(), $seq);
$result = http()->json($url, [], true);
$memberList = $result['MemberList'];
$seq = $result['Seq'];
foreach ($memberList as $contact) {
if(official()->isOfficial($contact['VerifyFlag'])){ #公众号
if (isset($result['MemberList']) && $result['MemberList']) {
foreach ($result['MemberList'] as $contact) {
if (official()->isOfficial($contact['VerifyFlag'])) { #公众号
Official::getInstance()->put($contact['UserName'], $contact);
}elseif (in_array($contact['UserName'], static::SPECIAL_USERS)){ # 特殊账户
} elseif (in_array($contact['UserName'], static::SPECIAL_USERS)) { # 特殊账户
Special::getInstance()->put($contact['UserName'], $contact);
}elseif (strstr($contact['UserName'], '@@') !== false){ # 群聊
} elseif (strstr($contact['UserName'], '@@') !== false) { # 群聊
group()->put($contact['UserName'], $contact);
}else{
} else {
contact()->put($contact['UserName'], $contact);
}
}
}
if($seq != 0){
$this->makeContactList($seq);
if (isset($result['Seq']) && $result['Seq'] != 0) {
$this->makeContactList($result['Seq']);
}
}
......@@ -84,7 +84,7 @@ class ContactFactory
$url = sprintf(server()->baseUri . '/webwxbatchgetcontact?type=ex&r=%s&pass_ticket=%s', time(), server()->passTicket);
$list = [];
group()->each(function($item, $key) use (&$list){
group()->each(function ($item, $key) use (&$list) {
$list[] = ['UserName' => $key, 'EncryChatRoomId' => ''];
});
......@@ -104,6 +104,7 @@ class ContactFactory
*/
private function initGroupMembers($array)
{
if (isset($array['ContactList']) && $array['ContactList']) {
foreach ($array['ContactList'] as $group) {
$groupAccount = group()->get($group['UserName']);
$groupAccount['MemberList'] = $group['MemberList'];
......@@ -113,6 +114,7 @@ class ContactFactory
member()->put($member['UserName'], $member);
}
}
}
}
......
......@@ -18,6 +18,13 @@ class Group extends Collection
static $instance = null;
/**
* username => id
*
* @var array
*/
public $map = [];
/**
* create a single instance
*
* @return Group
......@@ -62,6 +69,68 @@ class Group extends Collection
}
/**
* 根据通讯录中的昵称获取通讯对象
*
* @param $nickname
* @return mixed
*/
public function getUsernameByNickname($nickname)
{
return $this->search(function($item, $key) use ($nickname){
if($item['NickName'] === $nickname){
return true;
}
});
}
/**
* 根据昵称搜索群成员
*
* @param $groupUsername
* @param $memberNickname
* @param bool $blur
* @return array
*/
public function getMembersByNickname($groupUsername, $memberNickname, $blur = false)
{
$members = $this->get($groupUsername);
$result = [];
foreach ($members['MemberList'] as $member) {
if ($blur && str_contains($member['NickName'], $memberNickname)) {
$result[] = $member;
} elseif (!$blur && $member['NickName'] === $memberNickname) {
$result[] = $member;
}
}
return $result;
}
/**
* 根据ID获取群username
*
* @param $id
* @return mixed
*/
public function getUsernameById($id)
{
return array_search($id, $this->map);
}
/**
* 设置map
*
* @param $username
* @param $id
*/
public function setMap($username, $id)
{
$this->map[$username] = $id;
}
/**
* 创建群聊天
*
* @param array $contacts
......
......@@ -26,7 +26,7 @@ class Member extends Collection
*/
public static function getInstance()
{
if(static::$instance === null){
if (static::$instance === null) {
static::$instance = new Member();
}
......
......@@ -50,9 +50,11 @@ class Http
return $array ? json_decode($content, true) : $content;
}
public function json($url, $options = [], $array = false)
public function json($url, $params = [], $array = false, $extra = [])
{
$content = $this->request($url, 'POST', ['json' => $options]);
$params = array_merge(['json' => $params], $extra);
$content = $this->request($url, 'POST', $params);
return $array ? json_decode($content, true) : $content;
}
......@@ -86,15 +88,9 @@ class Http
*/
public function request($url, $method = 'GET', $options = [])
{
try{
$response = $this->getClient()->request($method, $url, $options);
return $response->getBody()->getContents();
}catch (\Exception $e){
Console::log('http链接失败:' . $e->getMessage(), Console::ERROR);
Console::log('错误URL:' . $url, Console::ERROR);
}
return null;
return $response->getBody()->getContents();
}
......
......@@ -68,7 +68,7 @@ class MessageFactory
else if(str_contains($msg['Content'], '添加') || str_contains($msg['Content'], 'have added') || str_contains($msg['Content'], '打招呼')){
# 添加好友
return new NewFriend($msg);
}else if(str_contains($msg['Content'], '加入了群聊') || str_contains($msg['Content'], '移出了群聊') || str_contains($msg['Content'], '改群名为')){
}else if(str_contains($msg['Content'], '加入了群聊') || str_contains($msg['Content'], '移出了群聊') || str_contains($msg['Content'], '改群名为') || str_contains($msg['Content'], '移出群聊') || str_contains($msg['Content'], '邀请你')){
return new GroupChange($msg);
}
break;
......
......@@ -32,6 +32,8 @@ class MessageHandler
private $exceptionHandler;
private $onceHandler;
private $sync;
private $messageFactory;
......@@ -49,7 +51,7 @@ class MessageHandler
*/
public static function getInstance()
{
if(static::$instance === null){
if (static::$instance === null) {
static::$instance = new MessageHandler();
}
......@@ -64,7 +66,7 @@ class MessageHandler
*/
public function setMessageHandler(Closure $closure)
{
if(!$closure instanceof Closure){
if (!$closure instanceof Closure) {
throw new \Exception('message handler must be a closure!');
}
......@@ -79,7 +81,7 @@ class MessageHandler
*/
public function setCustomHandler(Closure $closure)
{
if(!$closure instanceof Closure){
if (!$closure instanceof Closure) {
throw new \Exception('custom handler must be a closure!');
}
......@@ -94,7 +96,7 @@ class MessageHandler
*/
public function setExitHandler(Closure $closure)
{
if(!$closure instanceof Closure){
if (!$closure instanceof Closure) {
throw new \Exception('exit handler must be a closure!');
}
......@@ -109,7 +111,7 @@ class MessageHandler
*/
public function setExceptionHandler(Closure $closure)
{
if(!$closure instanceof Closure){
if (!$closure instanceof Closure) {
throw new \Exception('exit handler must be a closure!');
}
......@@ -117,29 +119,48 @@ class MessageHandler
}
/**
* 执行一次的处理器
*
* @param Closure $closure
* @throws \Exception
*/
public function setOnceHandler(Closure $closure)
{
if (!$closure instanceof Closure) {
throw new \Exception('exit handler must be a closure!');
}
$this->onceHandler = $closure;
}
/**
* 轮询消息API接口
*/
public function listen()
{
while (true){
if($this->customHandler instanceof Closure){
if ($this->onceHandler instanceof Closure) {
call_user_func_array($this->onceHandler, []);
}
while (true) {
if ($this->customHandler instanceof Closure) {
call_user_func_array($this->customHandler, []);
}
$time = time();
list($retCode, $selector) = $this->sync->checkSync();
if(in_array($retCode, ['1100', '1101'])){ # 微信客户端上登出或者其他设备登录
if (in_array($retCode, ['1100', '1101'])) { # 微信客户端上登出或者其他设备登录
Console::log('微信客户端正常退出');
if($this->exitHandler){
if ($this->exitHandler) {
call_user_func_array($this->exitHandler, []);
}
break;
}elseif ($retCode == 0){
} elseif ($retCode == 0) {
$this->handlerMessage($selector);
}else{
} else {
Console::log('微信客户端异常退出');
if($this->exceptionHandler){
if ($this->exceptionHandler) {
call_user_func_array($this->exitHandler, []);
}
break;
......@@ -157,27 +178,37 @@ class MessageHandler
*/
private function handlerMessage($selector)
{
if($selector === 0){
if ($selector === 0) {
return;
}
$message = $this->sync->sync();
if($message['AddMsgList']){
if (count($message['ModContactList']) > 0) {
foreach ($message['ModContactList'] as $contact) {
if (str_contains($contact['UserName'], '@@')) {
group()->put($contact['UserName'], $contact);
} else {
contact()->put($contact['UserName'], $contact);
}
}
}
if ($message['AddMsgList']) {
foreach ($message['AddMsgList'] as $msg) {
$content = $this->messageFactory->make($msg);
if($content){
if ($content) {
$this->addToMessageCollection($content);
if($this->handler){
if ($this->handler) {
$reply = call_user_func_array($this->handler, [$content]);
if($reply){
if($reply instanceof Image){
if ($reply) {
if ($reply instanceof Image) {
Image::sendByMsgId($content->from['UserName'], $reply->msg['MsgId']);
}elseif($reply instanceof Video){
} elseif ($reply instanceof Video) {
Video::sendByMsgId($content->from['UserName'], $reply->msg['MsgId']);
}elseif($reply instanceof Emoticon){
} elseif ($reply instanceof Emoticon) {
Emoticon::sendByMsgId($content->from['UserName'], $reply->msg['MsgId']);
}else{
} else {
Text::send($content->from['UserName'], $reply);
}
}
......@@ -194,7 +225,7 @@ class MessageHandler
{
message()->put($message->msg['MsgId'], $message);
if(server()->config['debug']) {
if (server()->config['debug']) {
$file = fopen(System::getPath() . 'message.json', 'a');
fwrite($file, json_encode($message) . PHP_EOL);
fclose($file);
......
......@@ -88,8 +88,10 @@ class Server
$this->statusNotify();
Console::log('开始初始化联系人');
$this->initContact();
Console::log(sprintf("初始化联系人成功\n群数量: %d\n联系人数量: %d\n公众号数量: %d\n特殊号数量: %d", group()->count(), contact()->count(), official()->count(), Special::getInstance()->count()));
Console::log('初始化联系人成功');
Console::log(sprintf("群数量: %d", group()->count()));
Console::log(sprintf("联系人数量: %d", contact()->count()));
Console::log(sprintf("公众号数量: %d", official()->count()));
MessageHandler::getInstance()->listen();
}
......@@ -337,4 +339,9 @@ class Server
{
MessageHandler::getInstance()->setExceptionHandler($closure);
}
public function setOnceHandler(\Closure $closure)
{
MessageHandler::getInstance()->setOnceHandler($closure);
}
}
\ No newline at end of file
......@@ -52,7 +52,7 @@ class Sync
'BaseRequest' => server()->baseRequest,
'SyncKey' => server()->syncKey,
'rr' => ~time()
], true);
], true, ['timeout' => 35]);
if($result['BaseResponse']['Ret'] == 0){
$this->generateSyncKey($result);
......@@ -60,7 +60,7 @@ class Sync
return $result;
}catch (\Exception $e){
return null;
$this->sync();
}
}
......@@ -107,7 +107,7 @@ class Sync
*/
public function debugMessage($retCode, $selector, $sleep = null)
{
Console::log('[DEBUG] retcode:' . $retCode . ' selector:' . $selector);
Console::log('retcode:' . $retCode . ' selector:' . $selector, Console::WARNING);
if($sleep){
sleep($sleep);
......
......@@ -35,7 +35,7 @@ class Emoticon extends Message implements MediaInterface, MessageInterface
$response = static::uploadMedia($username, $file);
if (!$response) {
Console::log("表情 {$file} 上传失败");
Console::log("表情 {$file} 上传失败", Console::WARNING);
return false;
}
......@@ -57,7 +57,7 @@ class Emoticon extends Message implements MediaInterface, MessageInterface
$result = http()->json($url, $data, true);
if ($result['BaseResponse']['Ret'] != 0) {
Console::log('发送表情失败');
Console::log('发送表情失败', Console::WARNING);
return false;
}
......@@ -79,6 +79,22 @@ class Emoticon extends Message implements MediaInterface, MessageInterface
}
/**
* 从当前账号的本地表情库随机发送一个
*
* @param $username
*/
public static function sendRandom($username)
{
$path = static::getPath(static::$folder);
$files = scandir($path);
unset($files[0], $files[1]);
$msgId = $files[array_rand($files)];
static::send($username, $path . '/' . $msgId);
}
/**
* 下载文件
*
* @return mixed
......
......@@ -18,8 +18,27 @@ class GroupChange extends Message implements MessageInterface
public $action;
/**
* 群名重命名的名称
*
* @var
*/
public $rename;
/**
* 被踢出群时的群信息
*
* @var
*/
public $group;
/**
* 新人进群的昵称(可能单个可能多个)
*
* @var
*/
public $nickname;
public function __construct($msg)
{
parent::__construct($msg);
......@@ -29,17 +48,25 @@ class GroupChange extends Message implements MessageInterface
public function make()
{
if(str_contains($this->msg['Content'], '加入了群聊')){
Console::debug($this->msg['Content']);
if (str_contains($this->msg['Content'], '邀请你')) {
$this->action = 'INVITE';
} elseif (str_contains($this->msg['Content'], '加入了群聊')) {
preg_match('/.+"(.+)"加入了群聊/', $this->msg['Content'], $match);
$this->action = 'ADD';
Console::log("检测到 {$this->from['NickName']} 有新成员,正在刷新群成员列表...");
$this->nickname = $match[1];
Console::debug("检测到 {$this->from['NickName']} 有新成员,正在刷新群成员列表...");
(new ContactFactory())->makeContactList();
Console::log('群成员更新成功!');
}elseif(str_contains($this->msg['Content'], '移出了群聊')){
Console::debug('群成员更新成功!');
} elseif (str_contains($this->msg['Content'], '移出了群聊')) {
$this->action = 'REMOVE';
}elseif(str_contains($this->msg['Content'], '改群名为')){
} elseif (str_contains($this->msg['Content'], '改群名为')) {
$this->action = 'RENAME';
preg_match('/改群名为“(.+)”/', $this->msg['Content'], $match);
$this->updateGroupName($match[1]);
} elseif (str_contains($this->msg['Content'], '移出群聊')) {
$this->action = 'BE_REMOVE';
$this->group = group()->pull($this->from['UserName']);
}
$this->content = $this->msg['Content'];
......
......@@ -42,7 +42,7 @@ class Image extends Message implements MessageInterface, MediaInterface
$response = static::uploadMedia($username, $file);
if (!$response) {
Console::log("文件 {$file} 上传失败");
Console::log("文件 {$file} 上传失败", Console::WARNING);
return false;
}
......@@ -63,7 +63,7 @@ class Image extends Message implements MessageInterface, MediaInterface
$result = http()->json($url, $data, true);
if ($result['BaseResponse']['Ret'] != 0) {
Console::log('发送图片失败');
Console::log('发送图片失败', Console::WARNING);
return false;
}
......
......@@ -24,8 +24,8 @@ class NewFriend extends Message implements MessageInterface
public function make()
{
Console::log('检测到新加好友,正在刷新好友列表...');
Console::debug('检测到新加好友,正在刷新好友列表...');
(new ContactFactory())->makeContactList();
Console::log('好友更新成功!');
Console::debug('好友更新成功!');
}
}
\ No newline at end of file
......@@ -58,7 +58,7 @@ class Text extends Message implements MessageInterface
);
if ($result['BaseResponse']['Ret'] != 0) {
Console::log('发送消息失败');
Console::log('发送消息失败', Console::WARNING);
return false;
}
......
......@@ -34,7 +34,7 @@ class Video extends Message implements MessageInterface, MediaInterface
$response = static::uploadMedia($username, $file);
if (!$response) {
Console::log("视频 {$file} 上传失败");
Console::log("视频 {$file} 上传失败", Console::WARNING);
return false;
}
......@@ -55,7 +55,7 @@ class Video extends Message implements MessageInterface, MediaInterface
$result = http()->json($url, $data, true);
if ($result['BaseResponse']['Ret'] != 0) {
Console::log('发送视频失败');
Console::log('发送视频失败', Console::WARNING);
return false;
}
......@@ -90,7 +90,8 @@ class Video extends Message implements MessageInterface, MediaInterface
]
]);
if(strlen($content) === 0){
Console::log('下载视频失败', Console::ERROR);
Console::log('下载视频失败', Console::WARNING);
Console::log('url:'. $url);
}else{
FileManager::download($this->msg['MsgId'] . '.mp4', $content, static::$folder);
}
......
......@@ -79,7 +79,7 @@ trait UploadAble
$response = static::uploadMedia($username, $file);
if(!$response){
Console::log("文件 {$file} 上传失败");
Console::log("文件 {$file} 上传失败", Console::WARNING);
return false;
}
......@@ -100,7 +100,7 @@ trait UploadAble
$result = http()->json($url, $data, true);
if($result['BaseResponse']['Ret'] != 0){
Console::log('发送文件失败');
Console::log('发送文件失败', Console::WARNING);
return false;
}
......
......@@ -34,6 +34,18 @@ class Console
}
/**
* debug 模式下调试输出
*
* @param $str
*/
public static function debug($str)
{
if (server()->config['debug']) {
static::log($str, 'DEBUG');
}
}
/**
* 初始化二维码style
*
* @param OutputInterface $output
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!