diff --git a/.gitignore b/.gitignore index a863e36ec..4b683ee8b 100644 --- a/.gitignore +++ b/.gitignore @@ -26,3 +26,4 @@ venv/* packages/python_interpreter/workplace .venv/* .conda/ +.idea \ No newline at end of file diff --git a/astrbot/core/platform/sources/gewechat/client.py b/astrbot/core/platform/sources/gewechat/client.py index 6c7bd0a23..985185b12 100644 --- a/astrbot/core/platform/sources/gewechat/client.py +++ b/astrbot/core/platform/sources/gewechat/client.py @@ -1,17 +1,19 @@ -import threading import asyncio -import aiohttp -import quart import base64 import datetime -import re import os +import re +import threading + +import aiohttp import anyio -from astrbot.api.platform import AstrBotMessage, MessageMember, MessageType -from astrbot.api.message_components import Plain, Image, At, Record +import quart + from astrbot.api import logger, sp -from .downloader import GeweDownloader +from astrbot.api.message_components import Plain, Image, At, Record +from astrbot.api.platform import AstrBotMessage, MessageMember, MessageType from astrbot.core.utils.io import download_image_by_url +from .downloader import GeweDownloader class SimpleGewechatClient: @@ -22,12 +24,12 @@ class SimpleGewechatClient: """ def __init__( - self, - base_url: str, - nickname: str, - host: str, - port: int, - event_queue: asyncio.Queue, + self, + base_url: str, + nickname: str, + host: str, + port: int, + event_queue: asyncio.Queue, ): self.base_url = base_url if self.base_url.endswith("/"): @@ -137,8 +139,8 @@ class SimpleGewechatClient: # at msg_source = d["MsgSource"] if ( - f"" in msg_source - or f"" in msg_source + f"" in msg_source + or f"" in msg_source ): at_me = True if "在群聊中@了你" in d.get("PushContent", ""): @@ -155,8 +157,8 @@ class SimpleGewechatClient: user_real_name = "unknown" if abm.group_id: if ( - abm.group_id not in self.userrealnames - or user_id not in self.userrealnames[abm.group_id] + abm.group_id not in self.userrealnames + or user_id not in self.userrealnames[abm.group_id] ): # 获取群成员列表,并且缓存 if abm.group_id not in self.userrealnames: @@ -250,9 +252,9 @@ class SimpleGewechatClient: await asyncio.sleep(3) async with aiohttp.ClientSession() as session: async with session.post( - f"{self.base_url}/tools/setCallback", - headers=self.headers, - json={"token": self.token, "callbackUrl": self.callback_url}, + f"{self.base_url}/tools/setCallback", + headers=self.headers, + json={"token": self.token, "callbackUrl": self.callback_url}, ) as resp: json_blob = await resp.json() logger.info(f"设置回调结果: {json_blob}") @@ -280,9 +282,9 @@ class SimpleGewechatClient: # /login/checkOnline async with aiohttp.ClientSession() as session: async with session.post( - f"{self.base_url}/login/checkOnline", - headers=self.headers, - json={"appId": appid}, + f"{self.base_url}/login/checkOnline", + headers=self.headers, + json={"appId": appid}, ) as resp: json_blob = await resp.json() return json_blob["data"] @@ -293,9 +295,9 @@ class SimpleGewechatClient: if online: async with aiohttp.ClientSession() as session: async with session.post( - f"{self.base_url}/login/logout", - headers=self.headers, - json={"appId": self.appid}, + f"{self.base_url}/login/logout", + headers=self.headers, + json={"appId": self.appid}, ) as resp: json_blob = await resp.json() logger.info(f"登出结果: {json_blob}") @@ -327,9 +329,9 @@ class SimpleGewechatClient: try: async with aiohttp.ClientSession() as session: async with session.post( - f"{self.base_url}/login/getLoginQrCode", - headers=self.headers, - json=payload, + f"{self.base_url}/login/getLoginQrCode", + headers=self.headers, + json=payload, ) as resp: json_blob = await resp.json() if json_blob["ret"] != 200: @@ -378,9 +380,9 @@ class SimpleGewechatClient: async with aiohttp.ClientSession() as session: async with session.post( - f"{self.base_url}/login/checkLogin", - headers=self.headers, - json=payload, + f"{self.base_url}/login/checkLogin", + headers=self.headers, + json=payload, ) as resp: json_blob = await resp.json() logger.info(f"检查登录状态: {json_blob}") @@ -419,9 +421,9 @@ class SimpleGewechatClient: async with aiohttp.ClientSession() as session: async with session.post( - f"{self.base_url}/group/getChatroomMemberList", - headers=self.headers, - json=payload, + f"{self.base_url}/group/getChatroomMemberList", + headers=self.headers, + json=payload, ) as resp: json_blob = await resp.json() return json_blob["data"] @@ -437,7 +439,7 @@ class SimpleGewechatClient: async with aiohttp.ClientSession() as session: async with session.post( - f"{self.base_url}/message/postText", headers=self.headers, json=payload + f"{self.base_url}/message/postText", headers=self.headers, json=payload ) as resp: json_blob = await resp.json() logger.debug(f"发送消息结果: {json_blob}") @@ -451,7 +453,7 @@ class SimpleGewechatClient: async with aiohttp.ClientSession() as session: async with session.post( - f"{self.base_url}/message/postImage", headers=self.headers, json=payload + f"{self.base_url}/message/postImage", headers=self.headers, json=payload ) as resp: json_blob = await resp.json() logger.debug(f"发送图片结果: {json_blob}") @@ -468,7 +470,7 @@ class SimpleGewechatClient: async with aiohttp.ClientSession() as session: async with session.post( - f"{self.base_url}/message/postVoice", headers=self.headers, json=payload + f"{self.base_url}/message/postVoice", headers=self.headers, json=payload ) as resp: json_blob = await resp.json() logger.debug(f"发送语音结果: {json_blob}") @@ -483,7 +485,7 @@ class SimpleGewechatClient: async with aiohttp.ClientSession() as session: async with session.post( - f"{self.base_url}/message/postFile", headers=self.headers, json=payload + f"{self.base_url}/message/postFile", headers=self.headers, json=payload ) as resp: json_blob = await resp.json() logger.debug(f"发送文件结果: {json_blob}") @@ -501,9 +503,9 @@ class SimpleGewechatClient: async with aiohttp.ClientSession() as session: async with session.post( - f"{self.base_url}/contacts/addContacts", - headers=self.headers, - json=payload, + f"{self.base_url}/contacts/addContacts", + headers=self.headers, + json=payload, ) as resp: json_blob = await resp.json() logger.debug(f"申请添加好友结果: {json_blob}") @@ -517,9 +519,9 @@ class SimpleGewechatClient: async with aiohttp.ClientSession() as session: async with session.post( - f"{self.base_url}/group/getChatroomInfo", - headers=self.headers, - json=payload, + f"{self.base_url}/group/getChatroomInfo", + headers=self.headers, + json=payload, ) as resp: json_blob = await resp.json() logger.debug(f"获取群信息结果: {json_blob}") @@ -533,29 +535,68 @@ class SimpleGewechatClient: async with aiohttp.ClientSession() as session: async with session.post( - f"{self.base_url}/group/getChatroomMemberList", - headers=self.headers, - json=payload, + f"{self.base_url}/group/getChatroomMemberList", + headers=self.headers, + json=payload, ) as resp: json_blob = await resp.json() logger.debug(f"获取群信息结果: {json_blob}") return json_blob - async def add_group_member_to_friend( - self, group_id: str, to_wxid: str, content: str - ): + async def accept_group_invite(self, url: str): + """同意进群""" payload = { "appId": self.appid, - "chatroomId": group_id, - "content": content, - "memberWxid": to_wxid, + "url": url } async with aiohttp.ClientSession() as session: async with session.post( - f"{self.base_url}/group/addGroupMemberAsFriend", - headers=self.headers, - json=payload, + f"{self.base_url}/group/agreeJoinRoom", + headers=self.headers, + json=payload, + ) as resp: + json_blob = await resp.json() + logger.debug(f"获取群信息结果: {json_blob}") + return json_blob + + async def add_group_member_to_friend(self, group_id: str, to_wxid: str, content: str): + payload = { + "appId": self.appid, + "chatroomId": group_id, + "content": content, + "memberWxid": to_wxid + } + + async with aiohttp.ClientSession() as session: + async with session.post( + f"{self.base_url}/group/addGroupMemberAsFriend", + headers=self.headers, + json=payload, + ) as resp: + json_blob = await resp.json() + logger.debug(f"获取群信息结果: {json_blob}") + return json_blob + + async def get_user_or_group_info(self, *ids): + """ + 获取用户或群组信息。 + + :param ids: 可变数量的 wxid 参数 + """ + + wxids_str = list(ids) + + payload = { + "appId": self.appid, + "wxids": wxids_str # 使用逗号分隔的字符串 + } + + async with aiohttp.ClientSession() as session: + async with session.post( + f"{self.base_url}/contacts/getDetailInfo", + headers=self.headers, + json=payload, ) as resp: json_blob = await resp.json() logger.debug(f"获取群信息结果: {json_blob}") diff --git a/requirements.txt b/requirements.txt index 07b168cc1..ac56e3db4 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,27 +1,33 @@ pydantic~=2.10.3 -aiohttp -openai -anthropic +aiohttp~=3.11.13 +openai~=1.65.5 +anthropic~=0.49.0 qq-botpy chardet~=5.1.0 -Pillow -beautifulsoup4 +Pillow~=11.1.0 +beautifulsoup4~=4.13.3 googlesearch-python -readability-lxml -quart +readability-lxml~=0.8.1 +quart~=0.20.0 lxml_html_clean -colorlog -aiocqhttp -pyjwt -apscheduler -docstring_parser -aiodocker +colorlog~=6.9.0 +aiocqhttp~=1.4.4 +pyjwt~=2.10.1 +apscheduler~=3.11.0 +docstring_parser~=0.16 +aiodocker~=0.24.0 silk-python psutil>=5.8.0 lark-oapi -ormsgpack -cryptography -dashscope -python-telegram-bot -wechatpy -dingtalk-stream \ No newline at end of file +ormsgpack~=1.8.0 +cryptography~=44.0.2 +dashscope~=1.22.2 +python-telegram-bot~=21.11.1 +wechatpy~=1.8.18 +dingtalk-stream +PyYAML~=6.0.2 +pip~=23.2.1 +typing_extensions~=4.12.2 +requests~=2.32.3 +anyio~=4.8.0 +httpx~=0.28.1 \ No newline at end of file