Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. # encoding:utf-8
  2. """
  3. wechat channel
  4. """
  5. import itchat
  6. import json
  7. from itchat.content import *
  8. from channel.channel import Channel
  9. from concurrent.futures import ThreadPoolExecutor
  10. from common.log import logger
  11. from config import conf
  12. import requests
  13. import io
  14. thead_pool = ThreadPoolExecutor(max_workers=8)
  15. @itchat.msg_register(TEXT)
  16. def handler_single_msg(msg):
  17. WechatChannel().handle(msg)
  18. return None
  19. @itchat.msg_register(TEXT, isGroupChat=True)
  20. def handler_group_msg(msg):
  21. WechatChannel().handle_group(msg)
  22. return None
  23. class WechatChannel(Channel):
  24. def __init__(self):
  25. pass
  26. def startup(self):
  27. # login by scan QRCode
  28. itchat.auto_login(enableCmdQR=2)
  29. # start message listener
  30. itchat.run()
  31. def handle(self, msg):
  32. logger.debug("[WX]receive msg: " + json.dumps(msg, ensure_ascii=False))
  33. from_user_id = msg['FromUserName']
  34. to_user_id = msg['ToUserName'] # 接收人id
  35. other_user_id = msg['User']['UserName'] # 对手方id
  36. content = msg['Text']
  37. match_prefix = self.check_prefix(content, conf().get('single_chat_prefix'))
  38. if from_user_id == other_user_id and match_prefix is not None:
  39. # 好友向自己发送消息
  40. if match_prefix != '':
  41. str_list = content.split(match_prefix, 1)
  42. if len(str_list) == 2:
  43. content = str_list[1].strip()
  44. img_match_prefix = self.check_prefix(content, conf().get('image_create_prefix'))
  45. if img_match_prefix:
  46. content = content.split(img_match_prefix, 1)[1].strip()
  47. thead_pool.submit(self._do_send_img, content, from_user_id)
  48. else:
  49. thead_pool.submit(self._do_send, content, from_user_id)
  50. elif to_user_id == other_user_id and match_prefix:
  51. # 自己给好友发送消息
  52. str_list = content.split(match_prefix, 1)
  53. if len(str_list) == 2:
  54. content = str_list[1].strip()
  55. img_match_prefix = self.check_prefix(content, conf().get('image_create_prefix'))
  56. if img_match_prefix:
  57. content = content.split(img_match_prefix, 1)[1].strip()
  58. thead_pool.submit(self._do_send_img, content, to_user_id)
  59. else:
  60. thead_pool.submit(self._do_send, content, to_user_id)
  61. def handle_group(self, msg):
  62. logger.debug("[WX]receive group msg: " + json.dumps(msg, ensure_ascii=False))
  63. group_name = msg['User'].get('NickName', None)
  64. group_id = msg['User'].get('UserName', None)
  65. if not group_name:
  66. return ""
  67. origin_content = msg['Content']
  68. content = msg['Content']
  69. content_list = content.split(' ', 1)
  70. context_special_list = content.split('\u2005', 1)
  71. if len(context_special_list) == 2:
  72. content = context_special_list[1]
  73. elif len(content_list) == 2:
  74. content = content_list[1]
  75. config = conf()
  76. match_prefix = msg['IsAt'] or self.check_prefix(origin_content, config.get('group_chat_prefix')) or self.check_contain(origin_content, config.get('group_chat_keyword'))
  77. if (group_name in config.get('group_name_white_list') or 'ALL_GROUP' in config.get('group_name_white_list') or self.check_contain(group_name, config.get('group_name_keyword_white_list'))) and match_prefix:
  78. img_match_prefix = self.check_prefix(content, conf().get('image_create_prefix'))
  79. if img_match_prefix:
  80. content = content.split(img_match_prefix, 1)[1].strip()
  81. thead_pool.submit(self._do_send_img, content, group_id)
  82. else:
  83. thead_pool.submit(self._do_send_group, content, msg)
  84. def send(self, msg, receiver):
  85. logger.info('[WX] sendMsg={}, receiver={}'.format(msg, receiver))
  86. itchat.send(msg, toUserName=receiver)
  87. def _do_send(self, query, reply_user_id):
  88. try:
  89. if not query:
  90. return
  91. context = dict()
  92. context['from_user_id'] = reply_user_id
  93. reply_text = super().build_reply_content(query, context).strip()
  94. if reply_text:
  95. self.send(conf().get("single_chat_reply_prefix") + reply_text, reply_user_id)
  96. except Exception as e:
  97. logger.exception(e)
  98. def _do_send_img(self, query, reply_user_id):
  99. try:
  100. if not query:
  101. return
  102. context = dict()
  103. context['type'] = 'IMAGE_CREATE'
  104. img_url = super().build_reply_content(query, context)
  105. if not img_url:
  106. return
  107. # 图片下载
  108. pic_res = requests.get(img_url, stream=True)
  109. image_storage = io.BytesIO()
  110. for block in pic_res.iter_content(1024):
  111. image_storage.write(block)
  112. image_storage.seek(0)
  113. # 图片发送
  114. logger.info('[WX] sendImage, receiver={}'.format(reply_user_id))
  115. itchat.send_image(image_storage, reply_user_id)
  116. except Exception as e:
  117. logger.exception(e)
  118. def _do_send_group(self, query, msg):
  119. if not query:
  120. return
  121. context = dict()
  122. context['from_user_id'] = msg['ActualUserName']
  123. reply_text = super().build_reply_content(query, context)
  124. reply_text = '@' + msg['ActualNickName'] + ' ' + reply_text.strip()
  125. if reply_text:
  126. self.send(reply_text, msg['User']['UserName'])
  127. def check_prefix(self, content, prefix_list):
  128. for prefix in prefix_list:
  129. if content.startswith(prefix):
  130. return prefix
  131. return None
  132. def check_contain(self, content, keyword_list):
  133. if not keyword_list:
  134. return None
  135. for ky in keyword_list:
  136. if content.find(ky) != -1:
  137. return True
  138. return None