You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

540 line
26KB

  1. import aiohttp
  2. import asyncio
  3. import json
  4. import base64
  5. import io
  6. import json
  7. import os
  8. import threading
  9. import time
  10. import uuid,random
  11. from fastapi import FastAPI, Depends
  12. from common.log import logger
  13. from common.singleton import singleton
  14. from services.kafka_service import KafkaService
  15. from fastapi import Request
  16. from common.utils import *
  17. from services.redis_service import RedisService
  18. from services.kafka_service import KafkaService
  19. from services.gewe_service import GeWeService
  20. @singleton
  21. class BizService():
  22. def __init__(self,app:FastAPI):
  23. if not hasattr(self, 'initialized'):
  24. #self.kafka_service =kafka_service # 获取 KafkaService 单例
  25. self.kafka_service:KafkaService =app.state.kafka_service
  26. self.wxchat:GeWeService=app.state.gewe_service
  27. self.redis_service:RedisService=app.state.redis_service
  28. self.initialized = True
  29. def setup_handlers(self):
  30. """设置默认的消息处理器"""
  31. # 这里可以添加业务逻辑
  32. # 注册默认处理器
  33. self.kafka_service.add_handler(
  34. self.kafka_service.consumer_topic,
  35. self.ops_messages_process_handler
  36. )
  37. async def ops_messages_process_handler(self, message: str):
  38. """消息处理器"""
  39. #print(f"BizService handling message: {message}")
  40. try:
  41. msg_content = message
  42. cleaned_content = clean_json_string(msg_content)
  43. content = json.loads(cleaned_content)
  44. data = content.get("data", {})
  45. msg_type_data = data.get("msg_type", None)
  46. content_data = data.get("content", {})
  47. # if msg_type_data=="login":
  48. # await self.login_handler_async(content_data)
  49. # elif msg_type_data == 'group-sending':
  50. # print(f'处理消息类型group-sending')
  51. # await self.group_sending_handler_async(content_data)
  52. # elif msg_type_data == 'login_wx_captch_code':
  53. # pass
  54. # elif msg_type_data == 'sns-sendtext-forward':
  55. # pass
  56. # elif msg_type_data == 'sns-sendimages-forward':
  57. # pass
  58. # elif msg_type_data == 'sns-sendvideo-forward':
  59. # pass
  60. # else:
  61. # print(f'kakfa 未处理息类型 {msg_type_data}')
  62. match msg_type_data:
  63. case 'login':
  64. await self.login_handler_async(content_data)
  65. case 'group-sending':
  66. await self.group_sending_handler_async(content_data)
  67. case 'sns-sendtext-forward':
  68. await self.sns_sendtext_forward_handler_async(content_data)
  69. case 'sns-sendtext':
  70. await self.sns_sendtext_handler_async(content_data)
  71. case 'sns-sendimages-forward':
  72. await self.sns_sendimages_forward_handler_async(content_data)
  73. case 'sns-sendimages':
  74. await self.sns_sendimages_handler_async(content_data)
  75. case 'sns-sendvideo-forward':
  76. await self.sns_sendvideo_forward_handler_async(content_data)
  77. case 'sns-sendvideo':
  78. await self.sns_sendvideo_handler_async(content_data)
  79. case _:
  80. logger.warning(f'kakfa 未处理息类型 {msg_type_data}')
  81. except Exception as e:
  82. print(f"处理消息时发生错误: {e}, 消息内容: {message}")
  83. async def login_handler_async(self, content_data: dict):
  84. tel=content_data.get('tel', '18733438393')
  85. token_id=content_data.get('token_id', 'c50b7d57-2efa-4a53-8c11-104a06d1e1fa')
  86. region_id=content_data.get('region_id', '440000')
  87. agent_token_id=content_data.get('agent_token_id', 'sk-fAOIdANeGXjWKW5mFybnsNZZGYU2lFLmqVY9rVFaFmjiOaWt3tcWMi')
  88. loginfo= await self.wxchat.get_login_info_from_cache_async(tel,token_id,region_id,agent_token_id)
  89. print(loginfo)
  90. status=loginfo.get('status','0')
  91. if status=='1':
  92. logger.info(f'手机号{tel},wx_token{token_id} 已经微信登录,终止登录流程')
  93. return
  94. async def group_sending_handler_async(self,content_data: dict):
  95. agent_tel=content_data.get('agent_tel', '18733438393')
  96. hash_key = f"__AI_OPS_WX__:LOGININFO:{agent_tel}"
  97. logininfo = await self.redis_service.get_hash(hash_key)
  98. if not logininfo:
  99. logger.warning(f"未找到 {agent_tel} 的登录信息")
  100. return
  101. token_id = logininfo.get('tokenId')
  102. app_id = logininfo.get('appId')
  103. agent_wxid = logininfo.get('wxid')
  104. # 获取联系人列表并计算交集
  105. hash_key = f"__AI_OPS_WX__:CONTACTS_BRIEF:{agent_wxid}"
  106. cache_friend_wxids_str=await self.redis_service.get_hash_field(hash_key,"data")
  107. cache_friend_wxids_list=json.loads(cache_friend_wxids_str) if cache_friend_wxids_str else []
  108. cache_friend_wxids=[f["userName"] for f in cache_friend_wxids_list]
  109. # 获取群交集
  110. hash_key = f"__AI_OPS_WX__:GROUPS_INFO:{agent_wxid}"
  111. cache_chatrooms = await self.redis_service.get_hash(hash_key)
  112. cache_chatroom_ids=cache_chatrooms.keys()
  113. wxid_contact_list_content_data = [c['wxid'] for c in content_data.get("contact_list", [])]
  114. intersection_friend_wxids = list(set(cache_friend_wxids) & set(wxid_contact_list_content_data))
  115. intersection_chatroom_ids = list(set(cache_chatroom_ids) & set(wxid_contact_list_content_data))
  116. intersection_wxids=intersection_friend_wxids+intersection_chatroom_ids
  117. # 发送消息
  118. wx_content_list = content_data.get("wx_content", [])
  119. self.wxchat.forward_video_aeskey = ''
  120. self.wxchat.forward_video_cdnvideourl = ''
  121. self.wxchat.forward_video_length = 0
  122. self.wxchat.video_duration = 0
  123. self.wxchat.forward_image_aeskey = ''
  124. self.wxchat.forward_image_cdnthumburl = ''
  125. self.wxchat.forward_image_cdnthumblength=0
  126. self.wxchat.forward_image_cdnthumbheight=0
  127. self.wxchat.forward_image_cdnthumbwidth=0
  128. self.wxchat.forward_image_length=0
  129. self.wxchat.forward_image_md5=''
  130. self.wxchat.forward_file_aeskey = ''
  131. for intersection_wxid in intersection_wxids:
  132. for wx_content in wx_content_list:
  133. if wx_content["type"] == "text":
  134. await self.send_text_message_async(token_id, app_id, agent_wxid, [intersection_wxid], wx_content["text"])
  135. elif wx_content["type"] == "image_url":
  136. await self.send_image_messagae_sync(token_id, app_id, agent_wxid, [intersection_wxid], wx_content.get("image_url", {}).get("url"))
  137. elif wx_content["type"] == "tts":
  138. await self.send_tts_message(token_id, app_id, agent_wxid, [intersection_wxid], wx_content["text"])
  139. elif wx_content["type"] == "file":
  140. await self.send_file_message(token_id, app_id, agent_wxid, [intersection_wxid], wx_content.get("file_url", {}).get("url"))
  141. async def send_text_message_async(self, token_id, app_id, agent_wxid, intersection_wxids, text):
  142. for t in intersection_wxids:
  143. # 发送文本消息
  144. ret,ret_msg,res = await self.wxchat.post_text_async(token_id, app_id, t, text)
  145. logger.info(f'{agent_wxid} 向 {t} 发送文字【{text}】')
  146. # 构造对话消息并发送到 Kafka
  147. input_wx_content_dialogue_message = [{"type": "text", "text": text}]
  148. input_message = dialogue_message(agent_wxid, t, input_wx_content_dialogue_message)
  149. await self.kafka_service.send_message_async(input_message)
  150. logger.info("发送对话 %s", input_message)
  151. # 等待随机时间
  152. await asyncio.sleep(random.uniform(1.5, 3))
  153. async def send_image_messagae_sync(self,token_id, app_id, agent_wxid, intersection_wxids, image_url):
  154. #aeskey, cdnthumburl, cdnthumblength, cdnthumbheight, cdnthumbwidth, length, md5 = "", "", 0, 0, 0, 0, ""
  155. for t in intersection_wxids:
  156. if t == intersection_wxids[0]:
  157. # 发送图片
  158. ret,ret_msg,res = await self.wxchat.post_image_async(token_id, app_id, t, image_url)
  159. if ret==200:
  160. self.wxchat.forward_image_aeskey = res["aesKey"]
  161. self.wxchat.forward_image_cdnthumburl = res["fileId"]
  162. self.wxchat.forward_image_cdnthumblength = res["cdnThumbLength"]
  163. self.wxchat.forward_image_cdnthumbheight = res["height"]
  164. self.wxchat.forward_image_cdnthumbwidth = res["width"]
  165. self.wxchat.forward_image_length = res["length"]
  166. self.wxchat.forward_image_md5 = res["md5"]
  167. logger.info(f'{agent_wxid} 向 {t} 发送图片【{image_url}】{ret_msg}')
  168. else:
  169. logger.warning(f'{agent_wxid} 向 {t} 发送图片【{image_url}】{ret_msg}')
  170. else:
  171. if self.wxchat.forward_image_aeskey !="":
  172. # 转发图片
  173. ret,ret_msg,res = await self.wxchat.forward_image_async(token_id, app_id, t, self.wxchat.forward_image_aeskey, self.wxchat.forward_image_cdnthumburl, self.wxchat.forward_image_cdnthumblengt, self.wxchat.forward_image_cdnthumbheight, self.wxchat.forward_image_cdnthumbwidth, self.wxchat.forward_image_length, self.wxchat.forward_image_md5)
  174. logger.info(f'{agent_wxid} 向 {t} 转发图片【{image_url}】{ret_msg}')
  175. else:
  176. # 发送图片
  177. ret,ret_msg,res = await self.wxchat.post_image_async(token_id, app_id, t, image_url)
  178. if ret==200:
  179. self.wxchat.forward_image_aeskey = res["aesKey"]
  180. self.wxchat.forward_image_cdnthumburl = res["fileId"]
  181. self.wxchat.forward_image_cdnthumblength = res["cdnThumbLength"]
  182. self.wxchat.forward_image_cdnthumbheight = res["height"]
  183. self.wxchat.forward_image_cdnthumbwidth = res["width"]
  184. self.wxchat.forward_image_length = res["length"]
  185. self.wxchat.forward_image_md5 = res["md5"]
  186. logger.info(f'{agent_wxid} 向 {t} 发送图片【{image_url}】{ret_msg}')
  187. else:
  188. logger.warning(f'{agent_wxid} 向 {t} 发送图片【{image_url}】{ret_msg}')
  189. # 构造对话消息并发送到 Kafka
  190. wx_content_dialogue_message = [{"type": "image_url", "image_url": {"url": image_url}}]
  191. input_message = dialogue_message(agent_wxid, t, wx_content_dialogue_message)
  192. await self.kafka_service.send_message_async(input_message)
  193. logger.info("发送对话 %s", input_message)
  194. # 等待随机时间
  195. await asyncio.sleep(random.uniform(1.5, 3))
  196. # async def send_image_messagae_sync(self,token_id, app_id, agent_wxid, intersection_wxids, image_url):
  197. # aeskey, cdnthumburl, cdnthumblength, cdnthumbheight, cdnthumbwidth, length, md5 = "", "", 0, 0, 0, 0, ""
  198. # for t in intersection_wxids:
  199. # if t == intersection_wxids[0]:
  200. # # 发送图片
  201. # ret,ret_msg,res = await self.wxchat.post_image_async(token_id, app_id, t, image_url)
  202. # if ret==200:
  203. # aeskey = res["aesKey"]
  204. # cdnthumburl = res["fileId"]
  205. # cdnthumblength = res["cdnThumbLength"]
  206. # cdnthumbheight = res["height"]
  207. # cdnthumbwidth = res["width"]
  208. # length = res["length"]
  209. # md5 = res["md5"]
  210. # logger.info(f'{agent_wxid} 向 {t} 发送图片【{image_url}】{ret_msg}')
  211. # else:
  212. # logger.warning(f'{agent_wxid} 向 {t} 发送图片【{image_url}】{ret_msg}')
  213. # else:
  214. # if aeskey !="":
  215. # # 转发图片
  216. # ret,ret_msg,res = await self.wxchat.forward_image_async(token_id, app_id, t, aeskey, cdnthumburl, cdnthumblength, cdnthumbheight, cdnthumbwidth, length, md5)
  217. # logger.info(f'{agent_wxid} 向 {t} 转发图片【{image_url}】{ret_msg}')
  218. # else:
  219. # # 发送图片
  220. # ret,ret_msg,res = await self.wxchat.post_image_async(token_id, app_id, t, image_url)
  221. # if ret==200:
  222. # aeskey = res["aesKey"]
  223. # cdnthumburl = res["fileId"]
  224. # cdnthumblength = res["cdnThumbLength"]
  225. # cdnthumbheight = res["height"]
  226. # cdnthumbwidth = res["width"]
  227. # length = res["length"]
  228. # md5 = res["md5"]
  229. # logger.info(f'{agent_wxid} 向 {t} 发送图片【{image_url}】{ret_msg}')
  230. # else:
  231. # logger.warning(f'{agent_wxid} 向 {t} 发送图片【{image_url}】{ret_msg}')
  232. # # 构造对话消息并发送到 Kafka
  233. # wx_content_dialogue_message = [{"type": "image_url", "image_url": {"url": image_url}}]
  234. # input_message = dialogue_message(agent_wxid, t, wx_content_dialogue_message)
  235. # await self.kafka_service.send_message_async(input_message)
  236. # logger.info("发送对话 %s", input_message)
  237. # # 等待随机时间
  238. # await asyncio.sleep(random.uniform(1.5, 3))
  239. async def send_tts_message(self, token_id, app_id, agent_wxid, intersection_wxids, text):
  240. voice_during,voice_url=wx_voice(text)
  241. for t in intersection_wxids:
  242. # 发送送语音消息
  243. if voice_url:
  244. ret,ret_msg,res = await self.wxchat.post_voice_async(token_id, app_id, t, voice_url,voice_during)
  245. if ret==200:
  246. logger.info(f'{agent_wxid} 向 {t} 发送语音文本【{text}】{ret_msg}')
  247. # 构造对话消息并发送到 Kafka
  248. input_wx_content_dialogue_message = [{"type": "text", "text": text}]
  249. input_message = dialogue_message(agent_wxid, t, input_wx_content_dialogue_message)
  250. await self.kafka_service.send_message_async(input_message)
  251. logger.info("发送对话 %s", input_message)
  252. else:
  253. logger.warning((f'{agent_wxid} 向 {t} 发送语音文本【{text}】{ret_msg}'))
  254. else:
  255. logger.warning((f'{agent_wxid} 向 {t} 发送语音文本【{text}】出错'))
  256. # 等待随机时间
  257. await asyncio.sleep(random.uniform(1.5, 3))
  258. async def send_file_message(self,token_id, app_id, agent_wxid, intersection_wxids, file_url):
  259. parsed_url = urlparse(file_url)
  260. path = parsed_url.path
  261. # 从路径中提取文件名
  262. filename = path.split('/')[-1]
  263. # 获取扩展名
  264. _, ext = os.path.splitext(filename)
  265. if ext == '.mp4':
  266. await self.send_video_message(token_id, app_id, agent_wxid, intersection_wxids, file_url)
  267. # if ext == '.pdf':
  268. # await self.send_pdf_message_async(token_id, app_id, agent_wxid, intersection_wxids, file_url)
  269. else:
  270. await self.send_other_file_message(token_id, app_id, agent_wxid, intersection_wxids, file_url)
  271. #time.sleep(random.uniform(1.5, 3))
  272. async def send_video_message(self, token_id, app_id, agent_wxid, intersection_wxids, file_url):
  273. for t in intersection_wxids:
  274. # 发送视频消息
  275. parsed_url = urlparse(file_url)
  276. filename = os.path.basename(parsed_url.path)
  277. tmp_file_path = os.path.join(os.getcwd(),'tmp', filename) # 拼接完整路径
  278. thumbnail_path=tmp_file_path.replace('.mp4','.jpg')
  279. if self.wxchat.forward_video_aeskey == '':
  280. video_thumb_url,video_duration =download_video_and_get_thumbnail(file_url,thumbnail_path)
  281. print(f'视频缩略图 {video_thumb_url} 时长 {video_duration}')
  282. ret,ret_msg,res = await self.wxchat.post_video_async(token_id, app_id, t, file_url,video_thumb_url,video_duration)
  283. if ret==200:
  284. self.wxchat.forward_video_aeskey = res["aesKey"]
  285. self.wxchat.forward_video_cdnvideourl = res["cdnThumbUrl"]
  286. self.wxchat.forward_video_length = res["length"]
  287. self.wxchat.video_duration=int(video_duration)
  288. else:
  289. ret,ret_msg,res = await self.wxchat.forward_video_async(token_id, app_id, t, self.wxchat.forward_video_aeskey, self.wxchat.forward_video_cdnvideourl, self.wxchat.forward_video_length,self.wxchat.video_duration)
  290. print('转发视频')
  291. if ret==200:
  292. logger.info(f'{agent_wxid} 向 {t} 发送视频【{file_url}】{ret_msg}')
  293. # 构造对话消息并发送到 Kafka
  294. input_wx_content_dialogue_message = [{"type": "file", "file_url": {"url": file_url}}]
  295. input_message = dialogue_message(agent_wxid, t, input_wx_content_dialogue_message)
  296. await self.kafka_service.send_message_async(input_message)
  297. logger.info("发送对话 %s", input_message)
  298. else:
  299. logger.warning((f'{agent_wxid} 向 {t} 发送视频【{file_url}】{ret_msg}'))
  300. # 等待随机时间
  301. await asyncio.sleep(random.uniform(1.5, 3))
  302. async def send_pdf_message_async(self, token_id, app_id, agent_wxid, intersection_wxids, file_url):
  303. print('send_pdf_message_async')
  304. async def send_other_file_message(self, token_id, app_id, agent_wxid, intersection_wxids, file_url):
  305. parsed_url = urlparse(file_url)
  306. filename = os.path.basename(parsed_url.path)
  307. for t in intersection_wxids:
  308. # 发送文件消息
  309. ret,ret_msg,res = await self.wxchat.post_file_async(token_id, app_id, t, file_url,filename)
  310. if ret==200:
  311. logger.info(f'{agent_wxid} 向 {t} 发送文件【{file_url}】{ret_msg}')
  312. # 构造对话消息并发送到 Kafka
  313. input_wx_content_dialogue_message = [{"type": "file", "file_url": {"url": file_url}}]
  314. input_message = dialogue_message(agent_wxid, t, input_wx_content_dialogue_message)
  315. await self.kafka_service.send_message_async(input_message)
  316. logger.info("发送对话 %s", input_message)
  317. else:
  318. logger.warning((f'{agent_wxid} 向 {t} 发送文件【{file_url}】{ret_msg}'))
  319. # 等待随机时间
  320. await asyncio.sleep(random.uniform(1.5, 3))
  321. async def sns_sendtext_forward_handler_async(self,content_data):
  322. wxids=content_data.get('wxids',[])
  323. wx_sns_content_text=content_data.get("wx_sns_content",{}).get("text","")
  324. if not wx_sns_content_text:
  325. logger.warning(f'转发文本消息为空不处理 {wx_sns_content_text}')
  326. return
  327. if not wxids:
  328. logger.warning(f'wxids 空列表不处理 {wxids}')
  329. return
  330. tasks = []
  331. for wxid in wxids:
  332. loginfo=await self.wx_auth_required_time_async(wxid)
  333. if not loginfo:
  334. continue
  335. app_id=loginfo.get('appId','')
  336. token_id=loginfo.get('tokenId','')
  337. tasks.append(self.wxchat.send_text_sns_async(token_id, app_id, wx_sns_content_text))
  338. await asyncio.gather(*tasks)
  339. async def sns_sendimages_forward_handler_async(self,content_data):
  340. wxids=content_data.get('wxids',[])
  341. wx_sns_content_text=content_data.get("wx_sns_content",{}).get("text","")
  342. wx_sns_content_imgs=content_data.get("wx_sns_content",{}).get("imageUrls",[])
  343. if not wx_sns_content_imgs:
  344. logger.warning(f'转发图片消息为空不处理 {wx_sns_content_imgs}')
  345. return
  346. tasks = []
  347. for wxid in wxids:
  348. loginfo=await self.wx_auth_required_time_async(wxid)
  349. if not loginfo:
  350. continue
  351. app_id=loginfo.get('appId','')
  352. token_id=loginfo.get('tokenId','')
  353. tasks.append(self.wxchat.upload_send_image_sns_async(token_id, app_id, wx_sns_content_text,wx_sns_content_imgs))
  354. await asyncio.gather(*tasks)
  355. async def sns_sendvideo_forward_handler_async(self,content_data):
  356. wxids=content_data.get('wxids',[])
  357. wx_sns_content_text=content_data.get("wx_sns_content",{}).get("text","")
  358. wx_sns_content_video_url=content_data.get("wx_sns_content",{}).get("videoUrl","")
  359. wx_sns_content_thumb_url=content_data.get("wx_sns_content",{}).get("videoThumbUrl","")
  360. if not wx_sns_content_thumb_url:
  361. logger.warning(f'转发视频缩略图消息为空不处理 {wx_sns_content_thumb_url}')
  362. return
  363. if not wx_sns_content_video_url:
  364. logger.warning(f'转发视频消息为空不处理 {wx_sns_content_video_url}')
  365. return
  366. if not wx_sns_content_thumb_url:
  367. logger.warning(f'转发视频缩略图消息为空不处理 {wx_sns_content_thumb_url}')
  368. return
  369. tasks = []
  370. for wxid in wxids:
  371. loginfo=await self.wx_auth_required_time_async(wxid)
  372. if not loginfo:
  373. continue
  374. app_id=loginfo.get('appId','')
  375. token_id=loginfo.get('tokenId','')
  376. tasks.append(self.wxchat.upload_send_video_sns_async(token_id, app_id,wx_sns_content_text,wx_sns_content_video_url,wx_sns_content_thumb_url))
  377. await asyncio.gather(*tasks)
  378. async def sns_sendtext_handler_async(self,content_data):
  379. wxid=content_data.get('wxid','')
  380. wx_sns_content_text=content_data.get("wx_sns_content",{}).get("text","")
  381. if not wx_sns_content_text:
  382. logger.warning(f'转发文本消息为空不处理 {wx_sns_content_text}')
  383. return
  384. if not wxid:
  385. logger.warning(f'wxid 空不处理 {wxid}')
  386. return
  387. loginfo=await self.wx_auth_required_time_async(wxid)
  388. if not loginfo:
  389. return
  390. app_id=loginfo.get('appId','')
  391. token_id=loginfo.get('tokenId','')
  392. await self.wxchat.send_text_sns_async(token_id, app_id, wx_sns_content_text)
  393. async def sns_sendimages_handler_async(self,content_data):
  394. wxid=content_data.get('wxid','')
  395. wx_sns_content_text=content_data.get("wx_sns_content",{}).get("text","")
  396. wx_sns_content_imgs=content_data.get("wx_sns_content",{}).get("imageUrls",[])
  397. if not wx_sns_content_imgs:
  398. logger.warning(f'转发图片消息为空不处理 {wx_sns_content_imgs}')
  399. return
  400. if not wxid:
  401. logger.warning(f'wxid 空不处理 {wxid}')
  402. return
  403. loginfo=await self.wx_auth_required_time_async(wxid)
  404. if not loginfo:
  405. return
  406. app_id=loginfo.get('appId','')
  407. token_id=loginfo.get('tokenId','')
  408. await self.wxchat.upload_send_image_sns_async(token_id, app_id, wx_sns_content_text,wx_sns_content_imgs)
  409. async def sns_sendvideo_handler_async(self,content_data):
  410. wxid=content_data.get('wxid','')
  411. wx_sns_content_text=content_data.get("wx_sns_content",{}).get("text","")
  412. wx_sns_content_video_url=content_data.get("wx_sns_content",{}).get("videoUrl","")
  413. wx_sns_content_thumb_url=content_data.get("wx_sns_content",{}).get("videoThumbUrl","")
  414. if not wx_sns_content_thumb_url:
  415. logger.warning(f'转发视频缩略图消息为空不处理 {wx_sns_content_thumb_url}')
  416. return
  417. if not wx_sns_content_video_url:
  418. logger.warning(f'转发视频消息为空不处理 {wx_sns_content_video_url}')
  419. return
  420. if not wx_sns_content_thumb_url:
  421. logger.warning(f'转发视频缩略图消息为空不处理 {wx_sns_content_thumb_url}')
  422. return
  423. if not wxid:
  424. logger.warning(f'wxid 空不处理 {wxid}')
  425. return
  426. loginfo=await self.wx_auth_required_time_async(wxid)
  427. if not loginfo:
  428. return
  429. app_id=loginfo.get('appId','')
  430. token_id=loginfo.get('tokenId','')
  431. await self.wxchat.upload_send_video_sns_async(token_id, app_id,wx_sns_content_text,wx_sns_content_video_url,wx_sns_content_thumb_url)
  432. async def wx_auth_required_time_async(self,wxid:str)->dict:
  433. if not wxid:
  434. logger.warning(f'wxid 不能为空')
  435. return None
  436. # 模拟获取登录信息
  437. k, loginfo = await self.wxchat.get_login_info_by_wxid_async(wxid)
  438. if not loginfo:
  439. logger.warning(f'{wxid} 微信信息不存在')
  440. return None
  441. login_status = loginfo.get('status', '0')
  442. if login_status != '1':
  443. logger.warning(f'{wxid} 已经离线')
  444. return None
  445. creation_timestamp = int(loginfo.get('create_at', time.time()))
  446. current_timestamp = time.time()
  447. three_days_seconds = 3 * 24 * 60 * 60 # 三天的秒数
  448. diff_flag = (current_timestamp - creation_timestamp) >= three_days_seconds
  449. if not diff_flag:
  450. logger.warning(f'{wxid} 用户创建不够三天,不能使用该功能')
  451. return None
  452. return loginfo