Skip to content
This repository has been archived by the owner on May 25, 2022. It is now read-only.

Commit

Permalink
Merge pull request #522 from wj-Mcat/master
Browse files Browse the repository at this point in the history
add chatbot module
  • Loading branch information
chavarera authored Nov 16, 2021
2 parents 370f5db + a9c302f commit ceccdd3
Show file tree
Hide file tree
Showing 4 changed files with 275 additions and 0 deletions.
24 changes: 24 additions & 0 deletions projects/chatbot/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Chatbot
[python-wechaty](https://github.com/wechaty/python-wechaty) is an unified conversational RPA SDK for chatbot maker. Developer at least use six lines code to create chatbot base on multi-ims, eg: wechat, wechat official account, dingtalk, lark, whatsapp, giter, and so on ...

There are [chinese documents](https://wechaty.readthedocs.io/) and [english documents](http://wechaty.js.org/) for developers to create their own chatbots.

### Prerequisites

```shell
pip install -r projects/chatbot/requirements.txt
```

### How to run the script

```python
python projects/chatbot/bot.py
```

### Screenshot/GIF showing the sample use of the script

The Run command script above is the best screenshot.

## *Author Name*

[wj-Mcat](https://github.com/wj-Mcat), 吴京京, NLP Researcher, Chatbot Lover
237 changes: 237 additions & 0 deletions projects/chatbot/bot.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,237 @@
"""example code for ding-dong-bot with oop style"""
from typing import List, Optional, Union
import asyncio
from datetime import datetime
from wechaty_puppet import get_logger
from wechaty import (
MessageType,
FileBox,
RoomMemberQueryFilter,
Wechaty,
Contact,
Room,
Message,
Image,
MiniProgram,
Friendship,
FriendshipType,
EventReadyPayload
)

logger = get_logger(__name__)


class MyBot(Wechaty):
"""
listen wechaty event with inherited functions, which is more friendly for
oop developer
"""

def __init__(self) -> None:
"""initialization function
"""
self.login_user: Optional[Contact] = None
super().__init__()

async def on_ready(self, payload: EventReadyPayload) -> None:
"""listen for on-ready event"""
logger.info('ready event %s...', payload)

# pylint: disable=R0912,R0914,R0915
async def on_message(self, msg: Message) -> None:
"""
listen for message event
"""
from_contact: Contact = msg.talker()
text: str = msg.text()
room: Optional[Room] = msg.room()
msg_type: MessageType = msg.type()
file_box: Optional[FileBox] = None
if text == 'ding':
conversation: Union[
Room, Contact] = from_contact if room is None else room
await conversation.ready()
await conversation.say('dong')
file_box = FileBox.from_url(
'https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/'
'u=1116676390,2305043183&fm=26&gp=0.jpg',
name='ding-dong.jpg')
await conversation.say(file_box)

elif msg_type == MessageType.MESSAGE_TYPE_IMAGE:
logger.info('receving image file')
# file_box: FileBox = await msg.to_file_box()
image: Image = msg.to_image()

hd_file_box: FileBox = await image.hd()
await hd_file_box.to_file('./hd-image.jpg', overwrite=True)

thumbnail_file_box: FileBox = await image.thumbnail()
await thumbnail_file_box.to_file('./thumbnail-image.jpg', overwrite=True)
artwork_file_box: FileBox = await image.artwork()
await artwork_file_box.to_file('./artwork-image.jpg', overwrite=True)
# reply the image
await msg.say(hd_file_box)

# pylint: disable=C0301
elif msg_type in [MessageType.MESSAGE_TYPE_AUDIO, MessageType.MESSAGE_TYPE_ATTACHMENT, MessageType.MESSAGE_TYPE_VIDEO]:
logger.info('receving file ...')
file_box = await msg.to_file_box()
if file_box:
await file_box.to_file(file_box.name)

elif msg_type == MessageType.MESSAGE_TYPE_MINI_PROGRAM:
logger.info('receving mini-program ...')
mini_program: Optional[MiniProgram] = await msg.to_mini_program()
if mini_program:
await msg.say(mini_program)

elif text == 'get room members' and room:
logger.info('get room members ...')
room_members: List[Contact] = await room.member_list()
names: List[str] = [
room_member.name for room_member in room_members]
await msg.say('\n'.join(names))

elif text.startswith('remove room member:'):
logger.info('remove room member:')
if not room:
await msg.say('this is not room zone')
return

room_member_name = text[len('remove room member:') + 1:]

room_member: Optional[Contact] = await room.member(
query=RoomMemberQueryFilter(name=room_member_name)
)
if room_member:
if self.login_user and self.login_user.contact_id in room.payload.admin_ids:
await room.delete(room_member)
else:
await msg.say('登录用户不是该群管理员...')

else:
await msg.say(f'can not fine room member by name<{room_member_name}>')
elif text.startswith('get room topic'):
logger.info('get room topic')
if room:
topic: Optional[str] = await room.topic()
if topic:
await msg.say(topic)

elif text.startswith('rename room topic:'):
logger.info('rename room topic ...')
if room:
new_topic = text[len('rename room topic:') + 1:]
await msg.say(new_topic)
elif text.startswith('add new friend:'):
logger.info('add new friendship ...')
identity_info = text[len('add new friend:'):]
weixin_contact: Optional[Contact] = await self.Friendship.search(weixin=identity_info)
phone_contact: Optional[Contact] = await self.Friendship.search(phone=identity_info)
contact: Optional[Contact] = weixin_contact or phone_contact
if contact:
await self.Friendship.add(contact, 'hello world ...')

elif text.startswith('at me'):
if room:
talker = msg.talker()
await room.say('hello', mention_ids=[talker.contact_id])

elif text.startswith('my alias'):
talker = msg.talker()
alias = await talker.alias()
await msg.say('your alias is:' + (alias or ''))

elif text.startswith('set alias:'):
talker = msg.talker()
new_alias = text[len('set alias:'):]

# set your new alias
alias = await talker.alias(new_alias)
# get your new alias
alias = await talker.alias()
await msg.say('your new alias is:' + (alias or ''))

elif text.startswith('find friends:'):
friend_name: str = text[len('find friends:'):]
friend = await self.Contact.find(friend_name)
if friend:
logger.info('find only one friend <%s>', friend)

friends: List[Contact] = await self.Contact.find_all(friend_name)

logger.info('find friend<%d>', len(friends))
logger.info(friends)

else:
pass

if msg.type() == MessageType.MESSAGE_TYPE_UNSPECIFIED:
talker = msg.talker()
assert isinstance(talker, Contact)

async def on_login(self, contact: Contact) -> None:
"""login event
Args:
contact (Contact): the account logined
"""
logger.info('Contact<%s> has logined ...', contact)
self.login_user = contact

async def on_friendship(self, friendship: Friendship) -> None:
"""when receive a new friendship application, or accept a new friendship
Args:
friendship (Friendship): contains the status and friendship info,
eg: hello text, friend contact object
"""
MAX_ROOM_MEMBER_COUNT = 500
# 1. receive a new friendship from someone
if friendship.type() == FriendshipType.FRIENDSHIP_TYPE_RECEIVE:
hello_text: str = friendship.hello()

# accept friendship when there is a keyword in hello text
if 'wechaty' in hello_text.lower():
await friendship.accept()

# 2. you have a new friend to your contact list
elif friendship.type() == FriendshipType.FRIENDSHIP_TYPE_CONFIRM:
# 2.1 invite the user to wechaty group
# find the topic of room which contains Wechaty keyword
wechaty_rooms: List[Room] = await self.Room.find_all('Wechaty')

# 2.2 find the suitable room
for wechaty_room in wechaty_rooms:
members: List[Contact] = await wechaty_room.member_list()
if len(members) < MAX_ROOM_MEMBER_COUNT:
contact: Contact = friendship.contact()
await wechaty_room.add(contact)
break

async def on_room_join(self, room: Room, invitees: List[Contact],
inviter: Contact, date: datetime) -> None:
"""on_room_join when there are new contacts to the room
Args:
room (Room): the room instance
invitees (List[Contact]): the new contacts to the room
inviter (Contact): the inviter who share qrcode or manual invite someone
date (datetime): the datetime to join the room
"""
# 1. say something to welcome the new arrivals
names: List[str] = []
for invitee in invitees:
await invitee.ready()
names.append(invitee.name)

await room.say(f'welcome {",".join(names)} to the wechaty group !')


async def main() -> None:
"""doc"""
bot = MyBot()
await bot.start()

asyncio.run(main())
1 change: 1 addition & 0 deletions projects/chatbot/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
wechaty
13 changes: 13 additions & 0 deletions projects/chatbot/simple-bot.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import asyncio
from wechaty import Wechaty, Message

async def on_message(msg: Message):
if msg.text() == 'ding':
await msg.say('dong')

async def main():
bot = Wechaty()
bot.on('message', on_message)
await bot.start()

asyncio.run(main())

0 comments on commit ceccdd3

Please sign in to comment.