bot.py 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. """example code for ding-dong-bot with oop style"""
  2. from typing import List, Optional, Union
  3. import asyncio
  4. from datetime import datetime
  5. from wechaty_puppet import get_logger
  6. from wechaty import (
  7. MessageType,
  8. FileBox,
  9. RoomMemberQueryFilter,
  10. Wechaty,
  11. Contact,
  12. Room,
  13. Message,
  14. Image,
  15. MiniProgram,
  16. Friendship,
  17. FriendshipType,
  18. EventReadyPayload
  19. )
  20. logger = get_logger(__name__)
  21. class MyBot(Wechaty):
  22. """
  23. listen wechaty event with inherited functions, which is more friendly for
  24. oop developer
  25. """
  26. def __init__(self) -> None:
  27. """initialization function
  28. """
  29. self.login_user: Optional[Contact] = None
  30. super().__init__()
  31. async def on_ready(self, payload: EventReadyPayload) -> None:
  32. """listen for on-ready event"""
  33. logger.info('ready event %s...', payload)
  34. # pylint: disable=R0912,R0914,R0915
  35. async def on_message(self, msg: Message) -> None:
  36. """
  37. listen for message event
  38. """
  39. from_contact: Contact = msg.talker()
  40. text: str = msg.text()
  41. room: Optional[Room] = msg.room()
  42. msg_type: MessageType = msg.type()
  43. file_box: Optional[FileBox] = None
  44. if text == 'ding':
  45. conversation: Union[
  46. Room, Contact] = from_contact if room is None else room
  47. await conversation.ready()
  48. await conversation.say('dong')
  49. file_box = FileBox.from_url(
  50. 'https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/'
  51. 'u=1116676390,2305043183&fm=26&gp=0.jpg',
  52. name='ding-dong.jpg')
  53. await conversation.say(file_box)
  54. elif msg_type == MessageType.MESSAGE_TYPE_IMAGE:
  55. logger.info('receving image file')
  56. # file_box: FileBox = await msg.to_file_box()
  57. image: Image = msg.to_image()
  58. hd_file_box: FileBox = await image.hd()
  59. await hd_file_box.to_file('./hd-image.jpg', overwrite=True)
  60. thumbnail_file_box: FileBox = await image.thumbnail()
  61. await thumbnail_file_box.to_file('./thumbnail-image.jpg', overwrite=True)
  62. artwork_file_box: FileBox = await image.artwork()
  63. await artwork_file_box.to_file('./artwork-image.jpg', overwrite=True)
  64. # reply the image
  65. await msg.say(hd_file_box)
  66. # pylint: disable=C0301
  67. elif msg_type in [MessageType.MESSAGE_TYPE_AUDIO, MessageType.MESSAGE_TYPE_ATTACHMENT, MessageType.MESSAGE_TYPE_VIDEO]:
  68. logger.info('receving file ...')
  69. file_box = await msg.to_file_box()
  70. if file_box:
  71. await file_box.to_file(file_box.name)
  72. elif msg_type == MessageType.MESSAGE_TYPE_MINI_PROGRAM:
  73. logger.info('receving mini-program ...')
  74. mini_program: Optional[MiniProgram] = await msg.to_mini_program()
  75. if mini_program:
  76. await msg.say(mini_program)
  77. elif text == 'get room members' and room:
  78. logger.info('get room members ...')
  79. room_members: List[Contact] = await room.member_list()
  80. names: List[str] = [
  81. room_member.name for room_member in room_members]
  82. await msg.say('\n'.join(names))
  83. elif text.startswith('remove room member:'):
  84. logger.info('remove room member:')
  85. if not room:
  86. await msg.say('this is not room zone')
  87. return
  88. room_member_name = text[len('remove room member:') + 1:]
  89. room_member: Optional[Contact] = await room.member(
  90. query=RoomMemberQueryFilter(name=room_member_name)
  91. )
  92. if room_member:
  93. if self.login_user and self.login_user.contact_id in room.payload.admin_ids:
  94. await room.delete(room_member)
  95. else:
  96. await msg.say('登录用户不是该群管理员...')
  97. else:
  98. await msg.say(f'can not fine room member by name<{room_member_name}>')
  99. elif text.startswith('get room topic'):
  100. logger.info('get room topic')
  101. if room:
  102. topic: Optional[str] = await room.topic()
  103. if topic:
  104. await msg.say(topic)
  105. elif text.startswith('rename room topic:'):
  106. logger.info('rename room topic ...')
  107. if room:
  108. new_topic = text[len('rename room topic:') + 1:]
  109. await msg.say(new_topic)
  110. elif text.startswith('add new friend:'):
  111. logger.info('add new friendship ...')
  112. identity_info = text[len('add new friend:'):]
  113. weixin_contact: Optional[Contact] = await self.Friendship.search(weixin=identity_info)
  114. phone_contact: Optional[Contact] = await self.Friendship.search(phone=identity_info)
  115. contact: Optional[Contact] = weixin_contact or phone_contact
  116. if contact:
  117. await self.Friendship.add(contact, 'hello world ...')
  118. elif text.startswith('at me'):
  119. if room:
  120. talker = msg.talker()
  121. await room.say('hello', mention_ids=[talker.contact_id])
  122. elif text.startswith('my alias'):
  123. talker = msg.talker()
  124. alias = await talker.alias()
  125. await msg.say('your alias is:' + (alias or ''))
  126. elif text.startswith('set alias:'):
  127. talker = msg.talker()
  128. new_alias = text[len('set alias:'):]
  129. # set your new alias
  130. alias = await talker.alias(new_alias)
  131. # get your new alias
  132. alias = await talker.alias()
  133. await msg.say('your new alias is:' + (alias or ''))
  134. elif text.startswith('find friends:'):
  135. friend_name: str = text[len('find friends:'):]
  136. friend = await self.Contact.find(friend_name)
  137. if friend:
  138. logger.info('find only one friend <%s>', friend)
  139. friends: List[Contact] = await self.Contact.find_all(friend_name)
  140. logger.info('find friend<%d>', len(friends))
  141. logger.info(friends)
  142. else:
  143. pass
  144. if msg.type() == MessageType.MESSAGE_TYPE_UNSPECIFIED:
  145. talker = msg.talker()
  146. assert isinstance(talker, Contact)
  147. async def on_login(self, contact: Contact) -> None:
  148. """login event
  149. Args:
  150. contact (Contact): the account logined
  151. """
  152. logger.info('Contact<%s> has logined ...', contact)
  153. self.login_user = contact
  154. async def on_friendship(self, friendship: Friendship) -> None:
  155. """when receive a new friendship application, or accept a new friendship
  156. Args:
  157. friendship (Friendship): contains the status and friendship info,
  158. eg: hello text, friend contact object
  159. """
  160. MAX_ROOM_MEMBER_COUNT = 500
  161. # 1. receive a new friendship from someone
  162. if friendship.type() == FriendshipType.FRIENDSHIP_TYPE_RECEIVE:
  163. hello_text: str = friendship.hello()
  164. # accept friendship when there is a keyword in hello text
  165. if 'wechaty' in hello_text.lower():
  166. await friendship.accept()
  167. # 2. you have a new friend to your contact list
  168. elif friendship.type() == FriendshipType.FRIENDSHIP_TYPE_CONFIRM:
  169. # 2.1 invite the user to wechaty group
  170. # find the topic of room which contains Wechaty keyword
  171. wechaty_rooms: List[Room] = await self.Room.find_all('Wechaty')
  172. # 2.2 find the suitable room
  173. for wechaty_room in wechaty_rooms:
  174. members: List[Contact] = await wechaty_room.member_list()
  175. if len(members) < MAX_ROOM_MEMBER_COUNT:
  176. contact: Contact = friendship.contact()
  177. await wechaty_room.add(contact)
  178. break
  179. async def on_room_join(self, room: Room, invitees: List[Contact],
  180. inviter: Contact, date: datetime) -> None:
  181. """on_room_join when there are new contacts to the room
  182. Args:
  183. room (Room): the room instance
  184. invitees (List[Contact]): the new contacts to the room
  185. inviter (Contact): the inviter who share qrcode or manual invite someone
  186. date (datetime): the datetime to join the room
  187. """
  188. # 1. say something to welcome the new arrivals
  189. names: List[str] = []
  190. for invitee in invitees:
  191. await invitee.ready()
  192. names.append(invitee.name)
  193. await room.say(f'welcome {",".join(names)} to the wechaty group !')
  194. async def main() -> None:
  195. """doc"""
  196. bot = MyBot()
  197. await bot.start()
  198. asyncio.run(main())