Skip to content

Commit

Permalink
feat(wechat): add retry mechanism for message requests
Browse files Browse the repository at this point in the history
  • Loading branch information
InfinityPacer committed Oct 25, 2024
1 parent 5d89ad9 commit eff8a6c
Showing 1 changed file with 54 additions and 43 deletions.
97 changes: 54 additions & 43 deletions app/modules/wechat/wechat.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ def get_state(self):
"""
获取状态
"""
return True if self.__get_access_token else False
return True if self.__get_access_token() else False

@retry(Exception, logger=logger)
def __get_access_token(self, force=False):
Expand Down Expand Up @@ -172,23 +172,17 @@ def __send_message(self, title: str, text: str = None,
if not title:
logger.error("消息标题不能为空")
return False

message_url = self._send_msg_url.format(access_token=self.__get_access_token())
if text:
formatted_text = text.replace("\n\n", "\n")
content = f"{title}\n{formatted_text}"
else:
content = title

if link:
content = f"{content}\n点击查看:{link}"

if not userid:
userid = "@all"

# 分块处理逻辑
content_chunks = self.__split_content(content)

# 逐块发送消息
for chunk in content_chunks:
req_json = {
Expand All @@ -202,11 +196,13 @@ def __send_message(self, title: str, text: str = None,
"enable_id_trans": 0,
"enable_duplicate_check": 0
}
result = self.__post_request(message_url, req_json)
if not result:
logger.error(f"发送消息块失败: {chunk}")
try:
# 如果是超长消息,有一个发送失败就全部失败
if not self.__post_request(self._send_msg_url, req_json):
return False
except Exception as e:
logger.error(f"发送消息块失败:{e}")
return False

return True

def __send_image_message(self, title: str, text: str, image_url: str,
Expand All @@ -220,7 +216,6 @@ def __send_image_message(self, title: str, text: str, image_url: str,
:param link: 跳转链接
:return: 发送状态,错误信息
"""
message_url = self._send_msg_url.format(access_token=self.__get_access_token())
if text:
text = text.replace("\n\n", "\n")
if not userid:
Expand All @@ -240,7 +235,11 @@ def __send_image_message(self, title: str, text: str, image_url: str,
]
}
}
return self.__post_request(message_url, req_json)
try:
return self.__post_request(self._send_msg_url, req_json)
except Exception as e:
logger.error(f"发送图文消息失败:{e}")
return False

def send_msg(self, title: str, text: str = "", image: str = "",
userid: str = None, link: str = None) -> Optional[bool]:
Expand Down Expand Up @@ -272,7 +271,6 @@ def send_medias_msg(self, medias: List[MediaInfo], userid: str = "") -> Optional
logger.error("获取微信access_token失败,请检查参数配置")
return None

message_url = self._send_msg_url.format(access_token=self.__get_access_token())
if not userid:
userid = "@all"
articles = []
Expand All @@ -298,7 +296,11 @@ def send_medias_msg(self, medias: List[MediaInfo], userid: str = "") -> Optional
"articles": articles
}
}
return self.__post_request(message_url, req_json)
try:
return self.__post_request(self._send_msg_url, req_json)
except Exception as e:
logger.error(f"发送消息失败:{e}")
return False

def send_torrents_msg(self, torrents: List[Context],
userid: str = "", title: str = "", link: str = None) -> Optional[bool]:
Expand All @@ -314,7 +316,6 @@ def send_torrents_msg(self, torrents: List[Context],
self.__send_message(title=title, userid=userid, link=link)

# 发送列表
message_url = self._send_msg_url.format(access_token=self.__get_access_token())
if not userid:
userid = "@all"
articles = []
Expand Down Expand Up @@ -348,35 +349,41 @@ def send_torrents_msg(self, torrents: List[Context],
"articles": articles
}
}
return self.__post_request(message_url, req_json)
try:
return self.__post_request(self._send_msg_url, req_json)
except Exception as e:
logger.error(f"发送消息失败:{e}")
return False

def __post_request(self, message_url: str, req_json: dict) -> bool:
@retry(Exception, logger=logger)
def __post_request(self, url: str, req_json: dict) -> bool:
"""
向微信发送请求
"""
try:
res = RequestUtils(content_type="application/json").post(
message_url,
data=json.dumps(req_json, ensure_ascii=False).encode("utf-8")
)
if res and res.status_code == 200:
ret_json = res.json()
if ret_json.get("errcode") == 0:
return True
else:
if ret_json.get("errcode") == 42001:
self.__get_access_token(force=True)
logger.error(f"发送请求失败,错误信息:{ret_json.get('errmsg')}")
return False
elif res is not None:
logger.error(f"发送请求失败,错误码:{res.status_code},错误原因:{res.reason}")
return False
url = url.format(access_token=self.__get_access_token())
res = RequestUtils(content_type="application/json").post(
url=url,
data=json.dumps(req_json, ensure_ascii=False).encode("utf-8")
)
if res is None:
error_msg = "发送请求失败,未获取到返回信息"
raise Exception(error_msg)
if res.status_code != 200:
error_msg = f"发送请求失败,错误码:{res.status_code},错误原因:{res.reason}"
raise Exception(error_msg)

ret_json = res.json()
if ret_json.get("errcode") == 0:
return True
else:
if ret_json.get("errcode") == 42001:
self.__get_access_token(force=True)
error_msg = (f"access_token 已过期,尝试重新获取 access_token,"
f"errcode: {ret_json.get('errcode')}, errmsg: {ret_json.get('errmsg')}")
raise Exception(error_msg)
else:
logger.error(f"发送请求失败,未获取到返回信息")
logger.error(f"发送请求失败,错误信息:{ret_json.get('errmsg')}")
return False
except Exception as err:
logger.error(f"发送请求失败,错误信息:{str(err)}")
return False

def create_menus(self, commands: Dict[str, dict]):
"""
Expand Down Expand Up @@ -418,7 +425,7 @@ def create_menus(self, commands: Dict[str, dict]):
}
"""
# 请求URL
req_url = self._create_menu_url.format(access_token=self.__get_access_token(), agentid=self._appid)
req_url = self._create_menu_url.format(access_token="{access_token}", agentid=self._appid)

# 对commands按category分组
category_dict = {}
Expand Down Expand Up @@ -447,9 +454,13 @@ def create_menus(self, commands: Dict[str, dict]):

if buttons:
# 发送请求
self.__post_request(req_url, {
"button": buttons[:3]
})
try:
self.__post_request(req_url, {
"button": buttons[:3]
})
except Exception as e:
logger.error(f"创建菜单失败:{e}")
return False

def delete_menus(self):
"""
Expand Down

0 comments on commit eff8a6c

Please sign in to comment.