From 1225b6cbf0a028b765a0ab6d784bcb80459a67bb Mon Sep 17 00:00:00 2001 From: yj <2077506045@qq.com> Date: 星期三, 23 七月 2025 17:59:54 +0800 Subject: [PATCH] 功能更新 --- app/services/ecloud_client.py | 234 ++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 files changed, 203 insertions(+), 31 deletions(-) diff --git a/app/services/ecloud_client.py b/app/services/ecloud_client.py index 5a76116..42495c3 100644 --- a/app/services/ecloud_client.py +++ b/app/services/ecloud_client.py @@ -3,7 +3,7 @@ """ import requests -from typing import Optional, Dict, Any +from typing import Optional, Dict, Any, List from loguru import logger from config import settings @@ -26,10 +26,12 @@ Args: w_id: 鐧诲綍瀹炰緥鏍囪瘑 - wc_id: 濂藉弸寰俊id/缇d + wc_id: 濂藉弸寰俊id/缇d锛屽涓娇鐢ㄨ嫳鏂囬�楀彿鍒嗛殧 Returns: - 鑱旂郴浜轰俊鎭瓧鍏革紝澶辫触杩斿洖None + 鑱旂郴浜轰俊鎭瓧鍏告垨鍒楄〃锛屽け璐ヨ繑鍥濶one + - 鍗曚釜wcId鏃惰繑鍥炲瓧鍏� + - 澶氫釜wcId鏃惰繑鍥炲垪琛� """ try: url = f"{self.base_url}/getContact" @@ -45,8 +47,14 @@ if result.get("code") == "1000": contact_data = result.get("data", []) if contact_data and len(contact_data) > 0: - logger.info(f"鎴愬姛鑾峰彇鑱旂郴浜轰俊鎭�: wcId={wc_id}") - return contact_data[0] # 杩斿洖绗竴涓仈绯讳汉淇℃伅 + # 濡傛灉鏄崟涓獁cId锛岃繑鍥炵涓�涓仈绯讳汉淇℃伅 + if "," not in wc_id: + logger.info(f"鎴愬姛鑾峰彇鑱旂郴浜轰俊鎭�: wcId={wc_id}") + return contact_data[0] + else: + # 濡傛灉鏄涓獁cId锛岃繑鍥炲畬鏁村垪琛� + logger.info(f"鎴愬姛鑾峰彇鎵归噺鑱旂郴浜轰俊鎭�: count={len(contact_data)}") + return contact_data else: logger.warning(f"鑱旂郴浜轰俊鎭负绌�: wcId={wc_id}") return None @@ -63,7 +71,7 @@ logger.error(f"鑾峰彇鑱旂郴浜轰俊鎭紓甯�: wcId={wc_id}, error={str(e)}") return None - def send_text_message(self, w_id: str, wc_id: str, content: str) -> bool: + def send_text_message(self, w_id: str, wc_id: str, content: str, max_retries: int = None) -> bool: """ 鍙戦�佹枃鏈秷鎭� @@ -71,38 +79,55 @@ w_id: 鐧诲綍瀹炰緥鏍囪瘑 wc_id: 鎺ユ敹浜哄井淇d/缇d content: 鏂囨湰鍐呭娑堟伅 + max_retries: 鏈�澶ч噸璇曟鏁� Returns: 鍙戦�佹垚鍔熻繑鍥濼rue锛屽け璐ヨ繑鍥濬alse """ - try: - url = f"{self.base_url}/sendText" - payload = {"wId": w_id, "wcId": wc_id, "content": content} + if max_retries is None: + from config import settings + max_retries = settings.max_retry_count + + retry_count = 0 + while retry_count <= max_retries: + try: + url = f"{self.base_url}/sendText" + payload = {"wId": w_id, "wcId": wc_id, "content": content} - logger.info( - f"鍙戦�佹枃鏈秷鎭�: wId={w_id}, wcId={wc_id}, content_length={len(content)}" - ) - - response = self.session.post(url, json=payload, timeout=30) - response.raise_for_status() - - result = response.json() - - if result.get("code") == "1000": - logger.info(f"鏂囨湰娑堟伅鍙戦�佹垚鍔�: wcId={wc_id}") - return True - else: - logger.error( - f"鏂囨湰娑堟伅鍙戦�佸け璐�: wcId={wc_id}, code={result.get('code')}, message={result.get('message')}" + logger.info( + f"鍙戦�佹枃鏈秷鎭�: wId={w_id}, wcId={wc_id}, content_length={len(content)}, retry={retry_count}" ) - return False - except requests.exceptions.RequestException as e: - logger.error(f"鍙戦�佹枃鏈秷鎭綉缁滈敊璇�: wcId={wc_id}, error={str(e)}") - return False - except Exception as e: - logger.error(f"鍙戦�佹枃鏈秷鎭紓甯�: wcId={wc_id}, error={str(e)}") - return False + response = self.session.post(url, json=payload, timeout=30) + response.raise_for_status() + + result = response.json() + + if result.get("code") == "1000": + logger.info(f"鏂囨湰娑堟伅鍙戦�佹垚鍔�: wcId={wc_id}") + return True + else: + logger.error( + f"鏂囨湰娑堟伅鍙戦�佸け璐�: wcId={wc_id}, code={result.get('code')}, message={result.get('message')}" + ) + + except requests.exceptions.RequestException as e: + logger.error(f"鍙戦�佹枃鏈秷鎭綉缁滈敊璇�: wcId={wc_id}, retry={retry_count}, error={str(e)}") + except Exception as e: + logger.error(f"鍙戦�佹枃鏈秷鎭紓甯�: wcId={wc_id}, retry={retry_count}, error={str(e)}") + + retry_count += 1 + if retry_count <= max_retries: + from config import settings + wait_time = settings.retry_delay * retry_count + logger.info(f"绛夊緟閲嶈瘯: wcId={wc_id}, wait_time={wait_time}s") + import time + time.sleep(wait_time) + + logger.error( + f"鏂囨湰娑堟伅鍙戦�佸け璐ワ紝宸茶揪鏈�澶ч噸璇曟鏁�: wcId={wc_id}, max_retries={max_retries}" + ) + return False def send_group_message(self, w_id: str, group_id: str, content: str) -> bool: """ @@ -118,6 +143,153 @@ """ return self.send_text_message(w_id, group_id, content) + def init_address_list(self, w_id: str) -> bool: + """ + 鍒濆鍖栭�氳褰曞垪琛� + + Args: + w_id: 鐧诲綍瀹炰緥鏍囪瘑 + + Returns: + 鍒濆鍖栨垚鍔熻繑鍥濼rue锛屽け璐ヨ繑鍥濬alse + """ + try: + url = f"{self.base_url}/initAddressList" + payload = {"wId": w_id} + + logger.info(f"鍒濆鍖栭�氳褰曞垪琛�: wId={w_id}") + + response = self.session.post(url, json=payload, timeout=30) + response.raise_for_status() + + result = response.json() + + if result.get("code") == "1000": + logger.info(f"鍒濆鍖栭�氳褰曞垪琛ㄦ垚鍔�: wId={w_id}") + return True + else: + logger.error( + f"鍒濆鍖栭�氳褰曞垪琛ㄥけ璐�: wId={w_id}, code={result.get('code')}, message={result.get('message')}" + ) + return False + + except requests.exceptions.RequestException as e: + logger.error(f"鍒濆鍖栭�氳褰曞垪琛ㄧ綉缁滈敊璇�: wId={w_id}, error={str(e)}") + return False + except Exception as e: + logger.error(f"鍒濆鍖栭�氳褰曞垪琛ㄥ紓甯�: wId={w_id}, error={str(e)}") + return False + + def get_address_list(self, w_id: str) -> Optional[Dict[str, Any]]: + """ + 鑾峰彇閫氳褰曞垪琛� + + Args: + w_id: 鐧诲綍瀹炰緥鏍囪瘑 + + Returns: + 閫氳褰曟暟鎹瓧鍏革紝澶辫触杩斿洖None + 杩斿洖鏍煎紡: { + "chatrooms": [...], # 缇ょ粍鍒楄〃 + "friends": [...], # 濂藉弸鍒楄〃 + "ghs": [...], # 鍏紬鍙峰垪琛� + "others": [...] # 鍏朵粬 + } + """ + try: + url = f"{self.base_url}/getAddressList" + payload = {"wId": w_id} + + logger.info(f"鑾峰彇閫氳褰曞垪琛�: wId={w_id}") + + response = self.session.post(url, json=payload, timeout=30) + response.raise_for_status() + + result = response.json() + + if result.get("code") == "1000": + address_data = result.get("data", {}) + logger.info(f"鎴愬姛鑾峰彇閫氳褰曞垪琛�: wId={w_id}, friends_count={len(address_data.get('friends', []))}") + return address_data + else: + logger.error( + f"鑾峰彇閫氳褰曞垪琛ㄥけ璐�: wId={w_id}, code={result.get('code')}, message={result.get('message')}" + ) + return None + + except requests.exceptions.RequestException as e: + logger.error(f"鑾峰彇閫氳褰曞垪琛ㄧ綉缁滈敊璇�: wId={w_id}, error={str(e)}") + return None + except Exception as e: + logger.error(f"鑾峰彇閫氳褰曞垪琛ㄥ紓甯�: wId={w_id}, error={str(e)}") + return None + + def send_group_at_message(self, w_id: str, wc_id: str, content: str, at_wc_ids: List[str], max_retries: int = None) -> bool: + """ + 鍙戦�佺兢鑱夽娑堟伅 + + Args: + w_id: 鐧诲綍瀹炰緥鏍囪瘑 + wc_id: 鎺ユ敹鏂圭兢id + content: 鏂囨湰鍐呭娑堟伅锛園鐨勫井淇℃樀绉伴渶瑕佽嚜宸辨嫾鎺ワ紝蹇呴』鎷兼帴鑹剧壒绗﹀彿锛屼笉鐒朵笉鐢熸晥锛� + at_wc_ids: 鑹剧壒鐨勫井淇d鍒楄〃 + max_retries: 鏈�澶ч噸璇曟鏁� + + Returns: + 鍙戦�佹垚鍔熻繑鍥濼rue锛屽け璐ヨ繑鍥濬alse + """ + if max_retries is None: + from config import settings + max_retries = settings.max_retry_count + + retry_count = 0 + while retry_count <= max_retries: + try: + url = f"{self.base_url}/sendText" + # 灏哸t_wc_ids鍒楄〃鐢ㄩ�楀彿鎷兼帴 + at_str = ",".join(at_wc_ids) + payload = { + "wId": w_id, + "wcId": wc_id, + "content": content, + "at": at_str + } + + logger.info( + f"鍙戦�佺兢鑱夽娑堟伅: wId={w_id}, wcId={wc_id}, at={at_str}, content_length={len(content)}, retry={retry_count}" + ) + + response = self.session.post(url, json=payload, timeout=30) + response.raise_for_status() + + result = response.json() + + if result.get("code") == "1000": + logger.info(f"缇よ亰@娑堟伅鍙戦�佹垚鍔�: wcId={wc_id}, at={at_str}") + return True + else: + logger.error( + f"缇よ亰@娑堟伅鍙戦�佸け璐�: wcId={wc_id}, at={at_str}, code={result.get('code')}, message={result.get('message')}" + ) + + except requests.exceptions.RequestException as e: + logger.error(f"鍙戦�佺兢鑱夽娑堟伅缃戠粶閿欒: wcId={wc_id}, at={at_str}, retry={retry_count}, error={str(e)}") + except Exception as e: + logger.error(f"鍙戦�佺兢鑱夽娑堟伅寮傚父: wcId={wc_id}, at={at_str}, retry={retry_count}, error={str(e)}") + + retry_count += 1 + if retry_count <= max_retries: + from config import settings + wait_time = settings.retry_delay * retry_count + logger.info(f"绛夊緟閲嶈瘯: wcId={wc_id}, wait_time={wait_time}s") + import time + time.sleep(wait_time) + + logger.error( + f"缇よ亰@娑堟伅鍙戦�佸け璐ワ紝宸茶揪鏈�澶ч噸璇曟鏁�: wcId={wc_id}, at={at_str}, max_retries={max_retries}" + ) + return False + # 鍏ㄥ眬E浜戠瀹跺鎴风瀹炰緥 ecloud_client = ECloudClient() -- Gitblit v1.9.1