Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.

90 lines
3.6KB

  1. import asyncio
  2. import re
  3. from wechaty import MessageType
  4. from wechaty.user import Message
  5. from bridge.context import ContextType
  6. from channel.chat_message import ChatMessage
  7. from common.log import logger
  8. from common.tmp_dir import TmpDir
  9. class aobject(object):
  10. """Inheriting this class allows you to define an async __init__.
  11. So you can create objects by doing something like `await MyClass(params)`
  12. """
  13. async def __new__(cls, *a, **kw):
  14. instance = super().__new__(cls)
  15. await instance.__init__(*a, **kw)
  16. return instance
  17. async def __init__(self):
  18. pass
  19. class WechatyMessage(ChatMessage, aobject):
  20. async def __init__(self, wechaty_msg: Message):
  21. super().__init__(wechaty_msg)
  22. room = wechaty_msg.room()
  23. self.msg_id = wechaty_msg.message_id
  24. self.create_time = wechaty_msg.payload.timestamp
  25. self.is_group = room is not None
  26. if wechaty_msg.type() == MessageType.MESSAGE_TYPE_TEXT:
  27. self.ctype = ContextType.TEXT
  28. self.content = wechaty_msg.text()
  29. elif wechaty_msg.type() == MessageType.MESSAGE_TYPE_AUDIO:
  30. self.ctype = ContextType.VOICE
  31. voice_file = await wechaty_msg.to_file_box()
  32. self.content = TmpDir().path() + voice_file.name # content直接存临时目录路径
  33. def func():
  34. loop = asyncio.get_event_loop()
  35. asyncio.run_coroutine_threadsafe(voice_file.to_file(self.content), loop).result()
  36. self._prepare_fn = func
  37. else:
  38. raise NotImplementedError("Unsupported message type: {}".format(wechaty_msg.type()))
  39. from_contact = wechaty_msg.talker() # 获取消息的发送者
  40. self.from_user_id = from_contact.contact_id
  41. self.from_user_nickname = from_contact.name
  42. # group中的from和to,wechaty跟itchat含义不一样
  43. # wecahty: from是消息实际发送者, to:所在群
  44. # itchat: 如果是你发送群消息,from和to是你自己和所在群,如果是别人发群消息,from和to是所在群和你自己
  45. # 但这个差别不影响逻辑,group中只使用到:1.用from来判断是否是自己发的,2.actual_user_id来判断实际发送用户
  46. if self.is_group:
  47. self.to_user_id = room.room_id
  48. self.to_user_nickname = await room.topic()
  49. else:
  50. to_contact = wechaty_msg.to()
  51. self.to_user_id = to_contact.contact_id
  52. self.to_user_nickname = to_contact.name
  53. if self.is_group or wechaty_msg.is_self(): # 如果是群消息,other_user设置为群,如果是私聊消息,而且自己发的,就设置成对方。
  54. self.other_user_id = self.to_user_id
  55. self.other_user_nickname = self.to_user_nickname
  56. else:
  57. self.other_user_id = self.from_user_id
  58. self.other_user_nickname = self.from_user_nickname
  59. if self.is_group: # wechaty群聊中,实际发送用户就是from_user
  60. self.is_at = await wechaty_msg.mention_self()
  61. if not self.is_at: # 有时候复制粘贴的消息,不算做@,但是内容里面会有@xxx,这里做一下兼容
  62. name = wechaty_msg.wechaty.user_self().name
  63. pattern = f"@{re.escape(name)}(\u2005|\u0020)"
  64. if re.search(pattern, self.content):
  65. logger.debug(f"wechaty message {self.msg_id} include at")
  66. self.is_at = True
  67. self.actual_user_id = self.from_user_id
  68. self.actual_user_nickname = self.from_user_nickname