Skip to content
This repository was archived by the owner on Mar 3, 2025. It is now read-only.

Commit b028fa3

Browse files
authored
Merge pull request #4 from CyanidEEEEE/master
修正错误&加入临时措施
2 parents 1eeb98a + a1f1db4 commit b028fa3

File tree

2 files changed

+46
-15
lines changed

2 files changed

+46
-15
lines changed

README.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,9 @@
55
> 欢迎任何贡献 ❤️
66
77
## 使用
8-
98
安装好插件后,刷新管理面板,在 `消息平台`->`消息平台适配器` 点击加号,即可看到 `telegram`,点击添加即可配置。
10-
119
在群聊时,前面加一个 `/` 即可触发机器人。如 `/help`, `/你好啊`
10+
加入临时的速率限制功能,可在tg_message_adapter.py设置self.rate_limit调整,默认值为30s
1211

1312
> [!TIP]
1413
> 当更新这个插件后,请在 配置页 直接点击保存配置以全量重启,否则不会生效

tg_message_adapter.py

Lines changed: 45 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from astrbot.api.message_components import Plain, Image, Record
88
from astrbot.core.platform.astr_message_event import MessageSesion
99
from astrbot.api.platform import register_platform_adapter
10+
from astrbot.core import logger
1011

1112
from telegram import Update, File
1213
from telegram.ext import ApplicationBuilder, ContextTypes, filters
@@ -22,7 +23,7 @@
2223
@register_platform_adapter("telegram", "telegram 适配器", default_config_tmpl={
2324
"telegram_token": "your_token",
2425
"start_message": "Hello, I'm AstrBot!",
25-
"telegram_api_base_url": "https://api.telegram.org/bot",
26+
"telegram_api_base_url": "https://api.telegram.org/bot", # 新增配置项
2627
"提示": "由于 Telegram 无法在中国大陆 / Iran 访问,如果你的网络环境为中国大陆 / Iran,记得在 `其他配置` 处设置代理!"
2728
})
2829
class TelegramPlatformAdapter(Platform):
@@ -32,13 +33,16 @@ def __init__(self, platform_config: dict, platform_settings: dict, event_queue:
3233
self.config = platform_config
3334
self.settingss = platform_settings
3435
self.client_self_id = uuid.uuid4().hex[:8]
35-
36+
self.message_queue = asyncio.Queue() # 新增消息队列
37+
self.rate_limit = 30 # 新增速率限制,每用户每 30 秒处理一次
38+
self.user_last_processed_time = {} # 新增用户最后处理时间记录
39+
3640
@override
3741
async def send_by_session(self, session: MessageSesion, message_chain: MessageChain):
3842
from_username = session.session_id
3943
await TelegramPlatformEvent.send_with_client(self.client, message_chain, from_username)
4044
await super().send_by_session(session, message_chain)
41-
45+
4246
@override
4347
def meta(self) -> PlatformMetadata:
4448
return PlatformMetadata(
@@ -54,23 +58,49 @@ async def run(self):
5458

5559
self.application = ApplicationBuilder().token(self.config['telegram_token']).base_url(base_url).build()
5660
message_handler = TelegramMessageHandler(
57-
filters=None,
58-
callback=self.convert_message
61+
filters=filters.ALL, # 允许接收所有类型的消息
62+
callback=self.enqueue_message # 修改为 enqueue_message
5963
)
6064
self.application.add_handler(message_handler)
6165
await self.application.initialize()
6266
await self.application.start()
6367
queue = self.application.updater.start_polling()
6468
self.client = self.application.bot
6569
print("Telegram Platform Adapter is running.")
70+
71+
asyncio.create_task(self.process_message_queue()) # 新增消息队列处理任务
72+
6673
await queue
6774

6875
async def start(self, update: Update, context: ContextTypes.DEFAULT_TYPE):
6976
await context.bot.send_message(chat_id=update.effective_chat.id, text=self.config["start_message"])
7077

71-
async def convert_message(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> AstrBotMessage:
78+
async def enqueue_message(self, update: Update, context: ContextTypes.DEFAULT_TYPE):
79+
"""将消息放入队列"""
80+
await self.message_queue.put((update, context))
81+
82+
async def process_message_queue(self):
83+
"""处理消息队列中的消息"""
84+
while True:
85+
update, context = await self.message_queue.get()
86+
user_id = str(update.effective_user.id)
87+
88+
current_time = asyncio.get_event_loop().time()
89+
last_processed_time = self.user_last_processed_time.get(user_id, 0)
90+
91+
if current_time - last_processed_time >= self.rate_limit:
92+
await self.convert_message(update, context)
93+
self.user_last_processed_time[user_id] = current_time
94+
# 处理完消息后,短暂休眠,避免 CPU 占用过高
95+
await asyncio.sleep(0.01)
96+
else:
97+
# 将消息重新放回队列
98+
await self.message_queue.put((update, context))
99+
# 短暂休眠,避免 CPU 占用过高
100+
await asyncio.sleep(0.01)
101+
102+
async def convert_message(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
72103
message = AstrBotMessage()
73-
# 获得是群聊还是私聊
74104
if update.effective_chat.type == ChatType.PRIVATE:
75105
message.type = MessageType.FRIEND_MESSAGE
76106
else:
@@ -82,19 +112,21 @@ async def convert_message(self, update: Update, context: ContextTypes.DEFAULT_TY
82112
message.self_id = str(context.bot.id)
83113
message.raw_message = update
84114
message.message_str = ""
85-
115+
86116
if update.message.text:
87117
plain_text = update.message.text
88118
message.message = [Plain(plain_text),]
89119
message.message_str = plain_text
90-
120+
await self.handle_msg(message)
91121
elif update.message.voice:
92122
file = await update.message.voice.get_file()
93123
message.message = [Record(file=file.file_path, url=file.file_path),]
94-
95-
96-
await self.handle_msg(message)
97-
124+
message.message_str = f"[语音消息: {file.file_path}]"
125+
await self.handle_msg(message)
126+
else:
127+
message.message = []
128+
logger.info(f"收到不支持的消息类型,来自:{message.sender.user_id if message.sender else '未知'},已忽略")
129+
98130
async def handle_msg(self, message: AstrBotMessage):
99131
message_event = TelegramPlatformEvent(
100132
message_str=message.message_str,

0 commit comments

Comments
 (0)