Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
weixin_46011646
wechaty
提交
64e69f73
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,体验更适合开发者的 AI 搜索 >>
提交
64e69f73
编写于
10月 12, 2016
作者:
Huan (李卓桓)
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
#40 more types, bug fixes, async/await
上级
2c1e4d3b
变更
11
隐藏空白更改
内联
并排
Showing
11 changed file
with
212 addition
and
213 deletion
+212
-213
README.md
README.md
+2
-2
example/room-bot.ts
example/room-bot.ts
+9
-4
src/config.ts
src/config.ts
+14
-5
src/event-scope.ts
src/event-scope.ts
+10
-12
src/io-client.ts
src/io-client.ts
+4
-4
src/io.ts
src/io.ts
+79
-63
src/message.ts
src/message.ts
+6
-6
src/puppet-web/firer.ts
src/puppet-web/firer.ts
+58
-95
src/puppet-web/puppet-web.ts
src/puppet-web/puppet-web.ts
+11
-8
src/room.ts
src/room.ts
+9
-4
src/wechaty.ts
src/wechaty.ts
+10
-10
未找到文件。
README.md
浏览文件 @
64e69f73
...
...
@@ -16,7 +16,7 @@ Wechaty is a Bot Framework for Wechat **Personal** Account that help you easy cr
# ATTENTION
## Wechaty is just converted
from Javascript to Type
script.
## Wechaty is just converted
to Typescript from Java
script.
Details: https://github.com/wechaty/wechaty/issues/40
...
...
@@ -25,7 +25,7 @@ Details: https://github.com/wechaty/wechaty/issues/40
- Please do not clone/pull until you are really want to play with typescript wechaty in alpha stage.
```
The last
j
avascript version is:
[
v0.4.0
](
https://github.com/wechaty/wechaty/releases/tag/v0.4.0
)
(
2016/10/9
)
The last
J
avascript version is:
[
v0.4.0
](
https://github.com/wechaty/wechaty/releases/tag/v0.4.0
)
(
2016/10/9
)
Or install v0.4 via
`npm install wechaty`
...
...
example/room-bot.ts
浏览文件 @
64e69f73
...
...
@@ -60,7 +60,7 @@ console.log(welcome)
const
bot
=
Wechaty
.
instance
({
profile
:
Config
.
DEFAULT_PROFILE
})
bot
.
on
(
'
scan
'
,
(
{
url
,
code
}
)
=>
{
.
on
(
'
scan
'
,
(
url
,
code
)
=>
{
console
.
log
(
`Use Wechat to Scan QR Code in url to login:
${
code
}
\n
${
url
}
`
)
})
.
on
(
'
logout
'
,
user
=>
log
.
info
(
'
Bot
'
,
`
${
user
.
name
()}
logouted`
))
...
...
@@ -87,7 +87,7 @@ bot
,
room
.
topic
()
,
Array
.
isArray
(
invitee
)
?
invitee
.
map
(
c
=>
c
.
name
()).
join
(
'
,
'
)
:
invitee
:
invitee
.
name
()
,
inviter
.
name
()
)
})
...
...
@@ -232,7 +232,12 @@ function manageDingRoom() {
* Event: Join
*/
room
.
on
(
'
join
'
,
(
invitee
:
Contact
|
Contact
[],
inviter
:
Contact
)
=>
{
log
.
verbose
(
'
Bot
'
,
'
Room EVENT: join - %s, %s
'
,
typeof
invitee
,
typeof
inviter
)
log
.
verbose
(
'
Bot
'
,
'
Room EVENT: join - %s, %s
'
,
Array
.
isArray
(
invitee
)
?
invitee
.
map
(
c
=>
c
.
name
()).
join
(
'
,
'
)
:
invitee
.
name
()
,
inviter
.
name
()
)
checkRoomJoin
.
call
(
this
,
room
,
invitee
,
inviter
)
})
...
...
@@ -318,7 +323,7 @@ function checkRoomJoin(room: Room, invitee: Contact|Contact[] , inviter: Contact
}
}
catch
(
e
)
{
log
.
error
(
'
room join event
exception: %s
'
,
e
.
stack
)
log
.
error
(
'
Bot
'
,
'
checkRoomJoin()
exception: %s
'
,
e
.
stack
)
}
}
...
...
src/config.ts
浏览文件 @
64e69f73
...
...
@@ -121,13 +121,22 @@ Config.puppetInstance = function(instance?: Puppet): Puppet {
type
WatchdogFood
=
{
data
:
any
,
type
?:
'
HEARTBEAT
'
|
'
POISON
'
|
'
SCAN
'
,
timeout
?:
number
// millisecond
,
type
?:
'
HEARTBEAT
'
|
'
POISON
'
|
'
SCAN
'
}
type
WechatyEventType
=
'
login
'
|
'
logout
'
|
'
friend
'
|
'
message
'
|
'
error
'
|
'
heartbeat
'
|
'
scan
'
|
'
room-join
'
|
'
room-leave
'
|
'
room-topic
'
type
WechatyEventName
=
'
error
'
|
'
friend
'
|
'
heartbeat
'
|
'
login
'
|
'
logout
'
|
'
message
'
|
'
room-join
'
|
'
room-leave
'
|
'
room-topic
'
|
'
scan
'
type
ScanInfo
=
{
url
:
string
...
...
@@ -141,5 +150,5 @@ export {
,
PuppetType
,
ScanInfo
,
WatchdogFood
,
WechatyEvent
Typ
e
,
WechatyEvent
Nam
e
}
src/event-scope.ts
浏览文件 @
64e69f73
...
...
@@ -10,23 +10,21 @@
* Events Function Wrapper
*
*/
import
Config
from
'
./config
'
import
Contact
from
'
./contact
'
import
Message
from
'
./message
'
import
Room
from
'
./room
'
import
Wechaty
from
'
./wechaty
'
import
{
Config
,
WechatyEventName
}
from
'
./config
'
import
Contact
from
'
./contact
'
import
Message
from
'
./message
'
import
Room
from
'
./room
'
import
Wechaty
from
'
./wechaty
'
import
log
from
'
./brolog-env
'
import
log
from
'
./brolog-env
'
type
WechatyEventScope
=
{
say
:
(
content
:
string
,
replyTo
?:
Contact
|
Contact
[])
=>
void
}
type
WechatyEventType
=
'
error
'
|
'
heartbeat
'
|
'
login
'
|
'
logout
'
|
'
message
'
|
'
scan
'
|
'
friend
'
|
'
room-join
'
|
'
room-leave
'
|
'
room-topic
'
const
EVENT_CONFIG
=
{
error
:
wrapFilehelper
,
friend
:
wrapFilehelper
...
...
@@ -45,7 +43,7 @@ class EventScope {
return
Object
.
keys
(
EVENT_CONFIG
)
}
public
static
wrap
(
this
:
Wechaty
|
Room
,
event
:
WechatyEvent
Typ
e
,
listener
:
Function
):
Function
{
public
static
wrap
(
this
:
Wechaty
|
Room
,
event
:
WechatyEvent
Nam
e
,
listener
:
Function
):
Function
{
log
.
verbose
(
'
WechatyEvent
'
,
'
wrap(%s, %s)
'
,
event
,
typeof
listener
)
if
(
typeof
listener
!==
'
function
'
)
{
...
...
src/io-client.ts
浏览文件 @
64e69f73
...
...
@@ -109,10 +109,10 @@ class IoClient {
const
wechaty
=
this
.
wechaty
wechaty
.
on
(
'
login
'
,
user
=>
this
.
log
.
info
(
'
IoClient
'
,
`
${
user
.
name
()}
logined`
))
.
on
(
'
logout
'
,
user
=>
this
.
log
.
info
(
'
IoClient
'
,
`
${
user
.
name
()}
logouted`
))
.
on
(
'
scan
'
,
(
{
url
,
code
}
)
=>
this
.
log
.
info
(
'
IoClient
'
,
`[
${
code
}
]
${
url
}
`
))
.
on
(
'
message
'
,
message
=>
{
.
on
(
'
login
'
,
user
=>
this
.
log
.
info
(
'
IoClient
'
,
`
${
user
.
name
()}
logined`
))
.
on
(
'
logout
'
,
user
=>
this
.
log
.
info
(
'
IoClient
'
,
`
${
user
.
name
()}
logouted`
))
.
on
(
'
scan
'
,
(
url
,
code
)
=>
this
.
log
.
info
(
'
IoClient
'
,
`[
${
code
}
]
${
url
}
`
))
.
on
(
'
message
'
,
message
=>
{
message
.
ready
()
.
then
(
this
.
onMessage
.
bind
(
this
))
.
catch
(
e
=>
this
.
log
.
error
(
'
IoClient
'
,
'
message.ready() %s
'
,
e
))
...
...
src/io.ts
浏览文件 @
64e69f73
...
...
@@ -13,10 +13,11 @@
import
*
as
WebSocket
from
'
ws
'
// const co = require('co')
import
Config
,
{
WechatyEventType
}
from
'
./config
'
import
Contact
from
'
./contact
'
import
{
Config
// WechatyEventName
}
from
'
./config
'
import
Wechaty
from
'
./wechaty
'
import
log
from
'
./brolog-env
'
...
...
@@ -27,8 +28,18 @@ type IoSetting = {
protocol
?:
string
}
type
IoEventName
=
'
botie
'
|
'
error
'
|
'
heartbeat
'
|
'
login
'
|
'
message
'
|
'
raw
'
|
'
reset
'
|
'
scan
'
|
'
shutdown
'
type
IoEvent
=
{
name
:
string
name
:
IoEventName
payload
:
any
}
...
...
@@ -36,7 +47,7 @@ class Io {
public
uuid
:
string
private
protocol
:
string
private
_
eventBuffer
=
[]
private
eventBuffer
=
[]
private
ws
:
WebSocket
private
_currentState
:
string
...
...
@@ -206,7 +217,7 @@ class Io {
log
.
verbose
(
'
Io
'
,
'
on(report): %s
'
,
ioEvent
.
payload
)
const
user
=
this
.
setting
.
wechaty
.
user
()
if
(
user
)
{
const
loginEvent
=
{
const
loginEvent
:
IoEvent
=
{
name
:
'
login
'
// , payload: user.obj
,
payload
:
user
...
...
@@ -219,7 +230,7 @@ class Io {
&&
this
.
setting
.
wechaty
.
puppet
&&
this
.
setting
.
wechaty
.
puppet
[
'
scan
'
]
if
(
scan
)
{
const
scanEvent
=
{
const
scanEvent
:
IoEvent
=
{
name
:
'
scan
'
,
payload
:
scan
}
...
...
@@ -297,77 +308,82 @@ class Io {
wechaty
.
on
(
'
message
'
,
this
.
ioMessage
)
const
hookEvents
:
WechatyEventType
[]
=
[
'
scan
'
,
'
login
'
,
'
logout
'
,
'
heartbeat
'
,
'
error
'
]
hookEvents
.
map
(
event
=>
{
wechaty
.
on
(
event
,
data
=>
{
const
ioEvent
=
{
name
:
event
,
payload
:
data
}
switch
(
event
)
{
case
'
login
'
:
case
'
logout
'
:
if
(
data
instanceof
Contact
)
{
// ioEvent.payload = data.obj
ioEvent
.
payload
=
data
}
break
case
'
error
'
:
ioEvent
.
payload
=
data
.
toString
()
break
case
'
heartbeat
'
:
ioEvent
.
payload
=
{
uuid
:
this
.
uuid
,
data
:
data
}
break
wechaty
.
on
(
'
scan
'
,
(
url
,
code
)
=>
this
.
send
({
name
:
'
scan
'
,
payload
:
{
url
,
code
}
}))
wechaty
.
on
(
'
login
'
,
user
=>
this
.
send
({
name
:
'
login
'
,
payload
:
user
}))
wechaty
.
on
(
'
logout
'
,
user
=>
this
.
send
({
name
:
'
login
'
,
payload
:
user
}))
wechaty
.
on
(
'
heartbeat
'
,
data
=>
this
.
send
({
name
:
'
heartbeat
'
,
payload
:
{
uuid
:
this
.
uuid
,
data
}
}))
wechaty
.
on
(
'
error
'
,
error
=>
this
.
send
({
name
:
'
error
'
,
payload
:
error
}))
// const hookEvents: WechatyEventName[] = [
// 'scan'
// , 'login'
// , 'logout'
// , 'heartbeat'
// , 'error'
// ]
// hookEvents.map(event => {
// wechaty.on(event, (data) => {
// const ioEvent: IoEvent = {
// name: event
// , payload: data
// }
// switch (event) {
// case 'login':
// case 'logout':
// if (data instanceof Contact) {
// // ioEvent.payload = data.obj
// ioEvent.payload = data
// }
// break
// case 'error':
// ioEvent.payload = data.toString()
// break
// case 'heartbeat':
// ioEvent.payload = {
// uuid: this.uuid
// , data: data
// }
// break
// default:
// break
// }
// this.send(ioEvent)
// })
// })
default
:
break
}
false
&&
wechaty
.
on
(
'
message
'
,
m
=>
{
const
text
=
(
m
.
room
()
?
'
[
'
+
m
.
room
().
topic
()
+
'
]
'
:
''
)
+
'
<
'
+
m
.
from
().
name
()
+
'
>
'
+
'
:
'
+
m
.
toStringDigest
()
this
.
send
(
ioEvent
)
})
this
.
send
({
name
:
'
message
'
,
payload
:
text
})
})
// wechaty.on('message', m => {
// const text = (m.room() ? '['+m.room().name()+']' : '')
// + '<'+m.from().name()+'>'
// + ':' + m.toStringDigest()
// const messageEvent = {
// name: 'message'
// , payload: text
// }
// this.send(messageEvent)
// })
return
Promise
.
resolve
()
return
}
private
send
(
ioEvent
?:
IoEvent
)
{
if
(
ioEvent
)
{
log
.
silly
(
'
Io
'
,
'
send(%s: %s)
'
,
ioEvent
.
name
,
ioEvent
.
payload
)
this
.
_
eventBuffer
.
push
(
ioEvent
)
this
.
eventBuffer
.
push
(
ioEvent
)
}
else
{
log
.
silly
(
'
Io
'
,
'
send()
'
)
}
if
(
!
this
.
connected
())
{
log
.
verbose
(
'
Io
'
,
'
send() without a connected websocket, eventBuffer.length = %d
'
,
this
.
_
eventBuffer
.
length
)
log
.
verbose
(
'
Io
'
,
'
send() without a connected websocket, eventBuffer.length = %d
'
,
this
.
eventBuffer
.
length
)
return
false
}
while
(
this
.
_
eventBuffer
.
length
)
{
while
(
this
.
eventBuffer
.
length
)
{
this
.
ws
.
send
(
JSON
.
stringify
(
this
.
_
eventBuffer
.
shift
()
this
.
eventBuffer
.
shift
()
)
)
}
...
...
@@ -391,7 +407,7 @@ class Io {
// try to send IoEvents in buffer
this
.
send
()
this
.
_
eventBuffer
=
[]
this
.
eventBuffer
=
[]
if
(
this
.
reconnectTimer
)
{
clearTimeout
(
this
.
reconnectTimer
)
...
...
src/message.ts
浏览文件 @
64e69f73
...
...
@@ -6,11 +6,11 @@
* https://github.com/wechaty/wechaty
*
*/
import
Con
tact
from
'
./contact
'
import
Room
from
'
./room
'
import
UtilLib
from
'
./util-lib
'
import
Wechaty
from
'
./wechaty
'
import
log
from
'
./brolog-env
'
import
Con
fig
from
'
./config
'
import
Contact
from
'
./contact
'
import
Room
from
'
./room
'
import
UtilLib
from
'
./util-lib
'
import
log
from
'
./brolog-env
'
type
MessageRawObj
=
{
MsgId
:
string
...
...
@@ -274,7 +274,7 @@ class Message {
m
.
content
(
mentionList
+
'
'
+
content
)
}
return
Wechaty
.
i
nstance
()
return
Config
.
puppetI
nstance
()
.
send
(
m
)
}
...
...
src/puppet-web/firer.ts
浏览文件 @
64e69f73
...
...
@@ -111,7 +111,7 @@ function checkRoomJoin(content: string): [string[], string] {
throw
new
Error
(
'
checkRoomJoin() not found
'
)
}
const
[
,
inviter
,
inviteeStr
]
=
found
const
[
inviter
,
inviteeStr
]
=
[
found
[
1
],
found
[
2
]
]
// "凌" invited "庆次、小桔妹" to the group chat
const
inviteeList
=
inviteeStr
.
split
(
/、/
)
...
...
@@ -120,7 +120,7 @@ function checkRoomJoin(content: string): [string[], string] {
}
async
function
fireRoomJoin
(
m
:
Message
):
Promise
<
void
>
{
log
.
verbose
(
'
PuppetWebFirer
'
,
'
fireRoomJoin(
)
'
)
log
.
verbose
(
'
PuppetWebFirer
'
,
'
fireRoomJoin(
%s)
'
,
m
.
content
()
)
const
room
=
m
.
room
()
const
content
=
m
.
content
()
...
...
@@ -128,7 +128,8 @@ async function fireRoomJoin(m: Message): Promise<void> {
let
inviteeList
:
string
[],
inviter
:
string
try
{
[
inviteeList
,
inviter
]
=
checkRoomJoin
(
content
)
}
catch
(
e
)
{
// not a room join message
}
catch
(
e
)
{
// not a room join message
return
}
log
.
silly
(
'
PuppetWebFirer
'
,
'
fireRoomJoin() inviteeList: %s, inviter: %s
'
...
...
@@ -139,7 +140,6 @@ async function fireRoomJoin(m: Message): Promise<void> {
let
inviterContact
:
Contact
let
inviteeContactList
:
Contact
[]
=
[]
// co.call(this, function* () {
try
{
if
(
inviter
===
"
You've
"
)
{
inviterContact
=
Contact
.
load
(
this
.
userId
)
...
...
@@ -152,57 +152,59 @@ async function fireRoomJoin(m: Message): Promise<void> {
// max = (2*totalTime/backoff) ^ (1/2)
// timeout = 11,250 for {max: 15, backoff: 100}
await
retryPromise
({
max
:
max
,
backoff
:
backoff
},
attempt
=>
{
await
retryPromise
({
max
:
max
,
backoff
:
backoff
},
a
sync
a
ttempt
=>
{
log
.
silly
(
'
PuppetWebFirer
'
,
'
fireRoomJoin() retryPromise() attempt %d with timeout %d
'
,
attempt
,
timeout
)
return
room
.
refresh
()
.
then
(
_
=>
{
let
iDone
,
allDone
=
true
for
(
let
i
in
inviteeList
)
{
iDone
=
inviteeContactList
[
i
]
instanceof
Contact
if
(
!
iDone
)
{
let
c
=
room
.
member
(
inviteeList
[
i
])
if
(
c
)
{
inviteeContactList
[
i
]
=
c
}
else
{
allDone
=
false
}
}
}
if
(
!
inviterContact
)
{
inviterContact
=
room
.
member
(
inviter
)
}
if
(
allDone
&&
inviterContact
)
{
log
.
silly
(
'
PuppetWebFirer
'
,
'
fireRoomJoin() resolve() inviteeContactList: %s, inviterContact: %s
'
,
inviteeContactList
.
map
((
c
:
Contact
)
=>
c
.
name
()).
join
(
'
,
'
)
,
inviterContact
.
name
()
)
return
Promise
.
resolve
()
}
else
{
log
.
silly
(
'
PuppetWebFirer
'
,
'
fireRoomJoin() reject() inviteeContactList: %s, inviterContact: %s
'
,
inviteeContactList
.
map
((
c
:
Contact
)
=>
c
.
name
()).
join
(
'
,
'
)
,
inviterContact
.
name
()
)
return
Promise
.
reject
(
'
not found(yet)
'
)
}
})
.
catch
(
e
=>
{
log
.
error
(
'
PuppetWebFirer
'
,
'
fireRoomJoin() retryPromise() room.refresh() rejected: %s
'
,
e
.
stack
)
throw
e
})
await
room
.
refresh
()
// .then(_ => {
let
iDone
,
allDone
=
true
for
(
let
i
in
inviteeList
)
{
iDone
=
inviteeContactList
[
i
]
instanceof
Contact
if
(
!
iDone
)
{
let
c
=
room
.
member
(
inviteeList
[
i
])
if
(
c
)
{
inviteeContactList
[
i
]
=
c
}
else
{
allDone
=
false
}
}
}
if
(
!
inviterContact
)
{
inviterContact
=
room
.
member
(
inviter
)
}
if
(
allDone
&&
inviterContact
)
{
log
.
silly
(
'
PuppetWebFirer
'
,
'
fireRoomJoin() resolve() inviteeContactList: %s, inviterContact: %s
'
,
inviteeContactList
.
map
((
c
:
Contact
)
=>
c
.
name
()).
join
(
'
,
'
)
,
inviterContact
.
name
()
)
return
}
throw
new
Error
(
'
not found(yet)
'
)
}).
catch
(
e
=>
{
log
.
silly
(
'
PuppetWebFirer
'
,
'
fireRoomJoin() reject() inviteeContactList: %s, inviterContact: %s
'
,
inviteeContactList
.
map
((
c
:
Contact
)
=>
c
.
name
()).
join
(
'
,
'
)
,
inviterContact
.
name
()
)
})
.
catch
(
e
=>
{
/* fail safe */
})
if
(
!
inviterContact
)
{
log
.
error
(
'
PuppetWebFirer
'
,
'
firmRoomJoin() inivter not found for %s
'
,
inviter
)
log
.
error
(
'
PuppetWebFirer
'
,
'
firmRoomJoin() inivter not found for %s
, `room-join` & `join` event will not fired
'
,
inviter
)
return
}
if
(
!
inviteeContactList
.
every
(
c
=>
c
instanceof
Contact
))
{
log
.
error
(
'
PuppetWebFirer
'
,
'
firmRoomJoin() inviteeList not all found for %s
'
,
inviteeContactList
.
join
(
'
,
'
))
log
.
error
(
'
PuppetWebFirer
'
,
'
firmRoomJoin() inviteeList not all found for %s , only part of them will in the `room-join` or `join` event
'
,
inviteeContactList
.
join
(
'
,
'
)
)
inviteeContactList
=
inviteeContactList
.
filter
(
c
=>
(
c
instanceof
Contact
))
if
(
inviteeContactList
.
length
<
1
)
{
log
.
error
(
'
PuppetWebFirer
'
,
'
firmRoomJoin() inviteeList empty. `room-join` & `join` event will not fired
'
)
return
}
}
await
Promise
.
all
(
inviteeContactList
.
map
(
c
=>
c
.
ready
()))
...
...
@@ -217,9 +219,8 @@ async function fireRoomJoin(m: Message): Promise<void> {
room
.
emit
(
'
join
'
,
inviteeContactList
,
inviterContact
)
}
// }).catch(e => {
}
catch
(
e
)
{
log
.
error
(
'
PuppetWebFirer
'
,
'
retryPromise() rejected
: %s
'
,
e
.
stack
)
log
.
error
(
'
PuppetWebFirer
'
,
'
exception
: %s
'
,
e
.
stack
)
}
return
...
...
@@ -232,64 +233,26 @@ function checkRoomLeave(content: string): string {
if
(
!
found
)
{
return
null
}
const
[,
leaver
]
=
found
return
leaver
return
found
[
1
]
// leaver
}
/**
* You removed "Bruce LEE" from the group chat
*/
async
function
fireRoomLeave
(
m
)
{
async
function
fireRoomLeave
(
m
:
Message
)
{
log
.
verbose
(
'
PuppetWebFirer
'
,
'
fireRoomLeave(%s)
'
,
m
.
content
())
const
leaver
=
checkRoomLeave
(
m
.
content
())
if
(
!
leaver
)
{
return
}
log
.
silly
(
'
PuppetWebFirer
'
,
'
fireRoomLeave() got leaver: %s
'
,
leaver
)
const
room
=
m
.
room
()
let
leaverContact
=
room
.
member
(
leaver
)
if
(
!
leaverContact
)
{
// co.call(this, function* () {
try
{
const
max
=
20
const
backoff
=
300
const
timeout
=
max
*
(
backoff
*
max
)
/
2
// 20 / 300 => 63,000
await
retryPromise
({
max
:
max
,
backoff
:
backoff
},
attempt
=>
{
log
.
silly
(
'
PuppetWebFirer
'
,
'
fireRoomLeave() retryPromise() attempt %d with timeout %d
'
,
attempt
,
timeout
)
return
room
.
refresh
()
.
then
(
_
=>
{
log
.
silly
(
'
PuppetWebFirer
'
,
'
leaver: %s
'
,
leaver
)
leaverContact
=
room
.
member
(
leaver
)
if
(
leaverContact
)
{
log
.
silly
(
'
PuppetWebFirer
'
,
'
fireRoomLeave() resolve() leaverContact: %s
'
,
leaverContact
)
return
Promise
.
resolve
(
leaverContact
)
}
else
{
log
.
silly
(
'
PuppetWebFirer
'
,
'
fireRoomLeave() reject() leaver: %s
'
,
leaver
)
return
Promise
.
reject
(
'
not found(yet)
'
)
}
})
.
catch
(
e
=>
{
log
.
error
(
'
PuppetWebFirer
'
,
'
fireRoomLeave() retryPromise() room.refresh() rejected: %s
'
,
e
&&
e
.
stack
||
e
)
throw
e
})
})
// }).catch(e => {
}
catch
(
e
)
{
log
.
error
(
'
PuppetWebFirer
'
,
'
fireRoomLeave() co exception: %s
'
,
e
&&
e
.
stack
||
e
)
}
}
if
(
!
leaverContact
)
{
log
.
error
(
'
PuppetWebFirer
'
,
'
fireRoomLeave() leaver not found for %s
'
,
leaver
)
log
.
error
(
'
PuppetWebFirer
'
,
'
fireRoomLeave() leaver %s not found, event `room-leave` & `leave` will not be fired
'
)
return
}
...
...
@@ -300,7 +263,7 @@ async function fireRoomLeave(m) {
await
room
.
refresh
()
}
function
checkRoomTopic
(
content
):
[
string
,
string
]
{
function
checkRoomTopic
(
content
:
string
):
[
string
,
string
]
{
const
re
=
regexConfig
.
roomTopic
const
found
=
content
.
match
(
re
)
...
...
@@ -311,7 +274,7 @@ function checkRoomTopic(content): [string, string] {
return
[
topic
,
changer
]
}
async
function
fireRoomTopic
(
m
)
{
async
function
fireRoomTopic
(
m
:
Message
)
{
let
topic
,
changer
try
{
[
topic
,
changer
]
=
checkRoomTopic
(
m
.
content
())
...
...
src/puppet-web/puppet-web.ts
浏览文件 @
64e69f73
...
...
@@ -291,13 +291,13 @@ class PuppetWeb extends Puppet {
return
this
.
user
}
public
send
(
message
)
{
const
to
=
message
.
get
(
'
to
'
)
const
room
=
message
.
get
(
'
room
'
)
public
send
(
message
:
Message
)
{
const
to
=
message
.
to
(
)
const
room
=
message
.
room
(
)
let
content
=
message
.
get
(
'
content
'
)
let
content
=
message
.
content
(
)
let
destination
=
to
let
destination
:
Contact
|
Room
=
to
if
(
room
)
{
destination
=
room
// TODO use the right @
...
...
@@ -306,12 +306,15 @@ class PuppetWeb extends Puppet {
// }
if
(
!
to
)
{
message
.
set
(
'
to
'
,
room
)
message
.
to
(
room
)
}
}
log
.
silly
(
'
PuppetWeb
'
,
`send() destination:
${
destination
}
, content:
${
content
}
)`
)
return
this
.
bridge
.
send
(
destination
,
content
)
log
.
silly
(
'
PuppetWeb
'
,
'
send() destination: %s, content: %s)
'
,
room
?
room
.
topic
()
:
to
.
name
()
,
content
)
return
this
.
bridge
.
send
(
destination
.
id
,
content
)
.
catch
(
e
=>
{
log
.
error
(
'
PuppetWeb
'
,
'
send() exception: %s
'
,
e
.
message
)
throw
e
...
...
src/room.ts
浏览文件 @
64e69f73
...
...
@@ -57,9 +57,9 @@ class Room extends EventEmitter {
// this.id = id
// this.obj = {}
// this.dirtyObj = {}
if
(
!
Config
.
puppetInstance
())
{
throw
new
Error
(
'
Config.puppetInstance() not found
'
)
}
//
if (!Config.puppetInstance()) {
//
throw new Error('Config.puppetInstance() not found')
//
}
}
public
toString
()
{
return
this
.
id
}
...
...
@@ -141,7 +141,12 @@ class Room extends EventEmitter {
}
public
say
(
content
:
string
,
replyTo
?:
Contact
|
Contact
[]):
Promise
<
any
>
{
log
.
verbose
(
'
Room
'
,
'
say(%s, %s)
'
,
content
,
replyTo
)
log
.
verbose
(
'
Room
'
,
'
say(%s, %s)
'
,
content
,
Array
.
isArray
(
replyTo
)
?
replyTo
.
map
(
c
=>
c
.
name
()).
join
(
'
,
'
)
:
replyTo
.
name
()
)
const
m
=
new
Message
()
m
.
room
(
this
)
...
...
src/wechaty.ts
浏览文件 @
64e69f73
...
...
@@ -8,22 +8,22 @@
* https://github.com/zixia/wechaty
*
*/
import
{
EventEmitter
}
from
'
events
'
import
*
as
path
from
'
path
'
// const co = require('co')
import
*
as
fs
from
'
fs
'
import
{
EventEmitter
}
from
'
events
'
import
*
as
path
from
'
path
'
import
*
as
fs
from
'
fs
'
import
Config
,
{
HeadType
import
{
Config
,
HeadType
,
PuppetType
,
WechatyEvent
Typ
e
}
from
'
./config
'
,
WechatyEvent
Nam
e
}
from
'
./config
'
import
Contact
from
'
./contact
'
import
FriendRequest
from
'
./friend-request
'
import
Message
from
'
./message
'
import
Puppet
from
'
./puppet
'
import
PuppetWeb
from
'
./puppet-web/
index
'
import
PuppetWeb
from
'
./puppet-web/
'
import
Room
from
'
./room
'
import
UtilLib
from
'
./util-lib
'
import
EventScope
from
'
./event-scope
'
...
...
@@ -167,7 +167,7 @@ class Wechaty extends EventEmitter {
public
on
(
event
:
'
room-topic
'
,
listener
:
(
room
:
Room
,
topic
:
string
,
oldTopic
:
string
,
changer
:
Contact
)
=>
void
):
this
public
on
(
event
:
'
scan
'
,
listener
:
(
url
:
string
,
code
:
number
)
=>
void
):
this
public
on
(
event
:
WechatyEvent
Typ
e
,
listener
:
Function
):
this
{
public
on
(
event
:
WechatyEvent
Nam
e
,
listener
:
Function
):
this
{
log
.
verbose
(
'
Wechaty
'
,
'
on(%s, %s)
'
,
event
,
typeof
listener
)
typeof
FriendRequest
typeof
Room
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录