Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
.www.
wechaty
提交
cbd3ff0b
W
wechaty
项目概览
.www.
/
wechaty
与 Fork 源项目一致
Fork自
wechaty / wechaty
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
W
wechaty
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
cbd3ff0b
编写于
6月 07, 2018
作者:
Huan (李卓桓)
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
fight with login success
上级
225c569a
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
126 addition
and
81 deletion
+126
-81
src/puppet-padchat/bridge.ts
src/puppet-padchat/bridge.ts
+63
-39
src/puppet-padchat/padchat-rpc.ts
src/puppet-padchat/padchat-rpc.ts
+45
-24
src/puppet-padchat/puppet-padchat.ts
src/puppet-padchat/puppet-padchat.ts
+17
-17
src/wechaty.ts
src/wechaty.ts
+1
-1
未找到文件。
src/puppet-padchat/bridge.ts
浏览文件 @
cbd3ff0b
...
...
@@ -65,7 +65,8 @@ export class Bridge extends EventEmitter {
private
readonly
padchatRpc
:
PadchatRpc
private
autoData
:
AutoDataType
private
loginQrCode
?:
string
private
loginScanQrCode
?
:
string
private
loginScanStatus
?
:
number
private
loginTimer
?:
NodeJS
.
Timer
...
...
@@ -114,9 +115,11 @@ export class Bridge extends EventEmitter {
await
this
.
loadAutoData
()
await
this
.
restoreLogin
()
const
restoreSucceed
=
await
this
.
restoreLogin
()
this
.
startLogin
()
if
(
!
restoreSucceed
)
{
this
.
startLogin
()
}
this
.
state
.
on
(
true
)
}
...
...
@@ -130,7 +133,8 @@ export class Bridge extends EventEmitter {
this
.
saveAutoData
()
this
.
emit
(
'
login
'
,
this
.
selfId
=
username
)
this
.
selfId
=
username
this
.
emit
(
'
login
'
,
this
.
selfId
)
}
public
logout
():
void
{
...
...
@@ -149,7 +153,8 @@ export class Bridge extends EventEmitter {
clearTimeout
(
this
.
loginTimer
)
this
.
loginTimer
=
undefined
}
this
.
loginQrCode
=
undefined
this
.
loginScanQrCode
=
undefined
this
.
loginScanStatus
=
undefined
}
protected
async
startLogin
():
Promise
<
void
>
{
...
...
@@ -169,14 +174,23 @@ export class Bridge extends EventEmitter {
/**
* 2. Wait user response
*/
let
lastStatus
=
WXCheckQRCodeStatus
.
Unknown
let
loop
=
true
while
(
loop
)
{
let
waitUser
=
true
while
(
waitUser
)
{
const
result
=
await
this
.
padchatRpc
.
WXCheckQRCode
()
if
(
lastStatus
!==
result
.
status
&&
this
.
loginQrCode
)
{
lastStatus
=
result
.
status
this
.
emit
(
'
scan
'
,
this
.
loginQrCode
,
result
.
status
)
if
(
this
.
loginScanStatus
!==
result
.
status
&&
this
.
loginScanQrCode
)
{
this
.
loginScanStatus
=
result
.
status
this
.
emit
(
'
scan
'
,
this
.
loginScanQrCode
,
this
.
loginScanStatus
,
)
}
if
(
result
.
expired_time
&&
result
.
expired_time
<
10
)
{
// result.expire_time is second
// emit new qrcode before the old one expired
waitUser
=
false
}
switch
(
result
.
status
)
{
...
...
@@ -205,29 +219,38 @@ export class Bridge extends EventEmitter {
case
WXCheckQRCodeStatus
.
Timeout
:
log
.
silly
(
'
PuppetPadchatBridge
'
,
'
checkQrcode: Timeout
'
)
this
.
loginQrCode
=
undefined
loop
=
false
this
.
loginScanQrCode
=
undefined
this
.
loginScanStatus
=
undefined
waitUser
=
false
break
case
WXCheckQRCodeStatus
.
Cancel
:
log
.
silly
(
'
PuppetPadchatBridge
'
,
'
user cancel
'
)
this
.
loginQrCode
=
undefined
loop
=
false
this
.
loginScanQrCode
=
undefined
this
.
loginScanStatus
=
undefined
waitUser
=
false
break
default
:
throw
new
Error
(
'
unknown status:
'
+
result
.
status
)
log
.
warn
(
'
PadchatBridge
'
,
'
startLogin() unknown WXCheckQRCodeStatus:
'
+
result
.
status
)
this
.
loginScanQrCode
=
undefined
this
.
loginScanStatus
=
undefined
waitUser
=
false
break
}
await
new
Promise
(
r
=>
setTimeout
(
r
,
1000
))
}
await
this
.
emitLoginQrCode
()
this
.
loginTimer
=
setTimeout
(
this
.
startLogin
.
bind
(
this
),
1000
)
this
.
loginTimer
=
setTimeout
(()
=>
{
this
.
loginTimer
=
undefined
this
.
startLogin
()
},
1000
)
return
}
protected
async
restoreLogin
():
Promise
<
void
>
{
protected
async
restoreLogin
():
Promise
<
boolean
>
{
/**
* 1. The following `if/else` block: emit qrcode or send login request to the user.
*/
...
...
@@ -243,8 +266,8 @@ export class Bridge extends EventEmitter {
/**
* 1.1 Auto Login Success, return username as the result
*/
this
.
selfId
=
autoLoginResult
.
user_name
return
this
.
login
(
autoLoginResult
.
user_name
)
return
true
}
else
{
/**
...
...
@@ -266,13 +289,13 @@ export class Bridge extends EventEmitter {
await
this
.
emitLoginQrCode
()
}
}
return
return
false
}
protected
async
emitLoginQrCode
():
Promise
<
void
>
{
log
.
verbose
(
'
PuppetPadchatBridge
'
,
`emitLoginQrCode()`
)
if
(
this
.
loginQrCode
)
{
if
(
this
.
login
Scan
QrCode
)
{
throw
new
Error
(
'
qrcode exist
'
)
}
...
...
@@ -284,10 +307,13 @@ export class Bridge extends EventEmitter {
const
qrCodeText
=
await
pfHelper
.
imageBase64ToQrCode
(
result
.
qr_code
)
this
.
loginScanQrCode
=
qrCodeText
this
.
loginScanStatus
=
WXCheckQRCodeStatus
.
WaitScan
this
.
emit
(
'
scan
'
,
this
.
login
QrCode
=
qrCodeText
,
0
,
this
.
login
ScanQrCode
,
this
.
loginScanStatus
,
)
}
...
...
@@ -310,13 +336,14 @@ export class Bridge extends EventEmitter {
protected
async
loadAutoData
():
Promise
<
void
>
{
log
.
verbose
(
'
PuppetPadchatBridge
'
,
`loadAutoData()`
)
const
autoData
:
AutoDataType
=
await
this
.
options
.
memory
.
get
(
AUTO_DATA_SLOT
)
this
.
autoData
=
{
...
autoData
||
{}
}
this
.
autoData
=
{
...
await
this
.
options
.
memory
.
get
(
AUTO_DATA_SLOT
),
}
// Check for 62 data, if has, then use WXLoadWxDat
if
(
autoData
.
wxData
)
{
if
(
this
.
autoData
.
wxData
)
{
log
.
silly
(
'
PuppetPadchatBridge
'
,
`start(), get 62 data`
)
await
this
.
padchatRpc
.
WXLoadWxDat
(
autoData
.
wxData
)
await
this
.
padchatRpc
.
WXLoadWxDat
(
this
.
autoData
.
wxData
)
}
}
...
...
@@ -346,13 +373,12 @@ export class Bridge extends EventEmitter {
public
async
syncContactsAndRooms
():
Promise
<
void
>
{
log
.
verbose
(
'
PuppetPadchatBridge
'
,
`syncContactsAndRooms()`
)
let
cont
=
true
// const syncContactMap = new Map<string, PadchatContactPayload>()
// const syncRoomMap = new Map<string, PadchatRoomPayload>()
// let contactIdList: string[] = []
// let roomIdList: string[] = []
while
(
cont
&&
this
.
state
.
on
()
&&
this
.
selfId
)
{
while
(
this
.
state
.
on
()
&&
this
.
selfId
)
{
log
.
silly
(
'
PuppetPadchatBridge
'
,
`syncContactsAndRooms() while()`
)
const
syncContactList
=
await
this
.
padchatRpc
.
WXSyncContact
()
...
...
@@ -375,29 +401,27 @@ export class Bridge extends EventEmitter {
),
)
syncContactList
.
forEach
(
syncContact
=>
{
for
(
const
syncContact
of
syncContactList
)
{
if
(
syncContact
.
continue
===
PadchatContinue
.
Go
)
{
if
(
syncContact
.
msg_type
===
PadchatContactMsgType
.
Contact
)
{
console
.
log
(
'
syncContact:
'
,
syncContact
.
user_name
,
syncContact
.
nick_name
)
if
(
pfHelper
.
isRoomId
(
syncContact
.
user_name
))
{
// /@chatroom$/.test(syncContact.user_name)) {
this
.
cacheRoomRawPayload
[
syncContact
.
user_name
]
=
syncContact
as
PadchatRoomPayload
// syncRoomMap.set(syncContact.user_name, syncContact as PadchatRoomPayload)
}
else
if
(
syncContact
.
user_name
)
{
}
else
if
(
pfHelper
.
isContactId
(
syncContact
.
user_name
)
)
{
this
.
cacheContactRawPayload
[
syncContact
.
user_name
]
=
syncContact
as
PadchatContactPayload
// syncContactMap.set(syncContact.user_name, syncContact as PadchatContactPayload)
}
else
{
throw
new
Error
(
'
no user_name
'
)
throw
new
Error
(
'
id is neither room nor contact
'
)
}
}
}
else
{
log
.
info
(
'
PuppetPadchatBridge
'
,
'
syncContactsAndRooms() sync contact done!
'
)
cont
=
false
return
log
.
verbose
(
'
PuppetPadchatBridge
'
,
'
syncContactsAndRooms() sync contact done!
'
)
break
}
})
log
.
silly
(
'
PuppetPadchatBridge
'
,
`syncContactsAndRooms(), continue to load via WXSyncContact ...`
)
}
log
.
verbose
(
'
PuppetPadchatBridge
'
,
`syncContactsAndRooms(), continue to load via WXSyncContact ...`
)
}
// contactIdList = contactIdList.filter(id => !!id)
...
...
src/puppet-padchat/padchat-rpc.ts
浏览文件 @
cbd3ff0b
...
...
@@ -12,6 +12,8 @@ import {
// JsonRpcPayloadError,
// JsonRpcParamsSchemaByName,
JsonRpcParamsSchemaByPositional
,
parse
,
}
from
'
json-rpc-peer
'
// import { MemoryCard } from 'memory-card'
...
...
@@ -83,23 +85,36 @@ export class PadchatRpc extends EventEmitter {
await
this
.
initWebSocket
()
await
this
.
initJsonRpcPeer
()
await
this
.
init
()
await
this
.
WXInitialize
()
}
protected
async
initJsonRpcPeer
():
Promise
<
void
>
{
log
.
verbose
(
'
PadchatRpc
'
,
'
initJsonRpcPeer()
'
)
if
(
!
this
.
socket
)
{
throw
new
Error
(
'
socket had not been opened yet!
'
)
}
this
.
jsonRpc
.
on
(
'
data
'
,
(
payload
:
JsonRpcPayloadRequest
)
=>
{
this
.
jsonRpc
.
on
(
'
data
'
,
(
buffer
:
string
|
Buffer
)
=>
{
log
.
silly
(
'
PadchatRpc
'
,
'
initJsonRpcPeer() jsonRpc.on(data)
'
)
if
(
!
this
.
socket
)
{
throw
new
Error
(
'
no web socket
'
)
}
console
.
log
(
'
jsonRpc.on(data) =
'
,
payload
.
type
,
'
,
'
,
typeof
payload
,
'
:
'
,
payload
)
const
text
=
String
(
buffer
)
const
payload
=
parse
(
text
)
as
JsonRpcPayloadRequest
log
.
silly
(
'
PadchatRpc
'
,
'
initJsonRpcPeer() jsonRpc.on(data) buffer="%s"
'
,
text
)
/**
* A Gateway at here:
*
* 1. Convert Payload format from JsonRpc to Padchat, then
* 2. Send payload to padchat server
*
*/
const
encodedParam
=
(
payload
.
params
as
JsonRpcParamsSchemaByPositional
).
map
(
encodeURIComponent
)
const
message
:
PadchatRpcRequest
=
{
...
...
@@ -109,6 +124,8 @@ export class PadchatRpc extends EventEmitter {
param
:
encodedParam
,
}
log
.
silly
(
'
PadchatRpc
'
,
'
initJsonRpcPeer() jsonRpc.on(data) converted to padchat payload="%s"
'
,
JSON
.
stringify
(
message
))
this
.
socket
.
send
(
JSON
.
stringify
(
message
))
})
}
...
...
@@ -215,12 +232,12 @@ export class PadchatRpc extends EventEmitter {
// })
}
protected
onServer
(
payload
:
PadchatPayload
)
{
console
.
log
(
'
server payload:
'
,
payload
)
log
.
verbose
(
'
PuppetPadchatBridge
'
,
'
onWebSocket(%s)
'
,
JSON
.
stringify
(
payload
).
substr
(
0
,
140
),
log
.
verbose
(
'
PuppetPadchatBridge
'
,
'
onServer(payload.length=%d)
'
,
JSON
.
stringify
(
payload
).
length
,
)
// console.log('server payload:', payload)
// check logout:
if
(
payload
.
type
===
PadchatPayloadType
.
Logout
)
{
// this.emit('logout', this.selfId())
...
...
@@ -282,42 +299,46 @@ export class PadchatRpc extends EventEmitter {
})
}
protected
onServerPadchat
(
payload
:
PadchatPayload
)
{
console
.
log
(
'
onServerMessagePadChat:
'
,
payload
)
protected
onServerPadchat
(
padchatPayload
:
PadchatPayload
)
{
log
.
verbose
(
'
PuppetPadchatBridge
'
,
'
onServerPadchat({apiName="%s", msgId="%s", ...})
'
,
padchatPayload
.
apiName
,
padchatPayload
.
msgId
,
)
// padchatPayload:
// {
// "apiName": "WXHeartBeat",
// "data": "%7B%22status%22%3A0%2C%22message%22%3A%22ok%22%7D",
// "msgId": "abc231923912983",
// "userId": "test"
// }
log
.
silly
(
'
PuppetPadchatBridge
'
,
'
onServerPadchat(%s)
'
,
JSON
.
stringify
(
padchatPayload
).
substr
(
0
,
500
))
// check logout:
if
(
payload
.
type
===
PadchatPayloadType
.
Logout
)
{
if
(
pa
dchatPa
yload
.
type
===
PadchatPayloadType
.
Logout
)
{
// this.emit('logout', this.selfId())
this
.
emit
(
'
logout
'
)
}
log
.
silly
(
'
PuppetPadchatBridge
'
,
'
return apiName: %s, msgId: %s
'
,
payload
.
apiName
,
payload
.
msgId
)
let
result
:
any
if
(
payload
.
data
)
{
result
=
JSON
.
parse
(
decodeURIComponent
(
payload
.
data
))
if
(
pa
dchatPa
yload
.
data
)
{
result
=
JSON
.
parse
(
decodeURIComponent
(
pa
dchatPa
yload
.
data
))
}
else
{
log
.
silly
(
'
PuppetPadchatBridge
'
,
'
onServerMessagePadchat() discard empty payload.data for apiName: %s
'
,
payload
.
apiName
)
log
.
silly
(
'
PuppetPadchatBridge
'
,
'
onServerMessagePadchat() discard empty payload.data for apiName: %s
'
,
pa
dchatPa
yload
.
apiName
)
result
=
{}
}
const
jsonRpcResponse
:
JsonRpcPayloadResponse
=
{
id
:
payload
.
msgId
,
id
:
pa
dchatPa
yload
.
msgId
,
jsonrpc
:
'
2.0
'
,
result
:
result
,
type
:
'
response
'
,
}
this
.
jsonRpc
.
write
(
jsonRpcResponse
)
const
responseText
=
JSON
.
stringify
(
jsonRpcResponse
)
log
.
silly
(
'
PuppetPadchatBridge
'
,
'
onServerPadchat() converted to JsonRpc payload="%s"
'
,
responseText
.
substr
(
0
,
500
))
// rawWebSocketData:
// {
// "apiName": "WXHeartBeat",
// "data": "%7B%22status%22%3A0%2C%22message%22%3A%22ok%22%7D",
// "msgId": "abc231923912983",
// "userId": "test"
// }
this
.
jsonRpc
.
write
(
responseText
)
// if (resolverDict[msgId]) {
// const resolve = resolverDict[msgId]
...
...
src/puppet-padchat/puppet-padchat.ts
浏览文件 @
cbd3ff0b
...
...
@@ -141,32 +141,32 @@ export class PuppetPadchat extends Puppet {
// feed the dog, heartbeat the puppet.
// puppet.emit('heartbeat', food.data)
const
feedAfterTenSeconds
=
async
()
=>
{
this
.
bridge
.
WXHeartBeat
()
.
then
(()
=>
{
this
.
emit
(
'
watchdog
'
,
{
data
:
'
WXHeartBeat()
'
,
})
})
.
catch
(
e
=>
{
log
.
warn
(
'
PuppetPadchat
'
,
'
initWatchdogForPuppet() feedAfterTenSeconds rejected: %s
'
,
e
&&
e
.
message
||
''
)
})
}
setTimeout
(
feedAfterTenSeconds
,
15
*
1000
)
//
const feedAfterTenSeconds = async () => {
//
this.bridge.WXHeartBeat()
//
.then(() => {
//
this.emit('watchdog', {
//
data: 'WXHeartBeat()',
//
})
//
})
//
.catch(e => {
//
log.warn('PuppetPadchat', 'initWatchdogForPuppet() feedAfterTenSeconds rejected: %s', e && e.message || '')
//
})
//
}
//
setTimeout(feedAfterTenSeconds, 15 * 1000)
})
//
this.watchdog.on('reset', async (food, timeout) => {
//
log.warn('PuppetPadchat', 'initWatchdogForPuppet() dog.on(reset) last food:%s, timeout:%s',
//
food.data, timeout)
this
.
watchdog
.
on
(
'
reset
'
,
async
(
food
,
timeout
)
=>
{
log
.
warn
(
'
PuppetPadchat
'
,
'
initWatchdogForPuppet() dog.on(reset) last food:%s, timeout:%s
'
,
food
.
data
,
timeout
)
// try {
// await this.stop()
// await this.start()
// } catch (e) {
// puppet.emit('error', e)
// }
//
})
})
this
.
emit
(
'
watchdog
'
,
{
data
:
'
inited
'
,
...
...
src/wechaty.ts
浏览文件 @
cbd3ff0b
...
...
@@ -707,7 +707,7 @@ export class Wechaty extends Accessory implements Sayable {
await
this
.
puppet
.
start
()
}
catch
(
e
)
{
// console.log
(e)
console
.
error
(
e
)
log
.
error
(
'
Wechaty
'
,
'
start() exception: %s
'
,
e
&&
e
.
message
)
Raven
.
captureException
(
e
)
throw
e
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录