Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
.Veneno.
wechaty
提交
5a9ba7ed
W
wechaty
项目概览
.Veneno.
/
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,发现更多精彩内容 >>
提交
5a9ba7ed
编写于
5月 20, 2018
作者:
Huan (李卓桓)
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
store puppet to the class static properti and add guard check (#1217)
上级
fbdc8005
变更
12
隐藏空白更改
内联
并排
Showing
12 changed file
with
226 addition
and
162 deletion
+226
-162
src/contact.spec.ts
src/contact.spec.ts
+52
-0
src/contact.ts
src/contact.ts
+12
-2
src/friend-request.ts
src/friend-request.ts
+15
-2
src/message.ts
src/message.ts
+19
-6
src/puppet-mock/puppet-mock.ts
src/puppet-mock/puppet-mock.ts
+6
-8
src/puppet-puppeteer/event.ts
src/puppet-puppeteer/event.ts
+4
-7
src/puppet-puppeteer/firer.ts
src/puppet-puppeteer/firer.ts
+4
-8
src/puppet-puppeteer/puppet-puppeteer.spec.ts
src/puppet-puppeteer/puppet-puppeteer.spec.ts
+1
-1
src/puppet-puppeteer/puppet-puppeteer.ts
src/puppet-puppeteer/puppet-puppeteer.ts
+11
-23
src/puppet/puppet.ts
src/puppet/puppet.ts
+15
-32
src/room.ts
src/room.ts
+21
-9
src/wechaty.ts
src/wechaty.ts
+66
-64
未找到文件。
src/contact.spec.ts
0 → 100755
浏览文件 @
5a9ba7ed
#!/usr/bin/env ts-node
import
*
as
test
from
'
blue-tape
'
// import * as sinon from 'sinon'
import
{
cloneClass
}
from
'
clone-class
'
import
{
Contact
}
from
'
./contact
'
test
(
'
Should not be able to instanciate directly
'
,
async
t
=>
{
t
.
throws
(()
=>
{
const
c
=
new
Contact
(
'
xxx
'
)
t
.
fail
(
c
.
name
())
},
'
should throw when `new Contact()`
'
)
t
.
throws
(()
=>
{
const
c
=
Contact
.
load
(
'
xxx
'
)
t
.
fail
(
c
.
name
())
},
'
should throw when `Contact.load()`
'
)
})
test
(
'
Should not be able to instanciate through cloneClass without puppet
'
,
async
t
=>
{
// tslint:disable-next-line:variable-name
const
MyContact
=
cloneClass
(
Contact
)
t
.
throws
(()
=>
{
const
c
=
new
MyContact
(
'
xxx
'
)
t
.
fail
(
c
.
name
())
},
'
should throw when `new MyContact()` without puppet
'
)
t
.
throws
(()
=>
{
const
c
=
MyContact
.
load
(
'
xxx
'
)
t
.
fail
(
c
.
name
())
},
'
should throw when `MyContact.load()` without puppet
'
)
})
test
(
'
Should be able to instanciate through cloneClass with puppet
'
,
async
t
=>
{
// tslint:disable-next-line:variable-name
const
MyContact
=
cloneClass
(
Contact
)
MyContact
.
puppet
=
{}
as
any
t
.
doesNotThrow
(()
=>
{
const
c
=
new
MyContact
(
'
xxx
'
)
t
.
ok
(
c
,
'
should get contact instance from `new MyContact()
'
)
},
'
should not throw when `new MyContact()`
'
)
t
.
doesNotThrow
(()
=>
{
const
c
=
MyContact
.
load
(
'
xxx
'
)
t
.
ok
(
c
,
'
should get contact instance from `MyContact.load()`
'
)
},
'
should not throw when `MyContact.load()`
'
)
})
src/contact.ts
浏览文件 @
5a9ba7ed
...
...
@@ -18,6 +18,7 @@
* @ignore
*/
import
{
FileBox
}
from
'
file-box
'
import
{
instanceToClass
}
from
'
clone-class
'
import
{
log
,
...
...
@@ -199,6 +200,17 @@ export class Contact extends PuppetAccessory implements Sayable {
)
{
super
()
log
.
silly
(
'
Contact
'
,
`constructor(
${
id
}
)`
)
// tslint:disable-next-line:variable-name
const
MyClass
=
instanceToClass
(
this
,
Contact
)
if
(
MyClass
===
Contact
)
{
throw
new
Error
(
'
Contact class can not be instanciated directly! See: https://github.com/Chatie/wechaty/issues/1217
'
)
}
if
(
!
this
.
puppet
)
{
throw
new
Error
(
'
Contact class can not be instanciated without a puppet!
'
)
}
}
/**
...
...
@@ -255,8 +267,6 @@ export class Contact extends PuppetAccessory implements Sayable {
throw
new
Error
(
'
unsupported
'
)
}
msg
.
puppet
=
this
.
puppet
log
.
silly
(
'
Contact
'
,
'
say() from: %s to: %s content: %s
'
,
this
.
puppet
.
userSelf
(),
this
,
...
...
src/friend-request.ts
浏览文件 @
5a9ba7ed
...
...
@@ -21,9 +21,11 @@
/* tslint:disable:no-var-requires */
const
retryPromise
=
require
(
'
retry-promise
'
).
default
import
PuppetAccessory
from
'
./puppet-accessory
'
import
{
instanceToClass
}
from
'
clone-class
'
import
Contact
from
'
./contact
'
import
{
PuppetAccessory
}
from
'
./puppet-accessory
'
import
{
Contact
}
from
'
./contact
'
import
{
log
,
...
...
@@ -121,6 +123,17 @@ export class FriendRequest extends PuppetAccessory {
)
{
super
()
log
.
verbose
(
'
PuppeteerFriendRequest
'
,
'
constructor(%s)
'
,
payload
)
// tslint:disable-next-line:variable-name
const
MyClass
=
instanceToClass
(
this
,
FriendRequest
)
if
(
MyClass
===
FriendRequest
)
{
throw
new
Error
(
'
FriendRequest class can not be instanciated directly! See: https://github.com/Chatie/wechaty/issues/1217
'
)
}
if
(
!
this
.
puppet
)
{
throw
new
Error
(
'
FriendRequest class can not be instanciated without a puppet!
'
)
}
}
public
async
send
():
Promise
<
void
>
{
...
...
src/message.ts
浏览文件 @
5a9ba7ed
...
...
@@ -21,7 +21,10 @@ import * as cuid from 'cuid'
import
{
FileBox
,
}
from
'
file-box
'
}
from
'
file-box
'
import
{
instanceToClass
,
}
from
'
clone-class
'
import
{
log
,
...
...
@@ -207,6 +210,17 @@ export class Message extends PuppetAccessory implements Sayable {
)
log
.
silly
(
'
Message
'
,
'
constructor()
'
)
// tslint:disable-next-line:variable-name
const
MyClass
=
instanceToClass
(
this
,
Message
)
if
(
MyClass
===
Message
)
{
throw
new
Error
(
'
Message class can not be instanciated directly! See: https://github.com/Chatie/wechaty/issues/1217
'
)
}
if
(
!
this
.
puppet
)
{
throw
new
Error
(
'
Message class can not be instanciated without a puppet!
'
)
}
// default set to MT because there's a id param
this
.
direction
=
MessageDirection
.
MT
}
...
...
@@ -408,7 +422,7 @@ export class Message extends PuppetAccessory implements Sayable {
/**
* File Message
*/
const
msg
=
Message
.
createMO
({
const
msg
=
this
.
puppet
.
Message
.
createMO
({
file
:
textOrFile
,
to
:
from
,
room
,
...
...
@@ -429,7 +443,7 @@ export class Message extends PuppetAccessory implements Sayable {
/**
* 1. to Individual
*/
msg
=
Message
.
createMO
({
msg
=
this
.
puppet
.
Message
.
createMO
({
to
,
text
,
})
...
...
@@ -443,7 +457,7 @@ export class Message extends PuppetAccessory implements Sayable {
*/
const
mentionContact
=
mentionList
[
0
]
const
textMentionList
=
mentionList
.
map
(
c
=>
'
@
'
+
c
.
name
()).
join
(
'
'
)
msg
=
Message
.
createMO
({
msg
=
this
.
puppet
.
Message
.
createMO
({
to
:
mentionContact
,
room
,
text
:
textMentionList
+
'
'
+
text
,
...
...
@@ -452,14 +466,13 @@ export class Message extends PuppetAccessory implements Sayable {
/**
* 2.2 did not mention anyone
*/
msg
=
Message
.
createMO
({
msg
=
this
.
puppet
.
Message
.
createMO
({
to
,
room
,
text
,
})
}
}
msg
.
puppet
=
this
.
puppet
await
this
.
puppet
.
messageSend
(
msg
)
}
...
...
src/puppet-mock/puppet-mock.ts
浏览文件 @
5a9ba7ed
...
...
@@ -25,7 +25,6 @@ import {
import
{
Message
,
MessagePayload
,
MessageDirection
,
}
from
'
../message
'
import
{
Contact
,
...
...
@@ -93,8 +92,8 @@ export class PuppetMock extends Puppet {
// await some tasks...
this
.
state
.
on
(
true
)
const
user
=
Contact
.
load
(
'
logined_user_id
'
)
const
msg
=
Message
.
createMT
(
'
mock_id
'
)
const
user
=
this
.
Contact
.
load
(
'
logined_user_id
'
)
const
msg
=
this
.
Message
.
createMT
(
'
mock_id
'
)
this
.
user
=
user
this
.
emit
(
'
login
'
,
user
)
...
...
@@ -200,11 +199,11 @@ export class PuppetMock extends Puppet {
log
.
verbose
(
'
PuppetMock
'
,
'
messagePayload(%s)
'
,
rawPayload
)
const
payload
:
MessagePayload
=
{
date
:
new
Date
(),
direction
:
Message
Direction
.
MT
,
from
:
Contact
.
load
(
'
xxx
'
),
direction
:
this
.
Message
.
Direction
.
MT
,
from
:
this
.
Contact
.
load
(
'
xxx
'
),
text
:
'
mock message text
'
,
to
:
this
.
userSelf
(),
type
:
Message
.
Type
.
Text
,
type
:
this
.
Message
.
Type
.
Text
,
}
return
payload
}
...
...
@@ -287,8 +286,7 @@ export class PuppetMock extends Puppet {
if
(
!
contactList
||
!
contactList
.
map
)
{
throw
new
Error
(
'
contactList not found
'
)
}
const
r
=
Room
.
load
(
'
mock room id
'
)
as
Room
r
.
puppet
=
this
const
r
=
this
.
Room
.
load
(
'
mock room id
'
)
as
Room
return
r
}
...
...
src/puppet-puppeteer/event.ts
浏览文件 @
5a9ba7ed
...
...
@@ -141,8 +141,7 @@ async function onLogin(
log
.
silly
(
'
PuppetPuppeteerEvent
'
,
'
bridge.getUserName: %s
'
,
userId
)
const
user
=
Contact
.
load
(
userId
)
user
.
puppet
=
this
const
user
=
this
.
Contact
.
load
(
userId
)
await
user
.
ready
()
log
.
silly
(
'
PuppetPuppeteerEvent
'
,
`onLogin() user
${
user
.
name
()}
logined`
)
...
...
@@ -191,8 +190,7 @@ async function onMessage(
this
:
PuppetPuppeteer
,
rawPayload
:
WebMessageRawPayload
,
):
Promise
<
void
>
{
let
msg
=
Message
.
createMT
(
rawPayload
.
MsgId
)
msg
.
puppet
=
this
let
msg
=
this
.
Message
.
createMT
(
rawPayload
.
MsgId
)
try
{
await
msg
.
ready
()
...
...
@@ -234,14 +232,13 @@ async function onMessage(
case
WebMsgType
.
MICROVIDEO
:
case
WebMsgType
.
APP
:
log
.
verbose
(
'
PuppetPuppeteerEvent
'
,
'
onMessage() EMOTICON/IMAGE/VIDEO/VOICE/MICROVIDEO message
'
)
msg
=
Message
.
createMT
(
rawPayload
.
MsgId
)
msg
.
puppet
=
this
msg
=
this
.
Message
.
createMT
(
rawPayload
.
MsgId
)
break
case
WebMsgType
.
TEXT
:
if
(
rawPayload
.
SubMsgType
===
WebMsgType
.
LOCATION
)
{
log
.
verbose
(
'
PuppetPuppeteerEvent
'
,
'
onMessage() (TEXT&LOCATION) message
'
)
msg
=
Message
.
createMT
(
rawPayload
.
MsgId
)
msg
=
this
.
Message
.
createMT
(
rawPayload
.
MsgId
)
}
break
}
...
...
src/puppet-puppeteer/firer.ts
浏览文件 @
5a9ba7ed
...
...
@@ -127,7 +127,7 @@ async function checkFriendRequest(
throw
new
Error
(
'
no recommendInfo
'
)
}
const
contact
=
Contact
.
load
(
recommendInfo
.
UserName
)
const
contact
=
this
.
Contact
.
load
(
recommendInfo
.
UserName
)
contact
.
puppet
=
this
const
hello
=
recommendInfo
.
Content
...
...
@@ -138,12 +138,11 @@ async function checkFriendRequest(
log
.
warn
(
'
PuppetPuppeteerFirer
'
,
'
fireFriendConfirm() contact still not ready after `ready()` call
'
)
}
const
receivedRequest
=
FriendRequest
.
createReceive
(
const
receivedRequest
=
this
.
FriendRequest
.
createReceive
(
contact
,
hello
,
ticket
,
)
receivedRequest
.
puppet
=
this
this
.
emit
(
'
friend
'
,
receivedRequest
)
}
...
...
@@ -179,10 +178,9 @@ async function checkFriendConfirm(
const
contact
=
m
.
from
()
const
confirmedRequest
=
FriendRequest
.
createConfirm
(
const
confirmedRequest
=
this
.
FriendRequest
.
createConfirm
(
contact
,
)
confirmedRequest
.
puppet
=
m
.
puppet
await
contact
.
ready
()
if
(
!
contact
.
isReady
())
{
...
...
@@ -416,8 +414,7 @@ async function checkRoomLeave(
// }
}
else
{
removerContact
=
Contact
.
load
(
this
.
userSelf
().
id
)
removerContact
.
puppet
=
m
.
puppet
removerContact
=
this
.
userSelf
()
// not sure which is better
// leaverContact = room.member({contactAlias: remover}) || room.member({name: leaver})
...
...
@@ -483,7 +480,6 @@ async function checkRoomTopic(
let
changerContact
:
Contact
|
null
if
(
/^You$/
.
test
(
changer
)
||
/^你$/
.
test
(
changer
))
{
changerContact
=
this
.
userSelf
()
changerContact
.
puppet
=
m
.
puppet
}
else
{
changerContact
=
room
.
member
(
changer
)
}
...
...
src/puppet-puppeteer/puppet-puppeteer.spec.ts
浏览文件 @
5a9ba7ed
...
...
@@ -81,7 +81,7 @@ test('login/logout events', sinonTest(async function (t: test.Test) {
})
t
.
ok
(
pw
,
'
should instantiated a PuppetPuppeteer
'
)
//
config.puppetInstance(pw)
//
FIXME: do not modify global instance
Contact
.
puppet
=
pw
await
pw
.
start
()
...
...
src/puppet-puppeteer/puppet-puppeteer.ts
浏览文件 @
5a9ba7ed
...
...
@@ -309,7 +309,7 @@ export class PuppetPuppeteer extends Puppet {
public
async
messageRawPayloadParser
(
rawPayload
:
WebMessageRawPayload
,
):
Promise
<
MessagePayload
>
{
const
from
:
Contact
=
Contact
.
load
(
rawPayload
.
MMActualSender
)
// MMPeerUserName
const
from
:
Contact
=
this
.
Contact
.
load
(
rawPayload
.
MMActualSender
)
// MMPeerUserName
const
text
:
string
=
rawPayload
.
MMActualContent
// Content has @id prefix added by wx
const
date
:
Date
=
new
Date
(
rawPayload
.
MMDisplayTime
)
// Javascript timestamp of milliseconds
...
...
@@ -319,9 +319,9 @@ export class PuppetPuppeteer extends Puppet {
// FIXME: has there any better method to know the room ID?
if
(
rawPayload
.
MMIsChatRoom
)
{
if
(
/^@@/
.
test
(
rawPayload
.
FromUserName
))
{
room
=
Room
.
load
(
rawPayload
.
FromUserName
)
// MMPeerUserName always eq FromUserName ?
room
=
this
.
Room
.
load
(
rawPayload
.
FromUserName
)
// MMPeerUserName always eq FromUserName ?
}
else
if
(
/^@@/
.
test
(
rawPayload
.
ToUserName
))
{
room
=
Room
.
load
(
rawPayload
.
ToUserName
)
room
=
this
.
Room
.
load
(
rawPayload
.
ToUserName
)
}
else
{
throw
new
Error
(
'
parse found a room message, but neither FromUserName nor ToUserName is a room(/^@@/)
'
)
}
...
...
@@ -330,7 +330,7 @@ export class PuppetPuppeteer extends Puppet {
if
(
rawPayload
.
ToUserName
)
{
if
(
!
/^@@/
.
test
(
rawPayload
.
ToUserName
))
{
// if a message in room without any specific receiver, then it will set to be `undefined`
to
=
Contact
.
load
(
rawPayload
.
ToUserName
)
to
=
this
.
Contact
.
load
(
rawPayload
.
ToUserName
)
}
}
...
...
@@ -737,8 +737,7 @@ export class PuppetPuppeteer extends Puppet {
try
{
const
idList
=
await
this
.
bridge
.
contactFind
(
filterFunc
)
return
idList
.
map
(
id
=>
{
const
c
=
Contact
.
load
(
id
)
as
Contact
c
.
puppet
=
this
const
c
=
this
.
Contact
.
load
(
id
)
return
c
})
}
catch
(
e
)
{
...
...
@@ -801,11 +800,7 @@ export class PuppetPuppeteer extends Puppet {
// console.log(rawPayload)
const
memberList
=
(
rawPayload
.
MemberList
||
[])
.
map
(
m
=>
{
const
c
=
Contact
.
load
(
m
.
UserName
)
c
.
puppet
=
this
return
c
})
.
map
(
m
=>
this
.
Contact
.
load
(
m
.
UserName
))
await
Promise
.
all
(
memberList
.
map
(
c
=>
c
.
ready
()))
const
nameMap
=
this
.
roomParseMap
(
'
name
'
,
rawPayload
.
MemberList
)
...
...
@@ -841,8 +836,7 @@ export class PuppetPuppeteer extends Puppet {
memberList
.
forEach
(
member
=>
{
let
tmpName
:
string
// console.log(member)
const
contact
=
Contact
.
load
(
member
.
UserName
)
contact
.
puppet
=
this
const
contact
=
this
.
Contact
.
load
(
member
.
UserName
)
// contact.ready().then(() => console.log('###############', contact.name()))
// console.log(contact)
// log.silly('PuppetPuppeteer', 'roomParseMap() memberList.forEach(contact=%s)', contact)
...
...
@@ -897,8 +891,7 @@ export class PuppetPuppeteer extends Puppet {
try
{
const
idList
=
await
this
.
bridge
.
roomFind
(
filterFunction
)
return
idList
.
map
(
id
=>
{
const
r
=
Room
.
load
(
id
)
as
Room
r
.
puppet
=
this
const
r
=
this
.
Room
.
load
(
id
)
as
Room
return
r
})
}
catch
(
e
)
{
...
...
@@ -959,8 +952,7 @@ export class PuppetPuppeteer extends Puppet {
if
(
!
roomId
)
{
throw
new
Error
(
'
PuppetPuppeteer.roomCreate() roomId "
'
+
roomId
+
'
" not found
'
)
}
const
r
=
Room
.
load
(
roomId
)
as
Room
r
.
puppet
=
this
const
r
=
this
.
Room
.
load
(
roomId
)
as
Room
return
r
}
catch
(
e
)
{
...
...
@@ -1013,14 +1005,10 @@ export class PuppetPuppeteer extends Puppet {
log
.
verbose
(
'
PuppetPuppeteer
'
,
'
readyStable()
'
)
let
counter
=
-
1
// tslint:disable-next-line:variable-name
const
MyContact
=
cloneClass
(
Contact
)
MyContact
.
puppet
=
this
async
function
stable
(
done
:
Function
):
Promise
<
void
>
{
const
stable
=
async
(
done
:
Function
):
Promise
<
void
>
=>
{
log
.
silly
(
'
PuppetPuppeteer
'
,
'
readyStable() stable() counter=%d
'
,
counter
)
const
contactList
=
await
My
Contact
.
findAll
()
const
contactList
=
await
this
.
Contact
.
findAll
()
if
(
counter
===
contactList
.
length
)
{
log
.
verbose
(
'
PuppetPuppeteer
'
,
'
readyStable() stable() READY counter=%d
'
,
counter
)
return
done
()
...
...
src/puppet/puppet.ts
浏览文件 @
5a9ba7ed
...
...
@@ -80,18 +80,6 @@ export const PUPPET_EVENT_DICT = {
export
type
PuppetEventName
=
keyof
typeof
PUPPET_EVENT_DICT
// export type PuppetContact = typeof Contact & Constructor<Contact>
// export type PuppetFriendRequest = typeof FriendRequest & Constructor<FriendRequest>
// export type PuppetMessage = typeof Message & Constructor<Message>
// export type PuppetRoom = typeof Room & Constructor<Room>
// export interface PuppetClasses {
// Contact: PuppetContact,
// FriendRequest: PuppetFriendRequest,
// Message: PuppetMessage,
// Room: PuppetRoom,
// }
export
interface
PuppetOptions
{
profile
:
Profile
,
wechaty
:
Wechaty
,
...
...
@@ -108,6 +96,15 @@ export abstract class Puppet extends EventEmitter implements Sayable {
protected
user
?:
Contact
/* tslint:disable:variable-name */
public
readonly
Contact
:
typeof
Contact
/* tslint:disable:variable-name */
public
readonly
FriendRequest
:
typeof
FriendRequest
/* tslint:disable:variable-name */
public
readonly
Message
:
typeof
Message
/* tslint:disable:variable-name */
public
readonly
Room
:
typeof
Room
/**
* childPkg stores the `package.json` that the NPM module who extends the `Puppet`
*/
...
...
@@ -124,23 +121,10 @@ export abstract class Puppet extends EventEmitter implements Sayable {
this
.
state
=
new
StateSwitch
(
this
.
constructor
.
name
,
log
)
this
.
watchdog
=
new
Watchdog
(
WATCHDOG_TIMEOUT
,
'
Puppet
'
)
/**
* 1. Check Classes for inherience correctly
*/
// if (!classes) {
// throw new Error('no classes found')
// }
// https://stackoverflow.com/questions/14486110/how-to-check-if-a-javascript-class-inherits-another-without-creating-an-obj
// const check = classes.Contact.prototype instanceof Contact
// && classes.FriendRequest.prototype instanceof FriendRequest
// && classes.Message.prototype instanceof Message
// && classes.Room.prototype instanceof Room
// if (!check) {
// throw new Error('Puppet must set classes right! https://github.com/Chatie/wechaty/issues/1167')
// }
// this.classes = classes
this
.
Contact
=
this
.
options
.
wechaty
.
Contact
this
.
FriendRequest
=
this
.
options
.
wechaty
.
FriendRequest
this
.
Message
=
this
.
options
.
wechaty
.
Message
this
.
Room
=
this
.
options
.
wechaty
.
Room
/**
* 2. Load the package.json for Puppet Plugin version range matching
...
...
@@ -257,12 +241,12 @@ export abstract class Puppet extends EventEmitter implements Sayable {
let
msg
:
Message
if
(
typeof
textOrFile
===
'
string
'
)
{
msg
=
Message
.
createMO
({
msg
=
this
.
Message
.
createMO
({
text
:
textOrFile
,
to
:
this
.
userSelf
(),
})
}
else
if
(
textOrFile
instanceof
FileBox
)
{
msg
=
Message
.
createMO
({
msg
=
this
.
Message
.
createMO
({
file
:
textOrFile
,
to
:
this
.
userSelf
(),
})
...
...
@@ -270,7 +254,6 @@ export abstract class Puppet extends EventEmitter implements Sayable {
throw
new
Error
(
'
say() arg unknown
'
)
}
msg
.
puppet
=
this
await
this
.
messageSend
(
msg
)
}
...
...
src/room.ts
浏览文件 @
5a9ba7ed
...
...
@@ -19,7 +19,12 @@
*/
import
*
as
util
from
'
util
'
import
{
FileBox
}
from
'
file-box
'
import
{
FileBox
,
}
from
'
file-box
'
import
{
instanceToClass
,
}
from
'
clone-class
'
import
{
// config,
...
...
@@ -197,6 +202,18 @@ export class Room extends PuppetAccessory implements Sayable {
)
{
super
()
log
.
silly
(
'
Room
'
,
`constructor(
${
id
}
)`
)
// tslint:disable-next-line:variable-name
const
MyClass
=
instanceToClass
(
this
,
Room
)
if
(
MyClass
===
Room
)
{
throw
new
Error
(
'
Room class can not be instanciated directly! See: https://github.com/Chatie/wechaty/issues/1217
'
)
}
if
(
!
this
.
puppet
)
{
throw
new
Error
(
'
Room class can not be instanciated without a puppet!
'
)
}
}
/**
...
...
@@ -295,13 +312,13 @@ export class Room extends PuppetAccessory implements Sayable {
}
else
{
text
=
textOrFile
}
msg
=
Message
.
createMO
({
msg
=
this
.
puppet
.
Message
.
createMO
({
room
:
this
,
to
:
replyToList
[
0
],
// FIXME: is this right?
text
,
})
}
else
if
(
textOrFile
instanceof
FileBox
)
{
msg
=
Message
.
createMO
({
msg
=
this
.
puppet
.
Message
.
createMO
({
room
:
this
,
to
:
replyToList
[
0
],
file
:
textOrFile
,
...
...
@@ -310,7 +327,6 @@ export class Room extends PuppetAccessory implements Sayable {
throw
new
Error
(
'
arg unsupported
'
)
}
msg
.
puppet
=
this
.
puppet
await
this
.
puppet
.
messageSend
(
msg
)
}
...
...
@@ -652,11 +668,7 @@ export class Room extends PuppetAccessory implements Sayable {
log
.
silly
(
'
Room
'
,
'
memberAll() check %s from %s: %s
'
,
filterValue
,
filterKey
,
JSON
.
stringify
(
filterMap
))
if
(
idList
.
length
)
{
return
idList
.
map
(
id
=>
{
const
c
=
Contact
.
load
(
id
)
c
.
puppet
=
this
.
puppet
return
c
})
return
idList
.
map
(
id
=>
this
.
puppet
.
Contact
.
load
(
id
))
}
else
{
return
[]
}
...
...
src/wechaty.ts
浏览文件 @
5a9ba7ed
...
...
@@ -85,8 +85,8 @@ export type WechatEventName = keyof typeof WECHAT_EVENT_DICT
export
type
WechatyEventName
=
keyof
typeof
WECHATY_EVENT_DICT
export
interface
WechatyOptions
{
puppet
?:
PuppetName
|
Puppet
,
profile
?:
string
|
null
,
puppet
:
PuppetName
|
Puppet
,
profile
:
null
|
string
,
}
/**
...
...
@@ -118,16 +118,16 @@ export class Wechaty extends PuppetAccessory implements Sayable {
* the cuid
* @private
*/
public
readonly
cuid
:
string
public
readonly
cuid
:
string
// tslint:disable-next-line:variable-name
public
Contact
:
typeof
Contact
public
readonly
Contact
:
typeof
Contact
// tslint:disable-next-line:variable-name
public
FriendRequest
:
typeof
FriendRequest
public
readonly
FriendRequest
:
typeof
FriendRequest
// tslint:disable-next-line:variable-name
public
Message
:
typeof
Message
public
readonly
Message
:
typeof
Message
// tslint:disable-next-line:variable-name
public
Room
:
typeof
Room
public
readonly
Room
:
typeof
Room
/**
* get the singleton instance of Wechaty
...
...
@@ -157,7 +157,7 @@ export class Wechaty extends PuppetAccessory implements Sayable {
* @public
*/
constructor
(
private
options
:
WechatyOptions
=
{},
private
options
:
WechatyOptions
=
{}
as
any
,
)
{
super
()
log
.
verbose
(
'
Wechaty
'
,
'
contructor()
'
)
...
...
@@ -171,6 +171,19 @@ export class Wechaty extends PuppetAccessory implements Sayable {
this
.
profile
=
new
Profile
(
options
.
profile
)
this
.
cuid
=
cuid
()
/**
* Clone Classes for this bot and attach the `puppet` to the Class
*
* https://stackoverflow.com/questions/36886082/abstract-constructor-type-in-typescript
* https://github.com/Microsoft/TypeScript/issues/5843#issuecomment-290972055
* https://github.com/Microsoft/TypeScript/issues/19197
*/
// TODO: make Message & Room constructor private???
this
.
Contact
=
cloneClass
(
Contact
)
this
.
FriendRequest
=
cloneClass
(
FriendRequest
)
this
.
Message
=
cloneClass
(
Message
)
this
.
Room
=
cloneClass
(
Room
)
}
/**
...
...
@@ -375,83 +388,72 @@ export class Wechaty extends PuppetAccessory implements Sayable {
*/
public
initPuppet
():
void
{
log
.
verbose
(
'
Wechaty
'
,
'
initPuppet()
'
)
let
puppet
:
Puppet
/**
* 1. Init the Puppet
*/
if
(
typeof
this
.
options
.
puppet
===
'
string
'
)
{
const
puppet
=
this
.
initPuppetResolver
(
this
.
options
.
puppet
)
if
(
!
this
.
initPuppetSemverSatisfy
(
puppet
.
wechatyVersionRange
(),
))
{
throw
new
Error
(
`The Puppet Plugin(
${
puppet
.
constructor
.
name
}
) `
+
`requires a version range(
${
puppet
.
wechatyVersionRange
()}
) `
+
`that is not satisfying the Wechaty version:
${
this
.
version
()}
.`
,
)
}
this
.
initPuppetEventBridge
(
puppet
)
this
.
initPuppetAccessory
(
puppet
)
}
/**
* Init the Puppet
*/
private
initPuppetResolver
(
puppet
:
PuppetName
|
Puppet
):
Puppet
{
log
.
verbose
(
'
Wechaty
'
,
'
initPuppetResolver(%s)
'
,
puppet
)
if
(
typeof
puppet
===
'
string
'
)
{
// tslint:disable-next-line:variable-name
const
MyPuppet
=
PUPPET_DICT
[
this
.
options
.
puppet
]
const
MyPuppet
=
PUPPET_DICT
[
puppet
]
if
(
!
MyPuppet
)
{
throw
new
Error
(
'
no such puppet:
'
+
puppet
)
}
const
options
=
{
profile
:
this
.
profile
,
wechaty
:
this
,
}
puppet
=
new
MyPuppet
(
options
)
return
new
MyPuppet
(
options
)
}
else
if
(
this
.
options
.
puppet
instanceof
Puppet
)
{
puppet
=
this
.
options
.
puppet
}
else
if
(
puppet
instanceof
Puppet
)
{
return
puppet
}
else
{
throw
new
Error
(
'
unsupported options.puppet!
'
)
}
}
/**
* 2. Plugin Version Range Check
*/
if
(
!
semver
.
satisfies
(
/**
* Plugin Version Range Check
*/
private
initPuppetSemverSatisfy
(
versionRange
:
string
)
{
log
.
verbose
(
'
Wechaty
'
,
'
initPuppet(%s)
'
,
versionRange
)
return
semver
.
satisfies
(
this
.
version
(
true
),
puppet
.
wechatyVersionRange
(),
))
{
throw
new
Error
(
`The Puppet Plugin(
${
puppet
.
constructor
.
name
}
) `
+
`requires a version range(
${
puppet
.
wechatyVersionRange
()}
) `
+
`that is not satisfying the Wechaty version:
${
this
.
version
()}
.`
)
}
versionRange
,
)
}
private
initPuppetEventBridge
(
puppet
:
Puppet
)
{
for
(
const
event
of
Object
.
keys
(
WECHATY_EVENT_DICT
))
{
log
.
verbose
(
'
Wechaty
'
,
'
initPuppet() puppet.on(%s) registered
'
,
event
)
log
.
verbose
(
'
Wechaty
'
,
'
initPuppet
EventBridge
() puppet.on(%s) registered
'
,
event
)
/// e as any ??? Maybe this is a bug of TypeScript v2.5.3
puppet
.
on
(
event
as
any
,
(...
args
:
any
[])
=>
{
this
.
emit
(
event
,
...
args
)
})
}
}
/**
* When `this` is the global instance of Wechaty (`Wechaty.instance()`)
* so we can keep using `Contact.find()` and `Room.find()`
*
* This workaround should be removed after v0.18
*
* See: fix the breaking changes for #518
* https://github.com/Chatie/wechaty/issues/518
*/
if
(
this
===
Wechaty
.
globalInstance
)
{
Contact
.
puppet
=
puppet
FriendRequest
.
puppet
=
puppet
Message
.
puppet
=
puppet
Room
.
puppet
=
puppet
instanceToClass
(
this
,
PuppetAccessory
).
puppet
=
puppet
}
/**
* Clone Classes for this bot and attach the `puppet` to the Class
*
* Fixme:
* https://stackoverflow.com/questions/36886082/abstract-constructor-type-in-typescript
* https://github.com/Microsoft/TypeScript/issues/5843#issuecomment-290972055
* https://github.com/Microsoft/TypeScript/issues/19197
*/
// this.Contact = cloneClass(puppet.classes.Contact)
// this.FriendRequest = cloneClass(puppet.classes.FriendRequest)
// this.Message = cloneClass(puppet.classes.Message)
// this.Room = cloneClass(puppet.classes.Room)
// TODO: make Message & Room constructor private???
this
.
Contact
=
cloneClass
(
Contact
)
this
.
FriendRequest
=
cloneClass
(
FriendRequest
)
this
.
Message
=
cloneClass
(
Message
)
this
.
Room
=
cloneClass
(
Room
)
private
initPuppetAccessory
(
puppet
:
Puppet
)
{
log
.
verbose
(
'
Wechaty
'
,
'
initPuppetAccessory(%s)
'
,
puppet
)
this
.
Contact
.
puppet
=
puppet
this
.
FriendRequest
.
puppet
=
puppet
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录