Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

221 Zeilen
7.0KB

  1. from flask import Flask, send_from_directory, request,jsonify
  2. from flask_restful import Api,got_request_exception
  3. from resources.user_resource import UserResource
  4. from resources.messages_resource import MessagesResource
  5. from resources.contacts_resources import DeleteFriendResource,GetFriendsInfoResource
  6. from resources.config_reources import GetWxchatConfigResource ,SaveWxchatConfigResource
  7. from resources.groups_resources import GetGroupsInfoResource
  8. from common.log import logger, log_exception
  9. from common.interceptors import before_request, after_request, handle_exception
  10. import threading
  11. from common import kafka_helper, redis_helper,utils
  12. import logging
  13. from config import load_config
  14. from wechat.biz import start_kafka_consumer_thread
  15. from channel import channel_factory
  16. from wechat import gewe_chat
  17. import os,time,json
  18. from voice.ali.ali_voice import AliVoice
  19. # 自定义错误消息
  20. errors = {
  21. 'UserAlreadyExistsError': {
  22. 'message': "A user with that username already exists.",
  23. 'status': 409,
  24. },
  25. 'ResourceDoesNotExist': {
  26. 'message': "A resource with that ID no longer exists.",
  27. 'status': 410,
  28. 'extra': "Any extra information you want.",
  29. },
  30. }
  31. def worker():
  32. kafka_helper.start()
  33. redis_helper.start()
  34. start_wxchat_thread()
  35. start_kafka_consumer_thread()
  36. def login_or_reconnect(wxchat:gewe_chat.GeWeChatCom, token_id, app_id, hash_key, is_reconnect=False):
  37. """
  38. 封装微信登录或重连的逻辑
  39. """
  40. while True:
  41. if is_reconnect:
  42. logger.info("尝试重连...")
  43. else:
  44. logger.info("获取二维码进行登录...")
  45. qr_code = wxchat.get_login_qr_code(token_id, app_id)
  46. base64_string = qr_code.get('qrImgBase64')
  47. uuid = qr_code.get('uuid')
  48. app_id = app_id or qr_code.get('appId')
  49. start_time = time.time()
  50. wxchat.qrCallback(uuid, base64_string)
  51. while True:
  52. # 如果登录超时,重新获取二维码
  53. if time.time() - start_time > 150:
  54. break
  55. res = wxchat.check_login(token_id, app_id, uuid)
  56. flag = res.get('status')
  57. if flag == 2:
  58. logger.info(f"登录成功: {res}")
  59. login_info = res.get('loginInfo', {})
  60. login_info.update({'appId': app_id, 'uuid': uuid, 'tokenId': token_id})
  61. cleaned_login_info = {k: (v if v is not None else '') for k, v in login_info.items()}
  62. redis_helper.redis_helper.set_hash(hash_key, cleaned_login_info)
  63. return login_info
  64. time.sleep(5)
  65. def fetch_and_save_contacts2():
  66. """
  67. 获取联系人列表并保存到缓存
  68. """
  69. wxchat=gewe_chat.wxchat
  70. while True:
  71. login_keys = list(redis_helper.redis_helper.client.scan_iter(match='__AI_OPS_WX__:LOGININFO:*'))
  72. logger.info(f"Fetching login keys: {login_keys}")
  73. # 遍历每一个获取到的登录键
  74. for k in login_keys:
  75. r= redis_helper.redis_helper.get_hash(k)
  76. print(r)
  77. token_id = r.get('tokenId')
  78. app_id = r.get('appId')
  79. wxid = r.get('wxid')
  80. status=r.get('status')
  81. if status=='1':
  82. contacts_list = wxchat.fetch_contacts_list(token_id, app_id)
  83. friend_wxids = contacts_list['friends'][3:] # 可以调整截取范围
  84. #friend_wxids.remove('weixin')
  85. wxchat.save_contacts_brief_to_cache(token_id, app_id, wxid, friend_wxids)
  86. logger.info(f'微信ID {wxid} 登录APPID {app_id} 成功,联系人已定时保存')
  87. chatrooms=contacts_list['chatrooms']
  88. wxchat.save_groups_info_to_cache(token_id, app_id, wxid, chatrooms)
  89. logger.info(f'微信ID {wxid} 登录APPID {app_id} 成功,群信息已定时保存')
  90. else:
  91. logger.info(f'微信ID {wxid} 未登录 {app_id} ,联系人不能定时保存')
  92. time.sleep(3)
  93. time.sleep(60*10)
  94. def start_wxchat_thread():
  95. # gewe_chat.start()
  96. scan_wx_login_info()
  97. # 启动同步联系人线程
  98. threading.Thread(target=fetch_and_save_contacts2).start()
  99. def scan_wx_login_info():
  100. gewe_chat.start()
  101. wxchat = gewe_chat.wxchat
  102. cursor = 0
  103. while True:
  104. cursor, login_keys = redis_helper.redis_helper.client.scan(cursor, match='__AI_OPS_WX__:LOGININFO:*')
  105. for k in login_keys:
  106. r = redis_helper.redis_helper.get_hash(k)
  107. app_id=r.get("appId")
  108. #tel=r.get("mobile")
  109. token_id=r.get("tokenId")
  110. wxid=r.get("wxid")
  111. is_online = wxchat.check_online(token_id, app_id)
  112. if is_online:
  113. logger.info(f'微信ID {wxid} 在APPID {app_id} 已经在线')
  114. else:
  115. # 尝试重连
  116. res = wxchat.reconnection(token_id, app_id)
  117. if res.get('ret') == 200:
  118. logger.info(f'微信ID {wxid} 在APPID {app_id} 重连成功')
  119. # 同步联系人
  120. #fetch_and_save_contacts(wxchat, token_id, app_id, k)
  121. else:
  122. print("重连失败,重新登录...")
  123. print("发送离线消息到kafka")
  124. redis_helper.redis_helper.update_hash_field(k,'status',0)
  125. time.sleep(3)
  126. # 如果游标为 0,则表示扫描完成
  127. if cursor == 0:
  128. break
  129. def app_run():
  130. flask_app = Flask(__name__)
  131. # api = Api(app)
  132. flask_api = Api(flask_app,errors=errors, catch_all_404s=True)
  133. # 设置日志(logger 已在 log.py 中配置)
  134. flask_app.logger.handlers.clear() # 清除 Flask 默认的日志处理器
  135. flask_app.logger.addHandler(logger.handlers[1]) # 使用文件日志处理器
  136. flask_app.logger.setLevel(logging.DEBUG) # 设置日志级别
  137. # 添加拦截器
  138. flask_app.before_request(before_request)
  139. flask_app.after_request(after_request)
  140. flask_app.register_error_handler(Exception, handle_exception)
  141. # 定义路由
  142. flask_api.add_resource(UserResource, '/api/user', '/api/user/<int:user_id>')
  143. flask_api.add_resource(MessagesResource, '/messages')
  144. flask_api.add_resource(DeleteFriendResource, '/api/contacts/deletefriend')
  145. flask_api.add_resource(GetFriendsInfoResource, '/api/contacts/getfriends')
  146. flask_api.add_resource(GetWxchatConfigResource, '/api/wxchat/getconfig')
  147. flask_api.add_resource(SaveWxchatConfigResource, '/api/wxchat/saveconfig')
  148. #
  149. flask_api.add_resource(GetGroupsInfoResource, '/api/groups/getchatroominfo')
  150. load_config()
  151. worker()
  152. # channel = channel_factory.create_channel('wx')
  153. # channel.startup()
  154. environment = os.environ.get('environment', 'default')
  155. port=5000
  156. if environment== 'default':
  157. port=80
  158. flask_app.run(debug=False,host='0.0.0.0',port=port)
  159. if __name__ == '__main__':
  160. app_run()