Skip to content
Toggle navigation
Projects
Groups
Snippets
Help
Toggle navigation
This project
Loading...
Sign in
hfpp2012
/
vbot
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Settings
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit 65fb54d2
authored
Dec 15, 2016
by
HanSon
Browse Files
Options
Browse Files
Tag
Download
Email Patches
Plain Diff
开始消息模块
1 parent
b29bc04a
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
270 additions
and
33 deletions
README.md
composer.lock
src/Core/MessageHandler.php
src/Core/Server.php
src/Message/Message.php
test/test.php
README.md
View file @
65fb54d
...
...
@@ -18,3 +18,8 @@ Robot->special
Robot->contact
Robot->group
# what can wx-robot do?
*
转发消息
*
记录特别消息
*
特别关注某人
\ No newline at end of file
composer.lock
View file @
65fb54d
...
...
@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
"hash": "
01d02b438cdd61b6f9c0202caaf088fb
",
"hash": "
a651fd0a020b70751704aec9ca9217f9
",
"content-hash": "524011ccf768eadbec9c686506e6057c",
"packages": [
{
...
...
@@ -648,7 +648,7 @@
},
{
"name": "symfony/css-selector",
"version": "v3.2.
0
",
"version": "v3.2.
1
",
"source": {
"type": "git",
"url": "https://github.com/symfony/css-selector.git",
...
...
@@ -701,16 +701,16 @@
},
{
"name": "symfony/dom-crawler",
"version": "v3.2.
0
",
"version": "v3.2.
1
",
"source": {
"type": "git",
"url": "https://github.com/symfony/dom-crawler.git",
"reference": "
c6b6111f5aae7c58698cdc10220785627ac44a2c
"
"reference": "
1638c7534a8a2fa0bf9e979f9aacb6d7e8e9e24e
"
},
"dist": {
"type": "zip",
"url": "https://packagist.phpcomposer.com/files/symfony/dom-crawler/
c6b6111f5aae7c58698cdc10220785627ac44a2c
.zip",
"reference": "
c6b6111f5aae7c58698cdc10220785627ac44a2c
",
"url": "https://packagist.phpcomposer.com/files/symfony/dom-crawler/
1638c7534a8a2fa0bf9e979f9aacb6d7e8e9e24e
.zip",
"reference": "
1638c7534a8a2fa0bf9e979f9aacb6d7e8e9e24e
",
"shasum": ""
},
"require": {
...
...
@@ -753,11 +753,11 @@
],
"description": "Symfony DomCrawler Component",
"homepage": "https://symfony.com",
"time": "2016-1
1-25 12:32:42
"
"time": "2016-1
2-10 14:24:53
"
},
{
"name": "symfony/options-resolver",
"version": "v3.2.
0
",
"version": "v3.2.
1
",
"source": {
"type": "git",
"url": "https://github.com/symfony/options-resolver.git",
...
...
src/Core/MessageHandler.php
View file @
65fb54d
...
...
@@ -9,13 +9,46 @@
namespace
Hanson\Robot\Core
;
use
Closure
;
use
Hanson\Robot\Message\Message
;
use
Hanson\Robot\Support\Log
;
class
MessageHandler
{
protected
$server
;
private
$syncHost
;
private
$handler
;
static
$instance
=
null
;
const
MESSAGE_MAP
=
[
2
=>
'text'
,
// 新消息
3
=>
'unknown'
,
// 未知
4
=>
'contactUpdate'
,
// 通讯录更新
6
=>
'money'
,
// 可能是红包
7
=>
'mobile'
// 手机上操作了微信
];
public
function
__construct
(
Server
$server
)
{
$this
->
server
=
$server
;
}
/**
* get a message handler single instance
*
* @param Server $server
* @return MessageHandler
*/
public
static
function
getInstance
(
$server
=
null
)
{
if
(
static
::
$instance
===
null
){
static
::
$instance
=
new
MessageHandler
(
$server
);
}
return
static
::
$instance
;
}
public
function
setMessageHandler
(
Closure
$closure
)
{
...
...
@@ -26,9 +59,157 @@ class MessageHandler
$this
->
handler
=
$closure
;
}
/**
* listen the chat api
*/
public
function
listen
()
{
call_user_func_array
(
$this
->
handler
,
[]);
$this
->
preCheckSync
();
while
(
true
){
$time
=
time
();
list
(
$retCode
,
$selector
)
=
$this
->
checkSync
();
if
(
in_array
(
$retCode
,
[
'1100'
,
'1101'
])){
# 微信客户端上登出或者其他设备登录
break
;
}
elseif
(
$retCode
==
0
){
$this
->
handlerMessage
(
$selector
);
}
else
{
$this
->
debugMessage
(
$retCode
,
$selector
,
10
);
}
$this
->
checkTime
(
$time
);
}
// call_user_func_array($this->handler, []);
}
private
function
handlerMessage
(
$selector
)
{
if
(
$selector
===
0
){
return
;
}
$message
=
$this
->
sync
();
Message
::
make
(
$selector
,
$message
);
// print_r($message);
Log
::
echo
(
json_encode
(
$message
));
}
/**
* get a message code
*
* @return array
*/
private
function
checkSync
()
{
$url
=
'https://'
.
$this
->
syncHost
.
'/cgi-bin/mmwebwx-bin/synccheck?'
.
http_build_query
([
'r'
=>
time
(),
'sid'
=>
$this
->
server
->
sid
,
'uin'
=>
$this
->
server
->
uin
,
'skey'
=>
$this
->
server
->
skey
,
'deviceid'
=>
$this
->
server
->
deviceId
,
'synckey'
=>
$this
->
server
->
syncKeyStr
,
'_'
=>
time
()
]);
try
{
$content
=
$this
->
server
->
http
->
get
(
$url
);
preg_match
(
'/window.synccheck=\{retcode:"(\d+)",selector:"(\d+)"\}/'
,
$content
,
$matches
);
return
[
$matches
[
1
],
$matches
[
2
]];
}
catch
(
\Exception
$e
){
return
[
-
1
,
-
1
];
}
}
/**
* test a domain before sync
*
* @return bool
*/
private
function
preCheckSync
()
{
foreach
([
'webpush.'
,
'webpush2.'
]
as
$host
)
{
$this
->
syncHost
=
$host
.
Server
::
BASE_HOST
;
list
(
$retCode
,)
=
$this
->
checkSync
();
if
(
$retCode
==
0
){
return
true
;
}
}
return
false
;
}
private
function
sync
()
{
$url
=
sprintf
(
Server
::
BASE_URI
.
'/webwxsync?sid=%s&skey=%s&lang=en_US&pass_ticket=%s'
,
$this
->
server
->
sid
,
$this
->
server
->
skey
,
$this
->
server
->
passTicket
);
try
{
$result
=
$this
->
server
->
http
->
json
(
$url
,
[
'BaseRequest'
=>
$this
->
server
->
baseRequest
,
'SyncKey'
=>
$this
->
server
->
syncKey
,
'rr'
=>
~
time
()
],
true
);
if
(
$result
[
'BaseResponse'
][
'Ret'
]
==
0
){
$this
->
generateSyncKey
(
$result
);
}
return
$result
;
}
catch
(
\Exception
$e
){
return
null
;
}
}
/**
* generate a sync key
*
* @param $result
*/
private
function
generateSyncKey
(
$result
)
{
$this
->
server
->
syncKey
=
$result
[
'SyncKey'
];
$syncKey
=
[];
foreach
(
$this
->
server
->
syncKey
[
'List'
]
as
$item
)
{
$syncKey
[]
=
$item
[
'Key'
]
.
'_'
.
$item
[
'Val'
];
}
$this
->
server
->
syncKeyStr
=
implode
(
'|'
,
$syncKey
);
}
/**
* check message time
*
* @param $time
*/
private
function
checkTime
(
$time
)
{
$checkTime
=
time
()
-
$time
;
if
(
$checkTime
<
0.8
){
sleep
(
1
-
$checkTime
);
}
}
/**
* debug while the sync
*
* @param $retCode
* @param $selector
* @param null $sleep
*/
private
function
debugMessage
(
$retCode
,
$selector
,
$sleep
=
null
)
{
Log
::
echo
(
'[DEBUG] retcode:'
.
$retCode
.
' selector:'
.
$selector
);
if
(
$sleep
){
sleep
(
$sleep
);
}
}
}
\ No newline at end of file
src/Core/Server.php
View file @
65fb54d
...
...
@@ -26,21 +26,21 @@ class Server
public
$skey
;
p
rotected
$sid
;
p
ublic
$sid
;
p
rotected
$uin
;
p
ublic
$uin
;
public
$passTicket
;
p
rotected
$deviceId
;
p
ublic
$deviceId
;
public
$baseRequest
;
p
rotected
$syncKey
;
p
ublic
$syncKey
;
protected
$myAccount
;
static
$myAccount
;
p
rotected
$syncKeyStr
;
p
ublic
$syncKeyStr
;
public
$http
;
...
...
@@ -74,7 +74,7 @@ class Server
$this
->
initContact
();
Log
::
echo
(
'[INFO] init contacts success!'
);
MessageHandler
::
listen
();
MessageHandler
::
getInstance
()
->
listen
();
}
public
function
prepare
()
...
...
@@ -144,8 +144,6 @@ class Server
$content
=
$this
->
http
->
get
(
$url
);
Log
::
echo
(
$content
);
preg_match
(
'/window.code=(\d+);/'
,
$content
,
$matches
);
$code
=
$matches
[
1
];
...
...
@@ -219,7 +217,7 @@ class Server
$result
=
json_decode
(
$content
,
true
);
$this
->
generateSyncKey
(
$result
);
$this
->
myAccount
=
$result
[
'User'
];
static
::
$
myAccount
=
$result
[
'User'
];
if
(
$result
[
'BaseResponse'
][
'Ret'
]
!=
0
){
throw
new
Exception
(
'[ERROR] init fail!'
);
...
...
@@ -241,8 +239,8 @@ class Server
$this
->
http
->
json
(
$url
,
[
'BaseRequest'
=>
$this
->
baseRequest
,
'Code'
=>
3
,
'FromUserName'
=>
$this
->
myAccount
[
'UserName'
],
'ToUserName'
=>
$this
->
myAccount
[
'UserName'
],
'FromUserName'
=>
static
::
$
myAccount
[
'UserName'
],
'ToUserName'
=>
static
::
$
myAccount
[
'UserName'
],
'ClientMsgId'
=>
time
()
]);
}
...
...
@@ -260,6 +258,20 @@ class Server
$this
->
syncKeyStr
=
implode
(
'|'
,
$syncKey
);
}
public
static
function
isMyself
(
$fromUserName
)
{
return
$fromUserName
===
static
::
$myAccount
[
'UserName'
];
}
public
function
setMessageHandler
(
\Closure
$closure
)
{
if
(
!
is_callable
(
$closure
)){
throw
new
\Exception
(
'[ERROR] message handler must be a closure!'
);
}
MessageHandler
::
getInstance
(
$this
)
->
setMessageHandler
(
$closure
);
}
public
function
debug
(
$debug
=
true
)
{
$this
->
debug
=
$debug
;
...
...
src/Message/Message.php
View file @
65fb54d
...
...
@@ -9,7 +9,46 @@
namespace
Hanson\Robot\Message
;
use
Hanson\Robot\Core\Server
;
class
Message
{
public
$sender
;
public
$receiver
;
public
$content
;
public
$time
;
public
$type
;
static
$message
=
[];
const
USER_MAP
=
[
0
=>
'Init'
,
1
=>
'Self'
,
2
=>
'FileHelper'
,
3
=>
'Group'
,
4
=>
'Contact'
,
5
=>
'Public'
,
6
=>
'Special'
,
99
=>
'UnKnown'
,
];
public
function
make
(
$selector
,
$message
)
{
$msg
=
$message
[
'AddMsgList'
][
0
];
if
(
$msg
[
'MsgType'
]
==
51
){
$this
->
sender
->
name
=
'system'
;
$this
->
sender
->
type
=
0
;
}
elseif
(
$msg
[
'MsgType'
]
==
37
){
$this
->
sender
->
type
=
37
;
}
elseif
(
Server
::
isMyself
(
$msg
[
'FromUserName'
])){
}
}
}
\ No newline at end of file
test/test.php
View file @
65fb54d
...
...
@@ -15,7 +15,17 @@ $robot = new \Hanson\Robot\Robot([
'tuling_key'
=>
''
]);
//$robot->setMessageHandler(function($message){
//$robot->run();
$robot
=
new
\Hanson\Robot\Foundation\Robot
([
'tmp'
=>
realpath
(
'./tmp'
)
.
'/'
,
'debug'
=>
true
,
'tuling'
=>
true
,
'tuling_key'
=>
''
]);
$robot
->
server
->
setMessageHandler
(
function
(
$message
){
// if($message->type === 'text'){
//
// }elseif ($message->type === 'location'){
...
...
@@ -25,16 +35,6 @@ $robot = new \Hanson\Robot\Robot([
// if($message->FromUserName === ''){
// # do something;
// }
//
//});
//$robot->run();
$robot
=
new
\Hanson\Robot\Foundation\Robot
([
'tmp'
=>
realpath
(
'./tmp'
)
.
'/'
,
'debug'
=>
true
,
'tuling'
=>
true
,
'tuling_key'
=>
''
]);
});
$robot
->
server
->
run
();
Write
Preview
Markdown
is supported
Attach a file
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to post a comment