From 46072abb41d255a164f4b0f780f99c206efb2320 Mon Sep 17 00:00:00 2001 From: "Junyan Qin (Chin)" Date: Wed, 19 Mar 2025 23:23:56 +0800 Subject: [PATCH 1/8] doc(README): add planning platforms comments (#1219) --- README.md | 3 +++ README_EN.md | 2 ++ README_JP.md | 2 ++ 3 files changed, 7 insertions(+) diff --git a/README.md b/README.md index 0fe96571..7fe8a9a9 100644 --- a/README.md +++ b/README.md @@ -93,6 +93,8 @@ | 钉钉 | ✅ | | | Discord | ✅ | | | Telegram | ✅ | | +| Slack | 🚧 | | +| LINE | 🚧 | | | WhatsApp | 🚧 | | 🚧: 正在开发中 @@ -115,6 +117,7 @@ | [阿里云百炼](https://bailian.console.aliyun.com/) | ✅ | 大模型聚合平台, LLMOps 平台 | | [火山方舟](https://console.volcengine.com/ark/region:ark+cn-beijing/model?vendor=Bytedance&view=LIST_VIEW) | ✅ | 大模型聚合平台, LLMOps 平台 | | [MCP](https://modelcontextprotocol.io/) | ✅ | 支持通过 MCP 协议获取工具 | + ### TTS | 平台/模型 | 备注 | diff --git a/README_EN.md b/README_EN.md index b313579c..8582a097 100644 --- a/README_EN.md +++ b/README_EN.md @@ -90,6 +90,8 @@ Directly use the released version to run, see the [Manual Deployment](https://do | DingTalk | ✅ | | | Discord | ✅ | | | Telegram | ✅ | | +| Slack | 🚧 | | +| LINE | 🚧 | | | WhatsApp | 🚧 | | 🚧: In development diff --git a/README_JP.md b/README_JP.md index c1c6c556..e18bd00e 100644 --- a/README_JP.md +++ b/README_JP.md @@ -89,6 +89,8 @@ LangBotはBTPanelにリストされています。BTPanelをインストール | DingTalk | ✅ | | | Discord | ✅ | | | Telegram | ✅ | | +| Slack | 🚧 | | +| LINE | 🚧 | | | WhatsApp | 🚧 | | 🚧: 開発中 From 808f30675d25ab97f996e163fac8ff60f3c600b9 Mon Sep 17 00:00:00 2001 From: "Junyan Qin (Chin)" Date: Fri, 21 Mar 2025 10:47:32 +0800 Subject: [PATCH 2/8] doc(README): contributors (#1223) --- README.md | 10 ++++++++-- README_EN.md | 8 ++++++-- README_JP.md | 8 ++++++-- 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 7fe8a9a9..9276d63e 100644 --- a/README.md +++ b/README.md @@ -134,9 +134,15 @@ ## 😘 社区贡献 -LangBot 离不开以下贡献者和社区内所有人的贡献,我们欢迎任何形式的贡献和反馈。 - +感谢以下[代码贡献者](https://github.com/RockChinQ/LangBot/graphs/contributors)和社区里其他成员对 LangBot 的贡献: + +以及 LangBot 核心团队成员: + +- [RockChinQ](https://github.com/RockChinQ) +- [the-lazy-me](https://github.com/the-lazy-me) +- [wangcham](https://github.com/wangcham) +- [KaedeSAMA](https://github.com/KaedeSAMA) \ No newline at end of file diff --git a/README_EN.md b/README_EN.md index 8582a097..f777c228 100644 --- a/README_EN.md +++ b/README_EN.md @@ -117,11 +117,15 @@ Directly use the released version to run, see the [Manual Deployment](https://do ## 🤝 Community Contribution -Thanks to the following contributors and everyone in the community for their contributions. - +Thank you for the following [code contributors](https://github.com/RockChinQ/LangBot/graphs/contributors) and other members in the community for their contributions to LangBot: +And the core team members of LangBot: +- [RockChinQ](https://github.com/RockChinQ) +- [the-lazy-me](https://github.com/the-lazy-me) +- [wangcham](https://github.com/wangcham) +- [KaedeSAMA](https://github.com/KaedeSAMA) diff --git a/README_JP.md b/README_JP.md index e18bd00e..9063dcfc 100644 --- a/README_JP.md +++ b/README_JP.md @@ -116,11 +116,15 @@ LangBotはBTPanelにリストされています。BTPanelをインストール ## 🤝 コミュニティ貢献 -以下の貢献者とコミュニティの皆さんの貢献に感謝します。 - +LangBot への貢献に対して、以下の [コード貢献者](https://github.com/RockChinQ/LangBot/graphs/contributors) とコミュニティの他のメンバーに感謝します。 +LangBot の核心チームメンバー: +- [RockChinQ](https://github.com/RockChinQ) +- [the-lazy-me](https://github.com/the-lazy-me) +- [wangcham](https://github.com/wangcham) +- [KaedeSAMA](https://github.com/KaedeSAMA) From cfdd0f8cb21f1fa6716d58fbac8b2cc7edef557c Mon Sep 17 00:00:00 2001 From: WangCham Date: Fri, 21 Mar 2025 14:04:13 +0800 Subject: [PATCH 3/8] fix: Format the code in a standardized way (#1222) --- libs/official_account_api/api.py | 39 ++++++++++++++++--------- pkg/platform/sources/officialaccount.py | 27 ++++------------- 2 files changed, 32 insertions(+), 34 deletions(-) diff --git a/libs/official_account_api/api.py b/libs/official_account_api/api.py index 58c9d067..a8d318dc 100644 --- a/libs/official_account_api/api.py +++ b/libs/official_account_api/api.py @@ -27,7 +27,6 @@ xml_template = """ """ -user_msg_queue = {} class OAClient(): @@ -45,6 +44,7 @@ class OAClient(): } self.access_token_expiry_time = None self.msg_id_map = {} + self.generated_content = {} async def handle_callback_request(self): @@ -87,12 +87,10 @@ class OAClient(): from_user = root.find("FromUserName").text # 发送者 to_user = root.find("ToUserName").text # 机器人 - from pkg.platform.sources import officialaccount - timeout = 4.80 interval = 0.1 while True: - content = officialaccount.generated_content.pop(message_data["MsgId"], None) + content = self.generated_content.pop(message_data["MsgId"], None) if content: response_xml = xml_template.format( to_user=from_user, @@ -172,6 +170,9 @@ class OAClient(): for handler in self._message_handlers[msg_type]: await handler(event) + async def set_message(self,msg_id:int,content:str): + self.generated_content[msg_id] = content + class OAClientForLongerResponse(): @@ -190,6 +191,8 @@ class OAClientForLongerResponse(): } self.access_token_expiry_time = None self.loading_message = LoadingMessage + self.msg_queue = {} + self.user_msg_queue = {} async def handle_callback_request(self): try: @@ -222,17 +225,15 @@ class OAClientForLongerResponse(): from_user = root.find("FromUserName").text to_user = root.find("ToUserName").text - - from pkg.platform.sources import officialaccount as oa - - if oa.msg_queue.get(from_user) and oa.msg_queue[from_user][0]["content"]: - queue_top = oa.msg_queue[from_user].pop(0) + if self.msg_queue.get(from_user) and self.msg_queue[from_user][0]["content"]: + + queue_top = self.msg_queue[from_user].pop(0) queue_content = queue_top["content"] # 弹出用户消息 - if user_msg_queue.get(from_user) and user_msg_queue[from_user]: - user_msg_queue[from_user].pop(0) + if self.user_msg_queue.get(from_user) and self.user_msg_queue[from_user]: + self.user_msg_queue[from_user].pop(0) response_xml = xml_template.format( to_user=from_user, @@ -250,7 +251,7 @@ class OAClientForLongerResponse(): content=self.loading_message ) - if user_msg_queue.get(from_user) and user_msg_queue[from_user][0]["content"]: + if self.user_msg_queue.get(from_user) and self.user_msg_queue[from_user][0]["content"]: return response_xml else: message_data = await self.get_message(xml_msg) @@ -258,7 +259,7 @@ class OAClientForLongerResponse(): if message_data: event = OAEvent.from_payload(message_data) if event: - user_msg_queue.setdefault(from_user,[]).append( + self.user_msg_queue.setdefault(from_user,[]).append( { "content":event.message, } @@ -318,6 +319,18 @@ class OAClientForLongerResponse(): for handler in self._message_handlers[msg_type]: await handler(event) + async def set_message(self,from_user:int,message_id:int,content:str): + if from_user not in self.msg_queue: + self.msg_queue[from_user] = [] + + self.msg_queue[from_user].append( + { + "msg_id":message_id, + "content":content, + } + ) + + diff --git a/pkg/platform/sources/officialaccount.py b/pkg/platform/sources/officialaccount.py index 518794a6..0816824f 100644 --- a/pkg/platform/sources/officialaccount.py +++ b/pkg/platform/sources/officialaccount.py @@ -22,10 +22,6 @@ from ..types import entities as platform_entities from ...command.errors import ParamNotEnoughError -# 生成的ai回答 -generated_content = {} -msg_queue = {} - class OAMessageConverter(adapter.MessageConverter): @staticmethod async def yiri2target(message_chain: platform_message.MessageChain): @@ -69,7 +65,7 @@ class OAEventConverter(adapter.EventConverter): class OfficialAccountAdapter(adapter.MessagePlatformAdapter): - bot : OAClient + bot : OAClient | OAClientForLongerResponse ap : app.Application bot_account_id: str message_converter: OAMessageConverter = OAMessageConverter() @@ -114,26 +110,15 @@ class OfficialAccountAdapter(adapter.MessagePlatformAdapter): async def reply_message(self, message_source: platform_events.FriendMessage, message: platform_message.MessageChain, quote_origin: bool = False): - global generated_content content = await OAMessageConverter.yiri2target( message ) - - generated_content[message_source.message_chain.message_id] = content - - from_user = message_source.sender.id - - - if from_user not in msg_queue: - msg_queue[from_user] = [] - - msg_queue[from_user].append( - { - "msg_id":message_source.message_chain.message_id, - "content":content, - } - ) + if type(self.bot) == OAClient: + await self.bot.set_message(message_source.message_chain.message_id,content) + if type(self.bot) == OAClientForLongerResponse: + from_user = message_source.sender.id + await self.bot.set_message(from_user,message_source.message_chain.message_id,content) async def send_message( From edbc59c117a7f4e6e844165b216f4a62dcfe13a2 Mon Sep 17 00:00:00 2001 From: "Junyan Qin (Chin)" Date: Mon, 24 Mar 2025 14:03:44 +0800 Subject: [PATCH 4/8] perf: use source_platform_object to pass source event in aiocqhttp (#1230) --- pkg/platform/sources/aiocqhttp.py | 69 +++---------------------------- 1 file changed, 5 insertions(+), 64 deletions(-) diff --git a/pkg/platform/sources/aiocqhttp.py b/pkg/platform/sources/aiocqhttp.py index 4fa730d0..af14372a 100644 --- a/pkg/platform/sources/aiocqhttp.py +++ b/pkg/platform/sources/aiocqhttp.py @@ -57,7 +57,7 @@ class AiocqhttpMessageConverter(adapter.MessageConverter): elif msg.path: arg = msg.path msg_list.append(aiocqhttp.MessageSegment.record(msg.path)) - elif type(msg) is forward.Forward: + elif type(msg) is platform_message.Forward: for node in msg.node_list: msg_list.extend((await AiocqhttpMessageConverter.yiri2target(node.message_chain))[0]) @@ -101,69 +101,8 @@ class AiocqhttpMessageConverter(adapter.MessageConverter): class AiocqhttpEventConverter(adapter.EventConverter): @staticmethod - async def yiri2target(event: platform_events.Event, bot_account_id: int): - - msg, msg_id, msg_time = await AiocqhttpMessageConverter.yiri2target(event.message_chain) - - if type(event) is platform_events.GroupMessage: - role = "member" - - if event.sender.permission == "ADMINISTRATOR": - role = "admin" - elif event.sender.permission == "OWNER": - role = "owner" - - payload = { - "post_type": "message", - "message_type": "group", - "time": int(msg_time.timestamp()), - "self_id": bot_account_id, - "sub_type": "normal", - "anonymous": None, - "font": 0, - "message": str(msg), - "raw_message": str(msg), - "sender": { - "age": 0, - "area": "", - "card": "", - "level": "", - "nickname": event.sender.member_name, - "role": role, - "sex": "unknown", - "title": "", - "user_id": event.sender.id, - }, - "user_id": event.sender.id, - "message_id": msg_id, - "group_id": event.group.id, - "message_seq": 0, - } - - return aiocqhttp.Event.from_payload(payload) - elif type(event) is platform_events.FriendMessage: - - payload = { - "post_type": "message", - "message_type": "private", - "time": int(msg_time.timestamp()), - "self_id": bot_account_id, - "sub_type": "friend", - "target_id": bot_account_id, - "message": str(msg), - "raw_message": str(msg), - "font": 0, - "sender": { - "age": 0, - "nickname": event.sender.nickname, - "sex": "unknown", - "user_id": event.sender.id, - }, - "message_id": msg_id, - "user_id": event.sender.id, - } - - return aiocqhttp.Event.from_payload(payload) + async def yiri2target(event: platform_events.MessageEvent, bot_account_id: int): + return event.source_platform_object @staticmethod async def target2yiri(event: aiocqhttp.Event): @@ -196,6 +135,7 @@ class AiocqhttpEventConverter(adapter.EventConverter): ), message_chain=yiri_chain, time=event.time, + source_platform_object=event ) return converted_event elif event.message_type == "private": @@ -207,6 +147,7 @@ class AiocqhttpEventConverter(adapter.EventConverter): ), message_chain=yiri_chain, time=event.time, + source_platform_object=event ) From 1a62e08bab641f0b7fcaeca2856a305c8de20ada Mon Sep 17 00:00:00 2001 From: "Junyan Qin (Chin)" Date: Mon, 24 Mar 2025 15:40:51 +0800 Subject: [PATCH 5/8] chore: update gitignore (#1231) --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index a4478803..17271201 100644 --- a/.gitignore +++ b/.gitignore @@ -19,7 +19,7 @@ cookies.json data/labels/announcement_saved.json cmdpriv.json tips.py -.venv +venv* bin/ .vscode test_* From a0fd152d19c4459786dd138f929d2d0c85453267 Mon Sep 17 00:00:00 2001 From: "Junyan Qin (Chin)" Date: Mon, 24 Mar 2025 15:43:46 +0800 Subject: [PATCH 6/8] doc(README): add 3.13 in python version badge (#1232) --- README.md | 2 +- README_EN.md | 2 +- README_JP.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 9276d63e..0b7df23d 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ [![QQ Group](https://img.shields.io/badge/%E7%A4%BE%E5%8C%BAQQ%E7%BE%A4-966235608-blue)](https://qm.qq.com/q/JLi38whHum) [![GitHub release (latest by date)](https://img.shields.io/github/v/release/RockChinQ/LangBot)](https://github.com/RockChinQ/LangBot/releases/latest) ![Dynamic JSON Badge](https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fapi.qchatgpt.rockchin.top%2Fapi%2Fv2%2Fview%2Frealtime%2Fcount_query%3Fminute%3D10080&query=%24.data.count&label=%E4%BD%BF%E7%94%A8%E9%87%8F%EF%BC%887%E6%97%A5%EF%BC%89) -python +python [![star](https://gitcode.com/RockChinQ/LangBot/star/badge.svg)](https://gitcode.com/RockChinQ/LangBot) [简体中文](README.md) / [English](README_EN.md) / [日本語](README_JP.md) diff --git a/README_EN.md b/README_EN.md index f777c228..47df5ec1 100644 --- a/README_EN.md +++ b/README_EN.md @@ -24,7 +24,7 @@ [![Discord](https://img.shields.io/discord/1335141740050649118?logo=discord&labelColor=%20%235462eb&logoColor=%20%23f5f5f5&color=%20%235462eb)](https://discord.gg/wdNEHETs87) [![GitHub release (latest by date)](https://img.shields.io/github/v/release/RockChinQ/LangBot)](https://github.com/RockChinQ/LangBot/releases/latest) ![Dynamic JSON Badge](https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fapi.qchatgpt.rockchin.top%2Fapi%2Fv2%2Fview%2Frealtime%2Fcount_query%3Fminute%3D10080&query=%24.data.count&label=Usage(7days)) -python +python [简体中文](README.md) / [English](README_EN.md) / [日本語](README_JP.md) diff --git a/README_JP.md b/README_JP.md index 9063dcfc..db4b0cf7 100644 --- a/README_JP.md +++ b/README_JP.md @@ -23,7 +23,7 @@ [![Discord](https://img.shields.io/discord/1335141740050649118?logo=discord&labelColor=%20%235462eb&logoColor=%20%23f5f5f5&color=%20%235462eb)](https://discord.gg/wdNEHETs87) [![GitHub release (latest by date)](https://img.shields.io/github/v/release/RockChinQ/LangBot)](https://github.com/RockChinQ/LangBot/releases/latest) ![Dynamic JSON Badge](https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fapi.qchatgpt.rockchin.top%2Fapi%2Fv2%2Fview%2Frealtime%2Fcount_query%3Fminute%3D10080&query=%24.data.count&label=Usage(7days)) -python +python [简体中文](README.md) / [English](README_EN.md) / [日本語](README_JP.md) From 394d4b3c1b538b152678aad47387c9d400911b5d Mon Sep 17 00:00:00 2001 From: "Junyan Qin (Chin)" Date: Fri, 28 Mar 2025 23:46:24 +0800 Subject: [PATCH 7/8] fix: static_file sent with wrong mimetype (#1243) --- pkg/api/http/controller/main.py | 38 +++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/pkg/api/http/controller/main.py b/pkg/api/http/controller/main.py index acbfa104..70a1a546 100644 --- a/pkg/api/http/controller/main.py +++ b/pkg/api/http/controller/main.py @@ -66,8 +66,42 @@ class HTTPController: @self.quart_app.route("/") async def index(): - return await quart.send_from_directory(frontend_path, "index.html") + return await quart.send_from_directory( + frontend_path, + "index.html", + mimetype="text/html" + ) @self.quart_app.route("/") async def static_file(path: str): - return await quart.send_from_directory(frontend_path, path) + + mimetype = None + + if path.endswith(".html"): + mimetype = "text/html" + elif path.endswith(".js"): + mimetype = "application/javascript" + elif path.endswith(".css"): + mimetype = "text/css" + elif path.endswith(".png"): + mimetype = "image/png" + elif path.endswith(".jpg"): + mimetype = "image/jpeg" + elif path.endswith(".jpeg"): + mimetype = "image/jpeg" + elif path.endswith(".gif"): + mimetype = "image/gif" + elif path.endswith(".svg"): + mimetype = "image/svg+xml" + elif path.endswith(".ico"): + mimetype = "image/x-icon" + elif path.endswith(".json"): + mimetype = "application/json" + elif path.endswith(".txt"): + mimetype = "text/plain" + + return await quart.send_from_directory( + frontend_path, + path, + mimetype=mimetype + ) \ No newline at end of file From 629ebae0e972dfcb57cebd2b6b1912854e9939e3 Mon Sep 17 00:00:00 2001 From: "Junyan Qin (Chin)" Date: Fri, 28 Mar 2025 23:48:09 +0800 Subject: [PATCH 8/8] chore: release v3.4.11.1 (#1244) --- pkg/utils/constants.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/utils/constants.py b/pkg/utils/constants.py index 14b2b74c..1e84a22e 100644 --- a/pkg/utils/constants.py +++ b/pkg/utils/constants.py @@ -1,4 +1,4 @@ -semantic_version = "v3.4.11" +semantic_version = "v3.4.11.1" debug_mode = False