Skip to content

Commit 76254ab

Browse files
authored
Merge pull request #21 from huangaszaq/master
add room-bot
2 parents 619c1cc + 8bce78c commit 76254ab

File tree

1 file changed

+226
-0
lines changed

1 file changed

+226
-0
lines changed

examples/advanced/room_bot.py

Lines changed: 226 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,226 @@
1+
import asyncio
2+
import re
3+
import time
4+
from datetime import datetime
5+
from typing import List
6+
7+
from apscheduler.schedulers.asyncio import AsyncIOScheduler
8+
9+
from wechaty import Contact, Room, Wechaty, get_logger, Message
10+
11+
welcome = """=============== Powered by Python-Wechaty ===============
12+
-------- https://github.com/Chatie/python-wechaty --------
13+
Hello,
14+
I'm a Wechaty Botie with the following super powers:
15+
1. Find a room
16+
2. Add people to room
17+
3. Del people from room
18+
4. Change room topic
19+
5. Monitor room events
20+
6. etc...
21+
If you send a message of magic word 'ding',
22+
you will get a invitation to join my own room!
23+
__________________________________________________
24+
Hope you like it, and you are very welcome to
25+
upgrade me for more super powers!
26+
Please wait... I'm trying to login in..."""
27+
HELPER_CONTACT_NAME = '黄纯洪'
28+
29+
print(welcome)
30+
log = get_logger('RoomBot')
31+
32+
33+
async def check_room_join(bot, room, invitee_list, inviter):
34+
try:
35+
user_self = bot.user_self()
36+
if inviter.id != user_self.contact_id:
37+
await room.say('RULE1: Invitation is limited to me, the owner only. '
38+
'Please do not invite people without notify me.' + inviter)
39+
await room.say('Please contact me: by send "ding" to me, I will re-send you a invitation. '
40+
'Now I will remove you out, sorry.' + ''.join(invitee_list))
41+
await room.topic('ding - warn ' + inviter.name())
42+
scheduler = AsyncIOScheduler()
43+
for i in invitee_list:
44+
scheduler.add_job(room.delete, args=[i], seconds=10)
45+
scheduler.start()
46+
else:
47+
await room.say('Welcome to my room! :)')
48+
welcomeTopic = ', '.join(map(lambda c: c.name, invitee_list))
49+
await room.topic('ding - welcome ' + welcomeTopic)
50+
except Exception as e:
51+
log.exception(e)
52+
53+
54+
async def manage_ding_room(bot):
55+
time.sleep(3)
56+
log.info('Bot' + 'manage_ding_room()')
57+
try:
58+
room = await bot.Room.find(topic='ding')
59+
if not room:
60+
log.warning('Bot ' + 'there is no room topic ding(yet)')
61+
return
62+
log.info('Bot' + 'start monitor "ding" room join/leave/topic event')
63+
64+
def on_join(inviteeList, inviter):
65+
log.info('room.on(join) id:', room.room_id)
66+
check_room_join(bot, room, inviteeList, inviter)
67+
68+
def on_leave(leaverList, remover):
69+
log.info('Bot' + 'Room EVENT: leave - "%s" leave(remover "%s"), bye bye' % (','.join(leaverList),
70+
remover or 'unknown'))
71+
72+
def on_topic(topic, oldTopic, changer):
73+
log.info('Bot' +
74+
'Room EVENT: topic - changed from "%s" to "%s" by member "%s"' % (oldTopic, topic, changer.name()))
75+
76+
room.on('join', on_join)
77+
room.on('leave', on_leave)
78+
room.on('topic', on_topic)
79+
except Exception as e:
80+
log.exception(e)
81+
82+
83+
async def put_in_room(contact, room):
84+
log.info('Bot' + 'put_in_room("%s", "%s")' % (contact.name(), await room.topic()))
85+
try:
86+
await room.add(contact)
87+
scheduler = AsyncIOScheduler()
88+
scheduler.add_job(lambda x: room.say('Welcome ', contact))
89+
scheduler.start()
90+
except Exception as e:
91+
log.exception(e)
92+
93+
94+
async def get_out_room(contact, room):
95+
log.info('Bot' + 'get_out_room("%s", "%s")' % (contact, room))
96+
try:
97+
await room.say('You said "ding" in my room, I will remove you out.')
98+
await room.delete(contact)
99+
except Exception as e:
100+
log.exception('get_out_room() exception: ', e)
101+
102+
103+
def get_helper_contact(bot):
104+
log.info('Bot' + 'get_helper_contact()')
105+
return bot.Contact.find(HELPER_CONTACT_NAME)
106+
107+
108+
async def create_ding_room(bot, contact):
109+
log.info('create_ding_room("%s")' % contact)
110+
try:
111+
helperContact = await get_helper_contact(bot)
112+
if not helperContact:
113+
log.warning('get_helper_contact() found nobody')
114+
await contact.say("""You don't have a friend called "%s", because create a new room at
115+
least need 3 contacts, please set [HELPER_CONTACT_NAME] in the code first!""" % HELPER_CONTACT_NAME)
116+
return
117+
log.info('get_helper_contact() ok. got: "%s"' % helperContact.name())
118+
contactList = [contact, helperContact]
119+
await contact.say(
120+
"""There isn't ding room. I'm trying to create a room with "{0}" and you""" % helperContact.name())
121+
room = await bot.Room.create(contactList, 'ding')
122+
log.info('create_ding_room() new ding room created: "%s"' % room)
123+
await room.topic('ding - created')
124+
await room.say('ding - created')
125+
return room
126+
except Exception as e:
127+
log.exception('get_helper_contact() exception:', e)
128+
129+
130+
class MyBot(Wechaty):
131+
132+
# def on_scan(self, status: ScanStatus, qr_code: Optional[str] = None,
133+
# data: Optional[str] = None):
134+
# qr_terminal(qr_code, 1)
135+
# log.info("{0}\n[{1}] Scan QR Code in above url to login: ".format(qr_code, status))
136+
137+
def on_error(self, payload):
138+
log.info(str(payload))
139+
140+
def on_logout(self, contact: Contact):
141+
log.info('Bot %s logouted' % contact.name)
142+
143+
async def on_login(self, contact: Contact):
144+
msg = contact.payload.name + ' logined'
145+
log.info('bot ' + msg)
146+
await contact.say(msg)
147+
148+
msg = "setting to manage_ding_room() after 3 seconds..."
149+
log.info('Bot' + msg)
150+
print(self.user_self())
151+
await contact.say(msg)
152+
await manage_ding_room(self)
153+
154+
async def on_room_join(self, room: Room, invitees: List[Contact],
155+
inviter: Contact, date: datetime):
156+
log.info('Bot' + 'EVENT: room-join - Room "%s" got new member "%s", invited by "%s"' %
157+
(await room.topic(), ','.join(map(lambda c: c.name, invitees)), inviter.name))
158+
print('bot room-join room id:', room.room_id)
159+
topic = await room.topic()
160+
await room.say('welcome to "{0}"!'.format(topic), [invitees[0].__str__()])
161+
162+
async def on_room_leave(self, room: Room, leavers: List[Contact],
163+
remover: Contact, date: datetime):
164+
log.info('Bot' + 'EVENT: room-leave - Room "%s" lost member "%s"' %
165+
(await room.topic(), ','.join(map(lambda c: c.name(), leavers))))
166+
topic = await room.topic()
167+
name = leavers[0].name if leavers[0] else 'no contact!'
168+
await room.say('kick off "{0}" from "{1}"!'.format(name, topic))
169+
170+
async def on_room_topic(self, room: Room, new_topic: str, old_topic: str,
171+
changer: Contact, date: datetime):
172+
try:
173+
log.info('Bot' + 'EVENT: room-topic - Room "%s" change topic from "%s" to "%s" by member "%s"' %
174+
(room, old_topic, new_topic, changer))
175+
await room.say('room-topic - change topic from "{0}" to "{1}" '
176+
'by member "{2}"'.format(old_topic, new_topic, changer.name))
177+
except Exception as e:
178+
log.exception(e)
179+
180+
async def on_message(self, msg: Message):
181+
if msg.age() > 3 * 60:
182+
log.info('Bot' + 'on(message) skip age("%d") > 3 * 60 seconds: "%s"', msg.age(), msg)
183+
return
184+
room = msg.room()
185+
talker = msg.talker()
186+
text = msg.text()
187+
if not talker:
188+
return
189+
if msg.is_self():
190+
return
191+
if re.search('^ding$', text):
192+
if room:
193+
if re.search('^ding', await room.topic()):
194+
await get_out_room(talker, room)
195+
else:
196+
try:
197+
dingRoom = await self.Room.find('^ding')
198+
if dingRoom:
199+
log.info('Bot' + 'onMessage: got dingRoom: "%s"' % await dingRoom.topic())
200+
if await dingRoom.has(talker):
201+
topic = await dingRoom.topic()
202+
log.info('Bot' + 'onMessage: sender has already in dingRoom')
203+
await dingRoom.say('I found you have joined in room "{0}"!'.format(topic), talker)
204+
await talker.say(
205+
'no need to ding again, because you are already in room: "{}"'.format(topic))
206+
else:
207+
log.info('Bot' + 'onMessage: add sender("%s") to dingRoom("%s")' % (
208+
talker.name, dingRoom.topic()))
209+
await talker.say('ok, I will put you in ding room!')
210+
await put_in_room(talker, dingRoom)
211+
else:
212+
log.info('Bot' + 'onMessage: dingRoom not found, try to create one')
213+
newRoom = await create_ding_room(self, talker)
214+
print('create_ding_room id:', newRoom.id)
215+
await manage_ding_room(self)
216+
except Exception as e:
217+
log.exception(e)
218+
219+
220+
async def main():
221+
bot = MyBot()
222+
await bot.start()
223+
224+
225+
if __name__ == '__main__':
226+
asyncio.run(main())

0 commit comments

Comments
 (0)