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

add chatbot module #522

Merged
merged 2 commits into from
Nov 16, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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())