Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
weixin_46011646
wechaty
提交
e9c0e448
W
wechaty
项目概览
weixin_46011646
/
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,发现更多精彩内容 >>
未验证
提交
e9c0e448
编写于
6月 08, 2018
作者:
Huan (李卓桓)
提交者:
GitHub
6月 08, 2018
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'master' into puppet-0602
上级
f06dd19a
9c1347bd
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
122 addition
and
143 deletion
+122
-143
package.json
package.json
+1
-1
src/puppet-padchat/bridge.ts
src/puppet-padchat/bridge.ts
+70
-56
src/puppet-padchat/config.ts
src/puppet-padchat/config.ts
+1
-1
src/puppet-padchat/padchat-rpc.ts
src/puppet-padchat/padchat-rpc.ts
+45
-80
src/puppet-padchat/puppet-padchat.ts
src/puppet-padchat/puppet-padchat.ts
+2
-3
src/puppet-padchat/pure-function-helper.ts
src/puppet-padchat/pure-function-helper.ts
+3
-2
未找到文件。
package.json
浏览文件 @
e9c0e448
{
"name"
:
"wechaty"
,
"version"
:
"0.15.1
07
"
,
"version"
:
"0.15.1
10
"
,
"description"
:
"Wechat for Bot(Personal Account)"
,
"main"
:
"dist/src/index.js"
,
"typings"
:
"dist/src/index.d.ts"
,
...
...
src/puppet-padchat/bridge.ts
浏览文件 @
e9c0e448
...
...
@@ -74,8 +74,6 @@ export class Bridge extends EventEmitter {
// private password? : string
// private nickname? : string
// private loginSucceed = false
private
cacheRoomRawPayload
:
{
[
id
:
string
]:
PadchatRoomPayload
}
private
cacheContactRawPayload
:
{
[
id
:
string
]:
PadchatContactPayload
}
...
...
@@ -88,12 +86,12 @@ export class Bridge extends EventEmitter {
log
.
verbose
(
'
PuppetPadchatBridge
'
,
'
constructor()
'
)
// this.userId = options.token
this
.
cacheRoomRawPayload
=
{}
this
.
cacheRoomRawPayload
=
{}
this
.
cacheContactRawPayload
=
{}
this
.
autoData
=
{}
this
.
state
=
new
StateSwitch
(
'
PuppetPadchatBridge
'
)
this
.
autoData
=
{}
this
.
padchatRpc
=
new
PadchatRpc
(
options
.
endpoint
,
options
.
token
)
this
.
state
=
new
StateSwitch
(
'
PuppetPadchatBridge
'
)
}
public
async
start
():
Promise
<
void
>
{
...
...
@@ -103,7 +101,7 @@ export class Bridge extends EventEmitter {
this
.
cacheContactRawPayload
=
{}
if
(
this
.
selfId
)
{
throw
new
Error
(
'
username
exist
'
)
throw
new
Error
(
'
selfId
exist
'
)
}
this
.
state
.
on
(
'
pending
'
)
...
...
@@ -153,10 +151,11 @@ export class Bridge extends EventEmitter {
this
.
stopLogin
()
this
.
saveAutoData
()
this
.
selfId
=
username
this
.
emit
(
'
login
'
,
this
.
selfId
)
this
.
saveAutoData
(
this
.
selfId
)
}
public
logout
():
void
{
...
...
@@ -272,47 +271,59 @@ export class Bridge extends EventEmitter {
return
}
/**
* Offline, then relogin
* emit qrcode or send login request to the user.
*/
protected
async
restoreLogin
():
Promise
<
boolean
>
{
/**
* 1. The following `if/else` block: emit qrcode or send login request to the user.
*/
if
(
this
.
autoData
&&
this
.
autoData
.
token
)
{
log
.
silly
(
'
PuppetPadchatBridge
'
,
`initLogin() autoData.token exist for %s`
,
this
.
autoData
.
nick_name
||
'
no nick_name
'
,
)
// Offline, then relogin
const
autoLoginResult
=
await
this
.
padchatRpc
.
WXAutoLogin
(
this
.
autoData
.
token
)
if
(
autoLoginResult
)
{
if
(
autoLoginResult
.
status
===
0
)
{
/**
* 1.1 Auto Login Success, return username as the result
*/
this
.
login
(
autoLoginResult
.
user_name
)
return
true
log
.
verbose
(
'
PuppetPadchatBridge
'
,
`initLogin()`
)
}
else
{
/**
* 1.2. Send Login Request to User to be confirm(the same as the user had scaned the QrCode)
*/
const
loginRequestResult
=
await
this
.
padchatRpc
.
WXLoginRequest
(
this
.
autoData
.
token
)
if
(
!
loginRequestResult
||
loginRequestResult
.
status
!==
0
)
{
/**
* 1.2.1 Login Request Not Valid, emit QrCode for scan.
*/
await
this
.
emitLoginQrCode
()
}
}
}
else
{
if
(
!
this
.
autoData
||
!
this
.
autoData
.
token
)
{
return
false
}
log
.
silly
(
'
PuppetPadchatBridge
'
,
`initLogin() autoData.token exist for %s`
,
this
.
autoData
.
nick_name
||
'
no nick_name
'
,
)
const
autoLoginResult
=
await
this
.
padchatRpc
.
WXAutoLogin
(
this
.
autoData
.
token
)
if
(
!
autoLoginResult
)
{
/**
* 1. No Auto Login, emit QrCode for scan
*/
await
this
.
emitLoginQrCode
()
return
false
}
if
(
autoLoginResult
.
status
===
0
)
{
/**
* 2 Auto Login Success
*/
this
.
login
(
autoLoginResult
.
user_name
)
return
true
}
else
{
/**
* 3. Send Login Request to User to be confirm(the same as the user had scaned the QrCode)
*/
const
loginRequestResult
=
await
this
.
padchatRpc
.
WXLoginRequest
(
this
.
autoData
.
token
)
if
(
!
loginRequestResult
||
loginRequestResult
.
status
!==
0
)
{
/**
*
1.3. No Auto Login, emit QrCode for scan
*
3.1 Login Request Not Valid, emit QrCode for scan.
*/
await
this
.
padchatRpc
.
WXInitialize
()
await
this
.
emitLoginQrCode
()
return
false
}
else
{
/**
* 3.2 Login Request Valid, wait user to confirm on the phone.
*/
return
false
}
}
return
false
}
protected
async
emitLoginQrCode
():
Promise
<
void
>
{
...
...
@@ -324,8 +335,9 @@ export class Bridge extends EventEmitter {
const
result
=
await
this
.
padchatRpc
.
WXGetQRCode
()
if
(
!
result
)
{
// if fail, do we need to await this.WXInitialize() again???
throw
new
Error
(
'
waitLogin() WXGetQrCode() return nothing
'
)
log
.
verbose
(
'
PuppetPadchatBridge
'
,
`emitLoginQrCode() result not found. Call WXInitialize() and try again ...`
)
await
this
.
padchatRpc
.
WXInitialize
()
return
await
this
.
emitLoginQrCode
()
}
const
qrCodeText
=
await
pfHelper
.
imageBase64ToQrCode
(
result
.
qr_code
)
...
...
@@ -341,15 +353,22 @@ export class Bridge extends EventEmitter {
}
protected
async
saveAutoData
():
Promise
<
void
>
{
log
.
verbose
(
'
PuppetPadchatBridge
'
,
`loadAutoData()`
)
protected
async
saveAutoData
(
selfId
:
string
):
Promise
<
void
>
{
log
.
verbose
(
'
PuppetPadchatBridge
'
,
`loadAutoData(%s)`
,
selfId
)
await
this
.
padchatRpc
.
WXHeartBeat
()
if
(
!
this
.
autoData
.
wxData
||
this
.
autoData
.
user_name
!==
selfId
)
{
log
.
verbose
(
'
PuppetPadchatBridge
'
,
`loadAutoData() user_name(%s) !== selfId(%s)`
,
this
.
autoData
.
user_name
,
selfId
,
)
this
.
autoData
.
wxData
=
(
await
this
.
padchatRpc
.
WXGenerateWxDat
()).
data
}
// Check 62 data. If has then use, or save 62 data here.
this
.
autoData
.
token
=
(
await
this
.
padchatRpc
.
WXGetLoginToken
()).
token
// TODO: should not WXGenerateWxDat immediately, check user_name
this
.
autoData
.
wxData
=
(
await
this
.
padchatRpc
.
WXGenerateWxDat
()).
data
if
(
!
this
.
autoData
.
user_name
||
!
this
.
autoData
.
wxData
||
!
this
.
autoData
.
token
)
{
throw
new
Error
(
'
autoData error
'
)
}
...
...
@@ -368,7 +387,7 @@ export class Bridge extends EventEmitter {
// Check for 62 data, if has, then use WXLoadWxDat
// TODO: should check this.autoData.user_name here
if
(
this
.
autoData
.
wxData
)
{
log
.
silly
(
'
PuppetPadchatBridge
'
,
`
start(), get
62 data`
)
log
.
silly
(
'
PuppetPadchatBridge
'
,
`
loadAutoData() load
62 data`
)
await
this
.
padchatRpc
.
WXLoadWxDat
(
this
.
autoData
.
wxData
)
}
}
...
...
@@ -538,8 +557,8 @@ export class Bridge extends EventEmitter {
return
rawPayload
}
public
async
ding
(
data
:
string
):
Promise
<
string
>
{
const
result
=
await
this
.
padchatRpc
.
WXHeartBeat
(
data
)
public
async
ding
():
Promise
<
string
>
{
const
result
=
await
this
.
padchatRpc
.
WXHeartBeat
()
return
result
.
message
}
...
...
@@ -583,9 +602,4 @@ export class Bridge extends EventEmitter {
public
async
WXAddUser
(
strangerV1
:
string
,
strangerV2
:
string
,
type
:
string
,
verify
:
string
):
Promise
<
void
>
{
await
this
.
padchatRpc
.
WXAddUser
(
strangerV1
,
strangerV2
,
type
,
verify
)
}
public
async
WXHeartBeat
(
data
=
'
ding
'
):
Promise
<
string
>
{
const
result
=
await
this
.
padchatRpc
.
WXHeartBeat
(
data
)
return
result
.
message
}
}
src/puppet-padchat/config.ts
浏览文件 @
e9c0e448
export
const
WECHATY_PUPPET_PADCHAT_ENDPOINT
=
process
.
env
[
'
WECHATY_PUPPET_PADCHAT_ENDPOINT
'
]
||
'
ws://
101.132.129.155
:9091/wx
'
export
const
WECHATY_PUPPET_PADCHAT_ENDPOINT
=
process
.
env
[
'
WECHATY_PUPPET_PADCHAT_ENDPOINT
'
]
||
'
ws://
54.223.36.77
:9091/wx
'
export
const
WECHATY_PUPPET_PADCHAT_TOKEN
=
process
.
env
[
'
WECHATY_PUPPET_PADCHAT_TOKEN
'
]
||
'
padchattest
'
src/puppet-padchat/padchat-rpc.ts
浏览文件 @
e9c0e448
...
...
@@ -65,14 +65,10 @@ import {
import
{
log
}
from
'
../config
'
// const AUTO_DATA_SLOT = 'autoData'
export
class
PadchatRpc
extends
EventEmitter
{
private
socket
?
:
WebSocket
private
readonly
jsonRpc
:
any
// Peer
// private readonly rpcPromiseWaittingDict: PadChatRpcPromiseDict
constructor
(
protected
endpoint
:
string
,
protected
token
:
string
,
...
...
@@ -87,20 +83,21 @@ export class PadchatRpc extends EventEmitter {
log
.
verbose
(
'
PadchatRpc
'
,
'
start()
'
)
await
this
.
initWebSocket
()
await
this
.
initJsonRpcPeer
()
await
this
.
initJsonRpc
()
await
this
.
init
()
await
this
.
WXInitialize
()
}
protected
async
initJsonRpc
Peer
():
Promise
<
void
>
{
log
.
verbose
(
'
PadchatRpc
'
,
'
initJsonRpc
Peer
()
'
)
protected
async
initJsonRpc
():
Promise
<
void
>
{
log
.
verbose
(
'
PadchatRpc
'
,
'
initJsonRpc()
'
)
if
(
!
this
.
socket
)
{
throw
new
Error
(
'
socket had not been opened yet!
'
)
}
this
.
jsonRpc
.
on
(
'
data
'
,
(
buffer
:
string
|
Buffer
)
=>
{
log
.
silly
(
'
PadchatRpc
'
,
'
initJsonRpc
Peer
() jsonRpc.on(data)
'
)
log
.
silly
(
'
PadchatRpc
'
,
'
initJsonRpc() jsonRpc.on(data)
'
)
if
(
!
this
.
socket
)
{
throw
new
Error
(
'
no web socket
'
)
...
...
@@ -109,7 +106,7 @@ export class PadchatRpc extends EventEmitter {
const
text
=
String
(
buffer
)
const
payload
=
parse
(
text
)
// as JsonRpcPayloadRequest
log
.
silly
(
'
PadchatRpc
'
,
'
initJsonRpc
Peer
() jsonRpc.on(data) buffer="%s"
'
,
text
)
log
.
silly
(
'
PadchatRpc
'
,
'
initJsonRpc() jsonRpc.on(data) buffer="%s"
'
,
text
)
/**
* A Gateway at here:
...
...
@@ -128,7 +125,7 @@ export class PadchatRpc extends EventEmitter {
param
:
encodedParam
,
}
log
.
silly
(
'
PadchatRpc
'
,
'
initJsonRpc
Peer
() jsonRpc.on(data) converted to padchat payload="%s"
'
,
JSON
.
stringify
(
message
))
log
.
silly
(
'
PadchatRpc
'
,
'
initJsonRpc() jsonRpc.on(data) converted to padchat payload="%s"
'
,
JSON
.
stringify
(
message
))
this
.
socket
.
send
(
JSON
.
stringify
(
message
))
})
...
...
@@ -152,7 +149,7 @@ export class PadchatRpc extends EventEmitter {
log
.
silly
(
'
PadchatRpc
'
,
'
initWebSocket() ws.on(message)
'
)
try
{
const
payload
:
PadchatPayload
=
JSON
.
parse
(
data
)
this
.
onS
erver
(
payload
)
this
.
onS
ocket
(
payload
)
}
catch
(
e
)
{
log
.
warn
(
'
PadchatRpc
'
,
'
startJsonRpc() ws.on(message) exception: %s
'
,
e
)
this
.
emit
(
'
error
'
,
e
)
...
...
@@ -191,54 +188,11 @@ export class PadchatRpc extends EventEmitter {
apiName
:
string
,
...
params
:
string
[]
):
Promise
<
any
>
{
log
.
silly
(
'
PadchatRpc
'
,
'
rpcCall(%s, %s)
'
,
apiName
,
params
.
join
(
'
,
'
))
return
await
this
.
jsonRpc
.
request
(
apiName
,
params
)
// if (!this.socket) {
// throw new Error('no web socket')
// }
// const msgId = cuid()
// const paramEncodedList = params.map(
// arg => encodeURIComponent(arg),
// )
// const request: PadchatRpcRequest = {
// userId: this.token,
// msgId,
// apiName,
// param: paramEncodedList,
// }
// const payload = JSON.stringify(request)
// log.silly('PadchatRpc', 'sendToWebSocket: %s', payload)
// this.socket.send(payload)
// return new Promise((resolve, reject) => {
// const timer = setTimeout(() => {
// delete this.rpcPromiseWaittingDict[msgId]
// reject('PadChat Server timeout for msgId: ' + msgId + ', apiName: ' + apiName + ', args: ' + params.join(', '))
// // TODO: send json again or detect init()
// }, 30000)
// this.rpcPromiseWaittingDict[msgId] = {
// resolver: (...args: any[]) => {
// delete this.rpcPromiseWaittingDict[msgId]
// clearTimeout(timer)
// resolve(...args)
// },
// reject: (...args: any[]) => {
// delete this.rpcPromiseWaittingDict[msgId]
// clearTimeout(timer)
// reject(...args)
// },
// }
// })
}
protected
onServer
(
payload
:
PadchatPayload
)
{
protected
onSocket
(
payload
:
PadchatPayload
)
{
log
.
verbose
(
'
PadchatRpc
'
,
'
onServer(payload.length=%d)
'
,
JSON
.
stringify
(
payload
).
length
,
)
...
...
@@ -259,26 +213,36 @@ export class PadchatRpc extends EventEmitter {
}
if
(
payload
.
msgId
)
{
// Data Return From WebSocket Client
this
.
onServerPadchat
(
payload
)
// 1. Padchat Payload
//
// padchatPayload:
// {
// "apiName": "WXHeartBeat",
// "data": "%7B%22status%22%3A0%2C%22message%22%3A%22ok%22%7D",
// "msgId": "abc231923912983",
// "userId": "test"
// }
this
.
onSocketPadchat
(
payload
)
}
else
{
// Data From Tencent
// 2. Tencent Payload
//
// messagePayload:
// {
// "apiName": "",
// "data": "XXXX",
// "msgId": "",
// "userId": "test"
// }
const
tencentPayloadList
:
PadchatMessagePayload
[]
=
JSON
.
parse
(
decodeURIComponent
(
payload
.
data
))
this
.
onS
erver
Tencent
(
tencentPayloadList
)
this
.
onS
ocket
Tencent
(
tencentPayloadList
)
}
}
protected
onS
erver
Tencent
(
messagePayloadList
:
PadchatMessagePayload
[])
{
protected
onS
ocket
Tencent
(
messagePayloadList
:
PadchatMessagePayload
[])
{
console
.
log
(
'
tencent messagePayloadList:
'
,
messagePayloadList
)
// if ( payload.continue === PadchatContinue.Done
// && payload.msg_type === PadchatMsgType.N15_32768
// && payload.status === PadchatStatus.One
// ) {
// // Skip empty message. "continue":0,"msg_type":32768,"status":1,"
// return
// }
//
rawWebSocketData
:
//
messagePayload
:
// {
// "apiName": "",
// "data": "XXXX",
...
...
@@ -286,6 +250,14 @@ export class PadchatRpc extends EventEmitter {
// "userId": "test"
// }
// if ( payload.continue === PadchatContinue.Done
// && payload.msg_type === PadchatMsgType.N15_32768
// && payload.status === PadchatStatus.One
// ) {
// // Skip empty message. "continue":0,"msg_type":32768,"status":1,"
// return
// }
// if (!payload.data) {
// console.error('data: no payload.data')
// return
...
...
@@ -306,18 +278,11 @@ export class PadchatRpc extends EventEmitter {
}
}
protected
onS
erver
Padchat
(
padchatPayload
:
PadchatPayload
)
{
protected
onS
ocket
Padchat
(
padchatPayload
:
PadchatPayload
)
{
log
.
verbose
(
'
PadchatRpc
'
,
'
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
(
'
PadchatRpc
'
,
'
onServerPadchat(%s)
'
,
JSON
.
stringify
(
padchatPayload
).
substr
(
0
,
500
))
// check logout:
...
...
@@ -410,8 +375,8 @@ export class PadchatRpc extends EventEmitter {
return
result
}
public
async
WXHeartBeat
(
data
:
string
):
Promise
<
WXHeartBeatType
>
{
const
result
=
await
this
.
rpcCall
(
'
WXHeartBeat
'
,
data
)
public
async
WXHeartBeat
():
Promise
<
WXHeartBeatType
>
{
const
result
=
await
this
.
rpcCall
(
'
WXHeartBeat
'
)
log
.
silly
(
'
PadchatRpc
'
,
'
WXHeartBeat result: %s
'
,
JSON
.
stringify
(
result
))
if
(
!
result
||
result
.
status
!==
0
)
{
throw
Error
(
'
WXHeartBeat error! canot get result from websocket server
'
)
...
...
src/puppet-padchat/puppet-padchat.ts
浏览文件 @
e9c0e448
...
...
@@ -115,7 +115,6 @@ export class PuppetPadchat extends Puppet {
memory
:
this
.
options
.
memory
,
token
:
WECHATY_PUPPET_PADCHAT_TOKEN
,
endpoint
:
WECHATY_PUPPET_PADCHAT_ENDPOINT
,
// profile: profile, // should be profile in the future
})
}
...
...
@@ -263,7 +262,7 @@ export class PuppetPadchat extends Puppet {
this
.
emit
(
'
logout
'
,
this
.
id
)
// becore we will throw above by logonoff() when this.user===undefined
this
.
id
=
undefined
// TODO: this.bridge.logout
await
this
.
bridge
.
logout
()
}
/**
...
...
@@ -381,7 +380,7 @@ export class PuppetPadchat extends Puppet {
log
.
verbose
(
'
PuppetPadchat
'
,
'
messageSend(%s, %s)
'
,
receiver
,
text
)
const
id
=
receiver
.
contactId
||
receiver
.
roomId
if
(
!
id
)
{
throw
Error
(
'
N
o id
'
)
throw
Error
(
'
n
o id
'
)
}
await
this
.
bridge
.
WXSendMsg
(
id
,
text
)
}
...
...
src/puppet-padchat/pure-function-helper.ts
浏览文件 @
e9c0e448
...
...
@@ -116,7 +116,8 @@ export class PadchatPureFunctionHelper {
switch
(
rawPayload
.
sub_type
)
{
case
PadchatMessageType
.
Sys
:
// fall down
case
PadchatMessageType
.
StatusNotify
:
// fall down
case
PadchatMessageType
.
Sys
:
// fall down
case
PadchatMessageType
.
Text
:
type
=
MessageType
.
Text
break
...
...
@@ -142,7 +143,7 @@ export class PadchatPureFunctionHelper {
break
default
:
throw
new
Error
(
'
unsupported type
'
)
throw
new
Error
(
'
unsupported type
:
'
+
PadchatMessageType
[
rawPayload
.
sub_type
]
+
'
(
'
+
rawPayload
.
sub_type
+
'
)
'
)
}
const
payloadBase
=
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录