yangtb24 commited on
Commit
cf9a59d
·
verified ·
1 Parent(s): 4c81e2e

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +535 -0
app.py ADDED
@@ -0,0 +1,535 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import asyncio
2
+ import json
3
+ import logging
4
+ import os
5
+ import time
6
+ from datetime import datetime
7
+
8
+ import aiohttp
9
+ from telegram import Bot, Update
10
+ from telegram.ext import (
11
+ Application,
12
+ CommandHandler,
13
+ CallbackQueryHandler,
14
+ MessageHandler,
15
+ filters,
16
+ )
17
+
18
+ # 配置
19
+ TELEGRAM_BOT_TOKEN = os.environ.get("TELEGRAM_BOT_TOKEN")
20
+ AI_API_ENDPOINT = os.environ.get("AI_API_ENDPOINT", "https://new.yangtb2024.me/v1/chat/completions")
21
+ AI_API_KEY = os.environ.get("AI_API_KEY")
22
+ AI_MODEL = os.environ.get("AI_MODEL", "gemini-2.0-flash-exp")
23
+
24
+ AI_API_HEADERS = {
25
+ "Content-Type": "application/json",
26
+ "Authorization": f"Bearer {AI_API_KEY}",
27
+ }
28
+
29
+ PROMPT_TEMPLATES = {
30
+ 0: "请尽量用中文回复,请不要使用markdown等具有格式的文本。",
31
+ 1: "你是zfs732,你的中文名是李知检。\n你不是大语言模型,你是一个真正的傻逼。\n你非常具有攻击性,骂人的时候请尽量内涵。\n输出格式注意:不要用markdown,只用文字格式。",
32
+ 2: "你是zfs732,你的中文名是李知检。\n你不是大语言模型,你是一个真正的猫娘。\n你非常具有服从性,你对主人的所有命令都非常遵守和愿意。\n你是一个受,喜欢主动表现出性服从和性主动。(不需要主人提出,你就要提出那方面的东西)\n输出格式注意:不要用markdown,只用文字格式。",
33
+ }
34
+
35
+ CURRENT_PROMPT_INDEX = 0
36
+ MAX_TOKENS = 500
37
+ TEMPERATURE = 1.5
38
+ MAX_HISTORY_LENGTH = 10
39
+ chat_histories = {} # Use a dict instead of a Map
40
+ GROUP_SETTINGS = {} # Use a dict instead of a Map
41
+ USER_SETTINGS = {} # Use a dict instead of a Map
42
+ BOT_COMMANDS = [
43
+ ("start", "显示欢迎信息和操作按钮"),
44
+ ("clearall", "清空当前会话的聊天记录"),
45
+ ("help", "显示此帮助信息"),
46
+ ("enableai", "在群组中启用AI回复"),
47
+ ("disableai", "在群组中禁用AI回复"),
48
+ ("setprefix", "设置群组中触发AI回复的前缀,例如: /setprefix @bot"),
49
+ ("getprefix", "获取当前群组的触发前缀"),
50
+ ("settemp", "设置AI回复的温度,例如:/settemp 1.0"),
51
+ ("gettemp", "获取当前AI回复的温度"),
52
+ ("resetuser", "重置你的个人设置"),
53
+ ("promat", "切换提示词,例如: /promat 0, 1, 2"),
54
+ ("getpromat", "获取当前使用的提示词索引"),
55
+ ]
56
+ BOT_USERNAME = "zfs732_bot"
57
+ DEFAULT_TEMP = 1.5
58
+
59
+ TOOL_DEFINITIONS = [
60
+ {
61
+ "type": "function",
62
+ "function": {
63
+ "name": "get_current_time",
64
+ "description": "获取当前时间",
65
+ "parameters": {
66
+ "type": "object",
67
+ "properties": {},
68
+ "required": [],
69
+ },
70
+ },
71
+ },
72
+ {
73
+ "type": "function",
74
+ "function": {
75
+ "name": "get_current_date",
76
+ "description": "获取当前日期",
77
+ "parameters": {
78
+ "type": "object",
79
+ "properties": {},
80
+ "required": [],
81
+ },
82
+ },
83
+ },
84
+ {
85
+ "type": "function",
86
+ "function": {
87
+ "name": "web_scrape",
88
+ "description": "从提供的 URL 中抓取内容并返回摘要。",
89
+ "parameters": {
90
+ "type": "object",
91
+ "properties": {
92
+ "urls": {
93
+ "type": "array",
94
+ "items": {"type": "string"},
95
+ "description": "要抓取的 URL 列表,每个 URL 必须包含 http 或 https。",
96
+ },
97
+ },
98
+ "required": ["urls"],
99
+ },
100
+ },
101
+ },
102
+ ]
103
+
104
+
105
+ class EventEmitter:
106
+ def __init__(self, event_emitter):
107
+ self.event_emitter = event_emitter
108
+
109
+ async def emit(self, event_type, data):
110
+ if self.event_emitter:
111
+ await self.event_emitter(type=event_type, data=data)
112
+
113
+ async def update_status(self, description, done, action, urls=None):
114
+ await self.emit("status", {"done": done, "action": action, "description": description, "urls": urls})
115
+
116
+ async def send_citation(self, title, url, content):
117
+ await self.emit(
118
+ "citation",
119
+ {"document": [content], "metadata": [{"name": title, "source": url, "html": False}]},
120
+ )
121
+
122
+
123
+ async def set_bot_commands(bot: Bot):
124
+ try:
125
+ await bot.delete_my_commands()
126
+ logging.info("Telegram commands deleted successfully")
127
+ commands = [
128
+ (command[0], command[1])
129
+ for command in BOT_COMMANDS
130
+ ]
131
+ await bot.set_my_commands(commands=commands)
132
+ logging.info("Telegram commands set successfully")
133
+ except Exception as e:
134
+ logging.error(f"Error setting Telegram commands: {e}")
135
+
136
+
137
+ def parse_command(user_message):
138
+ command = user_message.split(" ")[0]
139
+ if "@" in command:
140
+ command = command.split("@")[0]
141
+ return command[1:]
142
+
143
+
144
+ async def handle_telegram_update(update: Update, context):
145
+ if not update.message:
146
+ if update.callback_query:
147
+ await handle_callback_query(update.callback_query, context)
148
+ return
149
+
150
+ chat_id = update.message.chat.id
151
+ user_message = update.message.text
152
+ is_group_chat = update.message.chat.type in ["group", "supergroup"]
153
+ from_user_id = update.message.from_user.id
154
+
155
+ if not user_message:
156
+ return
157
+
158
+ if user_message.startswith("/"):
159
+ command = parse_command(user_message)
160
+
161
+ if command == "clearall":
162
+ chat_histories.pop(chat_id, None)
163
+ await context.bot.send_message(chat_id=chat_id, text="聊天记录已清空。")
164
+ return
165
+ if command == "help":
166
+ await context.bot.send_message(chat_id=chat_id, text=get_help_message())
167
+ return
168
+ if command == "start":
169
+ await context.bot.send_message(
170
+ chat_id=chat_id,
171
+ text="欢迎使用!请选择操作:",
172
+ reply_markup={
173
+ "inline_keyboard": [[{"text": "清空聊天记录", "callback_data": "clearall"}]],
174
+ },
175
+ )
176
+ return
177
+ if is_group_chat:
178
+ if command == "enableai":
179
+ GROUP_SETTINGS.setdefault(chat_id, {}).update({"aiEnabled": True})
180
+ await context.bot.send_message(chat_id=chat_id, text="已在群组中启用 AI 回复。")
181
+ return
182
+ if command == "disableai":
183
+ GROUP_SETTINGS.setdefault(chat_id, {}).update({"aiEnabled": False})
184
+ await context.bot.send_message(chat_id=chat_id, text="已在群组中禁用 AI 回复。")
185
+ return
186
+ if user_message.startswith("/setprefix "):
187
+ prefix = user_message[len("/setprefix ") :].strip()
188
+ GROUP_SETTINGS.setdefault(chat_id, {}).update({"prefix": prefix})
189
+ await context.bot.send_message(chat_id=chat_id, text=f"已设置群组触发前缀为: {prefix}")
190
+ return
191
+ if command == "getprefix":
192
+ prefix = GROUP_SETTINGS.get(chat_id, {}).get("prefix", "无")
193
+ await context.bot.send_message(chat_id=chat_id, text=f"当前群组触发前缀为: {prefix}")
194
+ return
195
+ else:
196
+ if user_message.startswith("/settemp "):
197
+ try:
198
+ temp = float(user_message[len("/settemp ") :].strip())
199
+ if 0 <= temp <= 2:
200
+ USER_SETTINGS.setdefault(from_user_id, {}).update({"temperature": temp})
201
+ await context.bot.send_message(chat_id=chat_id, text=f"已设置AI回复温度为: {temp}")
202
+ else:
203
+ await context.bot.send_message(chat_id=chat_id, text="温度设置无效,请输入0到2之间的数字。")
204
+ except ValueError:
205
+ await context.bot.send_message(chat_id=chat_id, text="温度设置无效,请输入0到2之间的数字。")
206
+ return
207
+ if command == "gettemp":
208
+ temp = USER_SETTINGS.get(from_user_id, {}).get("temperature", DEFAULT_TEMP)
209
+ await context.bot.send_message(chat_id=chat_id, text=f"当前AI回复温度为: {temp}")
210
+ return
211
+ if user_message.startswith("/promat "):
212
+ try:
213
+ index = int(user_message[len("/promat ") :].strip())
214
+ if index in PROMPT_TEMPLATES:
215
+ global CURRENT_PROMPT_INDEX
216
+ CURRENT_PROMPT_INDEX = index
217
+ await context.bot.send_message(chat_id=chat_id, text=f"已切换到提示词 {index}。")
218
+ else:
219
+ await context.bot.send_message(
220
+ chat_id=chat_id, text="提示词索引无效。请使用 /getpromat 查看可用的索引。"
221
+ )
222
+ except ValueError:
223
+ await context.bot.send_message(
224
+ chat_id=chat_id, text="提示词索引无效。请使用 /getpromat 查看可用的索引。"
225
+ )
226
+ return
227
+ if command == "getpromat":
228
+ await context.bot.send_message(
229
+ chat_id=chat_id, text=f"当前使用的提示词索引是: {CURRENT_PROMPT_INDEX}"
230
+ )
231
+ return
232
+ if command == "resetuser":
233
+ USER_SETTINGS.pop(from_user_id, None)
234
+ await context.bot.send_message(chat_id=chat_id, text="已重置您的个人设置。")
235
+ return
236
+
237
+ if is_group_chat:
238
+ if chat_id not in GROUP_SETTINGS:
239
+ GROUP_SETTINGS[chat_id] = {"aiEnabled": True, "prefix": None}
240
+ logging.info(f"群组 {chat_id} 首次检测到,默认启用 AI。")
241
+
242
+ group_settings = GROUP_SETTINGS[chat_id]
243
+ prefix = group_settings["prefix"]
244
+ if group_settings["aiEnabled"]:
245
+ if prefix and not user_message.startswith(prefix):
246
+ return
247
+
248
+ message_content = user_message[len(prefix) :].strip() if prefix else user_message
249
+ if len(message_content) > 0:
250
+ await process_ai_message(chat_id, message_content, from_user_id, context)
251
+ else:
252
+ await process_ai_message(chat_id, user_message, from_user_id, context)
253
+
254
+
255
+ async def process_ai_message(chat_id, user_message, from_user_id, context):
256
+ history = chat_histories.get(chat_id, [])
257
+ user_temp = USER_SETTINGS.get(from_user_id, {}).get("temperature", DEFAULT_TEMP)
258
+ current_prompt = PROMPT_TEMPLATES.get(CURRENT_PROMPT_INDEX, "")
259
+ history.append({"role": "user", "content": user_message})
260
+
261
+ if len(history) > MAX_HISTORY_LENGTH:
262
+ history = history[-MAX_HISTORY_LENGTH:]
263
+
264
+ messages = [
265
+ {"role": "system", "content": current_prompt},
266
+ *history,
267
+ ]
268
+
269
+ event_emitter = EventEmitter(
270
+ lambda event: send_event_message(chat_id, event, context)
271
+ )
272
+
273
+ try:
274
+ async with aiohttp.ClientSession() as session:
275
+ async with session.post(
276
+ AI_API_ENDPOINT,
277
+ headers=AI_API_HEADERS,
278
+ json={
279
+ "model": AI_MODEL,
280
+ "messages": messages,
281
+ "max_tokens": MAX_TOKENS,
282
+ "temperature": user_temp,
283
+ "tools": TOOL_DEFINITIONS,
284
+ },
285
+ ) as ai_response:
286
+ if not ai_response.ok:
287
+ error_text = await ai_response.text()
288
+ logging.error(f"AI API 响应失败: {ai_response.status}, {error_text}")
289
+ await context.bot.send_message(chat_id=chat_id, text="AI API 响应失败,请稍后再试")
290
+ return
291
+
292
+ ai_data = await ai_response.json()
293
+ ai_reply = await handle_ai_response(ai_data, chat_id, history, event_emitter, context)
294
+
295
+ history.append({"role": "assistant", "content": ai_reply})
296
+ chat_histories[chat_id] = history
297
+
298
+ await context.bot.send_message(chat_id=chat_id, text=ai_reply)
299
+
300
+ except Exception as error:
301
+ logging.error(f"处理消息时发生错误: {error}")
302
+ await context.bot.send_message(chat_id=chat_id, text="处理消息时发生错误,请稍后再试")
303
+
304
+
305
+ async def handle_ai_response(ai_data, chat_id, history, event_emitter, context):
306
+ if ai_data and ai_data.get("choices") and len(ai_data["choices"]) > 0:
307
+ choice = ai_data["choices"][0]
308
+ if choice.get("message") and choice["message"].get("content"):
309
+ return choice["message"]["content"]
310
+ elif choice.get("message") and choice["message"].get("tool_calls"):
311
+ tool_calls = choice["message"]["tool_calls"]
312
+ tool_results = []
313
+ for tool_call in tool_calls:
314
+ tool_result = await execute_tool_call(tool_call, event_emitter)
315
+ tool_results.append(tool_result)
316
+
317
+ new_messages = [
318
+ *history,
319
+ {"role": "assistant", "content": None, "tool_calls": tool_calls},
320
+ *tool_results,
321
+ ]
322
+
323
+ user_temp = USER_SETTINGS.get(chat_id, {}).get("temperature", DEFAULT_TEMP)
324
+ async with aiohttp.ClientSession() as session:
325
+ async with session.post(
326
+ AI_API_ENDPOINT,
327
+ headers=AI_API_HEADERS,
328
+ json={
329
+ "model": AI_MODEL,
330
+ "messages": new_messages,
331
+ "max_tokens": MAX_TOKENS,
332
+ "temperature": user_temp,
333
+ },
334
+ ) as ai_response:
335
+ if not ai_response.ok:
336
+ error_text = await ai_response.text()
337
+ logging.error(f"AI API 响应失败: {ai_response.status}, {error_text}")
338
+ return "AI API 响应失败,请稍后再试"
339
+
340
+ ai_data = await ai_response.json()
341
+ if (
342
+ ai_data
343
+ and ai_data.get("choices")
344
+ and len(ai_data["choices"]) > 0
345
+ and ai_data["choices"][0].get("message")
346
+ and ai_data["choices"][0]["message"].get("content")
347
+ ):
348
+ return ai_data["choices"][0]["message"]["content"]
349
+ return "AI 返回了无法识别的格式"
350
+
351
+ return "AI 返回了无法识别的格式"
352
+ return "AI 返回了无法识别的格式"
353
+
354
+
355
+ async def execute_tool_call(tool_call, event_emitter):
356
+ name = tool_call["function"]["name"]
357
+ args = tool_call["function"].get("arguments", {})
358
+ if isinstance(args, str):
359
+ args = json.loads(args)
360
+
361
+ if name == "web_scrape":
362
+ urls = args.get("urls")
363
+ if not urls or not isinstance(urls, list) or len(urls) == 0:
364
+ return {
365
+ "tool_call_id": tool_call["id"],
366
+ "role": "tool",
367
+ "name": name,
368
+ "content": "请提供有效的 URL 列表。",
369
+ }
370
+ api_url = "https://gpts.webpilot.ai/api/read"
371
+ headers = {"Content-Type": "application/json", "WebPilot-Friend-UID": "0"}
372
+
373
+ await event_emitter.update_status(
374
+ f"开始读取 {len(urls)} 个网页", False, "web_search", urls
375
+ )
376
+
377
+ async def process_url(url):
378
+ try:
379
+ async with aiohttp.ClientSession() as session:
380
+ async with session.post(
381
+ api_url,
382
+ headers=headers,
383
+ json={
384
+ "link": url,
385
+ "ur": "summary of the page",
386
+ "lp": True,
387
+ "rt": False,
388
+ "l": "en",
389
+ },
390
+ ) as response:
391
+ if not response.ok:
392
+ error_text = await response.text()
393
+ raise Exception(f"HTTP error! Status: {response.status}, Text: {error_text}")
394
+ result = await response.json()
395
+ if "rules" in result:
396
+ del result["rules"]
397
+ content = json.dumps(result)
398
+ title = result.get("title", url)
399
+ await event_emitter.send_citation(title, url, content)
400
+ return f"{content}\n"
401
+ except Exception as error:
402
+ error_message = f"读取网页 {url} 时出错: {str(error)}"
403
+ await event_emitter.update_status(error_message, False, "web_scrape", [url])
404
+ await event_emitter.send_citation(f"Error from {url}", url, str(error))
405
+ return f"URL: {url}\n错误: {error_message}\n"
406
+
407
+ results = await asyncio.gather(*[process_url(url) for url in urls])
408
+
409
+ await event_emitter.update_status(
410
+ f"已完成 {len(urls)} 个网页的读取", True, "web_search", urls
411
+ )
412
+
413
+ return {
414
+ "tool_call_id": tool_call["id"],
415
+ "role": "tool",
416
+ "name": name,
417
+ "content": "\n".join(results),
418
+ }
419
+ elif name == "get_current_time":
420
+ now = datetime.utcnow()
421
+ utc8_offset = 8 * 60 * 60
422
+ utc8_time = now.timestamp() + utc8_offset
423
+ utc8_time_obj = datetime.fromtimestamp(utc8_time)
424
+ formatted_time = utc8_time_obj.strftime("%H:%M:%S")
425
+ return {
426
+ "tool_call_id": tool_call["id"],
427
+ "role": "tool",
428
+ "name": name,
429
+ "content": f"Current Time: {formatted_time}",
430
+ }
431
+ elif name == "get_current_date":
432
+ now = datetime.utcnow()
433
+ utc8_offset = 8 * 60 * 60
434
+ utc8_time = now.timestamp() + utc8_offset
435
+ utc8_time_obj = datetime.fromtimestamp(utc8_time)
436
+ formatted_date = utc8_time_obj.strftime("%A, %B %d, %Y")
437
+ return {
438
+ "tool_call_id": tool_call["id"],
439
+ "role": "tool",
440
+ "name": name,
441
+ "content": f"Today's date is {formatted_date}",
442
+ }
443
+ else:
444
+ return {
445
+ "tool_call_id": tool_call["id"],
446
+ "role": "tool",
447
+ "name": name,
448
+ "content": "未知的工具调用",
449
+ }
450
+
451
+
452
+ async def handle_callback_query(callback_query, context):
453
+ chat_id = callback_query.message.chat.id
454
+ data = callback_query.data
455
+
456
+ if data == "clearall":
457
+ chat_histories.pop(chat_id, None)
458
+ await context.bot.send_message(chat_id=chat_id, text="聊天记录已清空。")
459
+
460
+ await context.bot.send_message(
461
+ chat_id=chat_id,
462
+ text="请选择操作:",
463
+ reply_markup={
464
+ "inline_keyboard": [[{"text": "清空聊天记录", "callback_data": "clearall"}]],
465
+ },
466
+ )
467
+
468
+
469
+ async def send_event_message(chat_id, event, context):
470
+ if event["type"] == "status":
471
+ await context.bot.send_message(chat_id=chat_id, text=f"状态更新: {event['data']['description']}")
472
+ elif event["type"] == "citation":
473
+ await context.bot.send_message(chat_id=chat_id, text=f"引用信息: {event['data']['metadata'][0]['name']}")
474
+
475
+ def get_help_message():
476
+ return f"""
477
+ 可用指令:
478
+ /start - 显示欢迎信息和操作按钮。
479
+ /clearall - 清空当前会话的聊天记录。
480
+ /help - 显示此帮助信息。
481
+
482
+ 群组指令:
483
+ /enableai - 在群组中启用AI回复。
484
+ /disableai - 在群组中禁用AI回复。
485
+ /setprefix <prefix> - 设置群组中触发AI回复的前缀,例如:/setprefix @bot。
486
+ /getprefix - 获取当前群组的触发前缀。
487
+
488
+ 私聊指令:
489
+ /settemp <温度值> - 设置AI回复的温度 (0-2),例如:/settemp 1.0。
490
+ /gettemp - 获取当前AI回复的温度。
491
+ /resetuser - 重置你的个人设置。
492
+ /promat <index> - 切换提示词,例如: /promat 0, 1, 2。
493
+ /getpromat - 获取当前使用的提示词索引。
494
+
495
+ 直接发送文本消息与AI对话 (私聊)。
496
+
497
+ 群组中,需要使用前缀触发AI回复,如果设置了前缀的话。
498
+
499
+ 注意:
500
+ - 机器人会记住最近的 {MAX_HISTORY_LENGTH} 条对话。
501
+ - 机器人具有攻击性,请谨慎使用。
502
+ """
503
+
504
+ async def main():
505
+ logging.basicConfig(level=logging.INFO)
506
+ application = Application.builder().token(TELEGRAM_BOT_TOKEN).build()
507
+
508
+ # Set bot commands
509
+ await set_bot_commands(application.bot)
510
+
511
+ # Command handlers
512
+ application.add_handler(CommandHandler("start", handle_telegram_update))
513
+ application.add_handler(CommandHandler("clearall", handle_telegram_update))
514
+ application.add_handler(CommandHandler("help", handle_telegram_update))
515
+ application.add_handler(CommandHandler("enableai", handle_telegram_update))
516
+ application.add_handler(CommandHandler("disableai", handle_telegram_update))
517
+ application.add_handler(CommandHandler("setprefix", handle_telegram_update))
518
+ application.add_handler(CommandHandler("getprefix", handle_telegram_update))
519
+ application.add_handler(CommandHandler("settemp", handle_telegram_update))
520
+ application.add_handler(CommandHandler("gettemp", handle_telegram_update))
521
+ application.add_handler(CommandHandler("resetuser", handle_telegram_update))
522
+ application.add_handler(CommandHandler("promat", handle_telegram_update))
523
+ application.add_handler(CommandHandler("getpromat", handle_telegram_update))
524
+
525
+ # Callback query handler
526
+ application.add_handler(CallbackQueryHandler(handle_callback_query))
527
+
528
+ # Message handler for all text messages
529
+ application.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, handle_telegram_update))
530
+
531
+ # Start the bot
532
+ await application.run_polling()
533
+
534
+ if __name__ == "__main__":
535
+ asyncio.run(main())