-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathchatops.ts
executable file
·203 lines (199 loc) · 6.87 KB
/
chatops.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
import { Wechaty, log, Message, Contact, UrlLink, MiniProgram, Room, FileBox } from 'wechaty';
import { DelayQueueExecutor, DelayQueueExector } from 'rx-queue'
import { TEST_ROOM_ID, HEARTBEAT_ROOM_ID } from './config/config'
export class Chatops {
public static bot: Chatops
private delayQueueExecutor: DelayQueueExector
public repeatMode: boolean = false
public static instance(
wechaty?: Wechaty,
) {
if (!this.bot) {
if (!wechaty) {
throw new Error('instance need a Wechaty instance to initialize')
}
this.bot = new Chatops(wechaty)
}
return this.bot
}
private constructor(
private wechaty: Wechaty
) {
this.delayQueueExecutor = new DelayQueueExecutor(5 * 1000)
}
public findFriendByWeChat(wechat: string) {
return this.wechaty.Contact.load(wechat)
}
public findRoomByRoomId(roomId: string) {
return this.wechaty.Room.load(roomId)
}
public async sayUnbind(contact: Contact) {
await this.queue(async () => {
await contact.say('您还未绑定账号\n请发送 #bd+“您的绑定码”\n如:\n#bd12345')
}, `friendship confirm with` + contact.name())
}
public async say2Friend(idOrContact: Contact | string, info: string | Message | UrlLink | MiniProgram) {
let contact: null | Contact
if (idOrContact instanceof Contact) {
contact = idOrContact
} else {
contact = await this.wechaty.Contact.load(idOrContact)
}
let contactId = contact.id
if (!this.wechaty.logonoff()) {
log.error('chat', 'say2Friend() bot is offline')
throw new Error('say2Friend() bot is offline')
}
if (!contact) {
log.error('chat', 'say2Friend() no contact found %s', contactId)
throw new Error(`say2Friend() no contact found ${contactId}`)
}
if (typeof info === 'string') {
await contact.say(info)
} else if (info instanceof Message) {
switch (info.type()) {
case Message.Type.Text:
await this.queue(async () => {
await contact?.say(`${info}`)
}, 'say2friend')
break
case Message.Type.Image:
const image = await info.toFileBox()
await this.queue(async () => {
await contact?.say(image)
}, 'say2friend')
break
case Message.Type.Url:
const urlLink = await info.toUrlLink()
await this.queue(async () => {
await contact?.say(urlLink)
}, 'say2friend')
break
default:
const typeName = Message.Type[info.type()]
await this.queue(async () => {
await contact?.say(`message type: ${typeName}`)
}, 'say2friend')
break
}
} else if (info instanceof UrlLink) {
await this.queue(async () => {
await contact?.say(info)
}, 'say2friend')
}
return
}
public async sayWelcomeBack(contact: Contact) {
await this.queue(async () => {
await contact.say('您还未绑定账号\n请发送 #bd+“您的绑定码”\n如:\n#bd12345\n发送"帮助"查看更多')
}, `friendship confirm with` + contact.name())
}
public async msgRoomTopic(msg: Message) {
const result = await msg.room()?.topic()
return result
}
public isBindUserId(contact: Contact) {
if (contact.weixin()) {
return false
} else {
return false
}
}
public logonoff(): boolean {
return this.wechaty.logonoff()
}
public async say2Room(roomId: string,
info: string | Message | UrlLink | FileBox | MiniProgram): Promise<void> {
if (!this.wechaty.logonoff()) {
log.error('chat', 'say2Room() bot is offline')
throw new Error('say2Room() bot is offline')
}
const room = await this.wechaty.Room.load(roomId)
if (!room) {
log.error('chat', 'say2Room() no bot found in Room %s', roomId)
throw new Error(`say2Room() no bot found in Room ${roomId}`)
}
if (typeof info === 'string') {
await room.say(info)
} else if (info instanceof Message) {
switch (info.type()) {
case Message.Type.Text:
await room.say(`${info}`)
break
case Message.Type.Image:
const image = await info.toFileBox()
room.say(image)
break
case Message.Type.Url:
const urlLink = await info.toUrlLink()
await room.say(urlLink)
break
default:
const typeName = Message.Type[info.type()]
await room.say(`message type: ${typeName}`)
break
}
} else if (info instanceof UrlLink) {
await room.say(info)
} else if (info instanceof FileBox) {
await room.say(info)
}
return
}
public async repeaterFromUser(msg: Message, roomId?: string, userId?: string): Promise<void> {
const contact = msg.from()
const msgType = msg.type()
const room = msg.room()
if (msg.self() && msg.text() == '复读机模式') {
await room?.say('复读机模式开启')
this.repeatMode = true
}
if (msg.self() && msg.text() == '正常模式') {
await room?.say('正常模式开启')
this.repeatMode = false
}
if (!contact) {
// do nothing!
log.error(`chat`, 'repeater() no bot found contact')
return
}
if (!room) {
log.error(`chat`, 'repeater() no bot found room')
return
// do nothing
}
console.log(`contact?.weixin():${contact?.weixin()}`)
console.log(`room?.id:${room?.id}`)
if (contact?.weixin() == userId && roomId == room?.id && this.repeatMode == true) {
if (msgType == Message.Type.Text) {
room?.say(msg.text())
}
} else {
log.error('error')
}
}
public async queue(fn: any, name?: string) {
log.info('chat', 'queue(,"%s")', name)
await this.delayQueueExecutor.execute(fn.bind(this), name)
log.info('chat', 'queue(,"%s") finish.', name)
}
async idsToRooms(idOrList: string | string[]) {
if (Array.isArray(idOrList)) {
const roomList = await Promise.all(
idOrList.map(
id => this.wechaty.Room.load(id)
)
)
return roomList.filter(r => !!r) as Room[]
} else {
const room = await this.wechaty.Room.load(idOrList)
return room ? [room] : []
}
}
public async say(textOrMessage: string | Message | UrlLink) {
return this.say2Room(TEST_ROOM_ID, textOrMessage)
}
async heartbeat(emoji: string) {
return this.say2Room(HEARTBEAT_ROOM_ID, emoji)
}
}