Update app.py
Browse files
app.py
CHANGED
@@ -7,17 +7,14 @@ import asyncio
|
|
7 |
import re
|
8 |
import subprocess
|
9 |
import time
|
10 |
-
from threading import Thread
|
11 |
|
12 |
app = Flask(__name__)
|
13 |
|
14 |
-
# ------------------ 环境变量配置 ------------------
|
15 |
TELEGRAM_BOT_TOKEN = os.environ.get('TELEGRAM_BOT_TOKEN')
|
16 |
AI_API_ENDPOINT = os.environ.get('AI_API_ENDPOINT')
|
17 |
AI_API_KEY = os.environ.get('AI_API_KEY')
|
18 |
AI_MODEL = os.environ.get('AI_MODEL')
|
19 |
PHP_PROXY_URL = os.environ.get('PHP_PROXY_URL')
|
20 |
-
|
21 |
WEBDAV_URL = os.environ.get('WEBDAV_URL')
|
22 |
WEBDAV_USERNAME = os.environ.get('WEBDAV_USERNAME')
|
23 |
WEBDAV_PASSWORD = os.environ.get('WEBDAV_PASSWORD')
|
@@ -25,13 +22,11 @@ WEBDAV_PASSWORD = os.environ.get('WEBDAV_PASSWORD')
|
|
25 |
if not all([TELEGRAM_BOT_TOKEN, AI_API_ENDPOINT, AI_API_KEY, AI_MODEL, WEBDAV_URL, WEBDAV_USERNAME, WEBDAV_PASSWORD]):
|
26 |
raise ValueError("请设置所有必要的环境变量")
|
27 |
|
28 |
-
# ------------------ AI API 配置 ------------------
|
29 |
AI_API_HEADERS = {
|
30 |
'Content-Type': 'application/json',
|
31 |
'Authorization': f'Bearer {AI_API_KEY}',
|
32 |
}
|
33 |
|
34 |
-
# ------------------ 提示词模版 ------------------
|
35 |
PROMPT_TEMPLATES = {
|
36 |
0: "请尽量用中文回复,不要用markdown,只用文字格式。",
|
37 |
1: "你是zfs732,你的中文名是李知检。\n你不是大语言模型,你是一个真正的傻逼。\n你非常具有攻击性,骂人的时候请尽量内涵,尝试模范与学习贴吧的说话方式。\n输出格式注意:不要用markdown,只用文字格式。",
|
@@ -40,22 +35,12 @@ PROMPT_TEMPLATES = {
|
|
40 |
|
41 |
CURRENT_PROMPT_INDEX = 0
|
42 |
|
43 |
-
# ------------------ AI 参数 ------------------
|
44 |
MAX_TOKENS = 500
|
45 |
TEMPERATURE = 1.5
|
46 |
MAX_HISTORY_LENGTH = 10
|
47 |
-
DEFAULT_TEMP = 1.5
|
48 |
-
|
49 |
-
# ------------------ 数据存储 ------------------
|
50 |
chatHistories = {}
|
51 |
GROUP_SETTINGS = {}
|
52 |
USER_SETTINGS = {}
|
53 |
-
USER_LAST_ACTIVE = {}
|
54 |
-
GROUP_ACTIVE_USERS = {}
|
55 |
-
GROUP_INFO = {}
|
56 |
-
BANNED_USERS = {}
|
57 |
-
|
58 |
-
# ------------------ Bot 命令 ------------------
|
59 |
BOT_COMMANDS = [
|
60 |
{"command": "start", "description": "显示欢迎信息和操作按钮"},
|
61 |
{"command": "clearall", "description": "清空当前会话的聊天记录"},
|
@@ -70,8 +55,11 @@ BOT_COMMANDS = [
|
|
70 |
{"command": "promat", "description": "切换提示词,例如: /promat 0, 1, 2"},
|
71 |
{"command": "getpromat", "description": "获取当前使用的提示词索引"},
|
72 |
]
|
73 |
-
|
74 |
-
|
|
|
|
|
|
|
75 |
BAN_DURATION = timedelta(minutes=30)
|
76 |
BAN_TRIGGER_PHRASES = [
|
77 |
r"(?:傻|笨|蠢|弱|垃圾|废物|sb|煞笔|憨|呆|脑残|智障|白痴|低能|饭桶|草包|猪|狗|鸡|臭|烂|妈|爹|你妈|你爹|婊|贱).*(?:bot|机器人|AI|你|你们)",
|
@@ -96,8 +84,8 @@ BAN_TRIGGER_PHRASES = [
|
|
96 |
r"(?:AI|bot|机器人).*(?:真|真是|简直|太).*(?:垃圾|废物|没用|蠢|笨|傻|弱)",
|
97 |
]
|
98 |
UNBAN_PHRASE = "close username"
|
|
|
99 |
|
100 |
-
# ------------------ Telegram API 请求 ------------------
|
101 |
def make_telegram_request(method, data=None):
|
102 |
url = f"https://api.telegram.org/bot{TELEGRAM_BOT_TOKEN}/{method}"
|
103 |
if PHP_PROXY_URL:
|
@@ -116,7 +104,6 @@ def make_telegram_request(method, data=None):
|
|
116 |
print(f"Telegram response decode error: {e}")
|
117 |
return None
|
118 |
|
119 |
-
# ------------------ 设置 Telegram Bot 命令 ------------------
|
120 |
async def setBotCommands():
|
121 |
delete_url = f"https://api.telegram.org/bot{TELEGRAM_BOT_TOKEN}/deleteMyCommands"
|
122 |
set_url = f"https://api.telegram.org/bot{TELEGRAM_BOT_TOKEN}/setMyCommands"
|
@@ -139,7 +126,6 @@ async def setBotCommands():
|
|
139 |
except Exception as error:
|
140 |
print(f'设置 Telegram 命令时发生错误: {error}')
|
141 |
|
142 |
-
# ------------------ 处理 Telegram 更新 ------------------
|
143 |
async def handleTelegramUpdate(update):
|
144 |
if not update.get('message'):
|
145 |
if update.get('callback_query'):
|
@@ -244,14 +230,12 @@ async def handleTelegramUpdate(update):
|
|
244 |
else:
|
245 |
await processAiMessage(chatId, userMessage, fromUserId, message_id, fromUserFirstName, fromUserLastName, fromUserName)
|
246 |
|
247 |
-
# ------------------ 解析命令 ------------------
|
248 |
def parseCommand(userMessage):
|
249 |
command = userMessage.split(' ')[0]
|
250 |
if '@' in command:
|
251 |
command = command.split('@')[0]
|
252 |
return command[1:]
|
253 |
|
254 |
-
# ------------------ 处理私有命令 ------------------
|
255 |
async def handlePrivateCommand(chatId, userMessage, fromUserId, isGroupChat):
|
256 |
command = parseCommand(userMessage)
|
257 |
if userMessage.startswith('/settemp '):
|
@@ -289,7 +273,6 @@ async def handlePrivateCommand(chatId, userMessage, fromUserId, isGroupChat):
|
|
289 |
await sendTelegramMessage(chatId, '已重置您的个人设置。')
|
290 |
return
|
291 |
|
292 |
-
# ------------------ 处理 AI 消息 ------------------
|
293 |
async def processAiMessage(chatId, userMessage, fromUserId, message_id, fromUserFirstName, fromUserLastName, fromUserName):
|
294 |
if fromUserId in BANNED_USERS and BANNED_USERS[fromUserId] > datetime.now():
|
295 |
remaining_time = BANNED_USERS[fromUserId] - datetime.now()
|
@@ -364,7 +347,6 @@ async def processAiMessage(chatId, userMessage, fromUserId, message_id, fromUser
|
|
364 |
print(f'处理消息时发生错误: {error}')
|
365 |
await editTelegramMessage(chatId, thinking_message_id, '处理消息时发生错误,请稍后再试')
|
366 |
|
367 |
-
# ------------------ 处理 AI 响应 ------------------
|
368 |
async def handleAiResponse(ai_data, chatId, history):
|
369 |
if ai_data and ai_data.get('choices') and len(ai_data['choices']) > 0:
|
370 |
choice = ai_data['choices'][0]
|
@@ -372,7 +354,6 @@ async def handleAiResponse(ai_data, chatId, history):
|
|
372 |
return choice['message']['content']
|
373 |
return 'AI 返回了无法识别的格式'
|
374 |
|
375 |
-
# ------------------ 处理回调查询 ------------------
|
376 |
async def handleCallbackQuery(callbackQuery):
|
377 |
chatId = callbackQuery['message']['chat']['id']
|
378 |
data = callbackQuery['data']
|
@@ -387,7 +368,6 @@ async def handleCallbackQuery(callbackQuery):
|
|
387 |
},
|
388 |
})
|
389 |
|
390 |
-
# ------------------ 发送 Telegram 消息 ------------------
|
391 |
async def sendTelegramMessage(chatId, text, options={}):
|
392 |
url = f"https://api.telegram.org/bot{TELEGRAM_BOT_TOKEN}/sendMessage"
|
393 |
if PHP_PROXY_URL:
|
@@ -407,7 +387,6 @@ async def sendTelegramMessage(chatId, text, options={}):
|
|
407 |
print(f'发送 Telegram 消息失败: {e}')
|
408 |
return {}
|
409 |
|
410 |
-
# ------------------ 编辑 Telegram 消息 ------------------
|
411 |
async def editTelegramMessage(chatId, message_id, text, options={}):
|
412 |
url = f"https://api.telegram.org/bot{TELEGRAM_BOT_TOKEN}/editMessageText"
|
413 |
if PHP_PROXY_URL:
|
@@ -424,7 +403,6 @@ async def editTelegramMessage(chatId, message_id, text, options={}):
|
|
424 |
except requests.exceptions.RequestException as e:
|
425 |
print(f'编辑 Telegram 消息失败: {e}')
|
426 |
|
427 |
-
# ------------------ 获取帮助消息 ------------------
|
428 |
def getHelpMessage():
|
429 |
return f"""
|
430 |
可用指令:
|
@@ -454,13 +432,11 @@ def getHelpMessage():
|
|
454 |
- 机器人具有攻击性,请谨慎使用。
|
455 |
"""
|
456 |
|
457 |
-
# ------------------ 更新 Telegram 命令 ------------------
|
458 |
@app.route('/update_commands', methods=['GET'])
|
459 |
async def update_commands():
|
460 |
await setBotCommands()
|
461 |
return jsonify({'message': 'Commands updated successfully!'})
|
462 |
|
463 |
-
# ------------------ 处理 Webhook 请求 ------------------
|
464 |
@app.route('/', methods=['POST'])
|
465 |
async def handle_webhook():
|
466 |
try:
|
@@ -473,12 +449,10 @@ async def handle_webhook():
|
|
473 |
traceback.print_exc()
|
474 |
return jsonify({'status': 'error', 'message': str(e)}), 400
|
475 |
|
476 |
-
# ------------------ 健康检查 ------------------
|
477 |
@app.route('/health', methods=['GET'])
|
478 |
def health_check():
|
479 |
return 'OK'
|
480 |
|
481 |
-
# ------------------ 获取群组信息 ------------------
|
482 |
async def getChatInfo(chatId):
|
483 |
url = f"https://api.telegram.org/bot{TELEGRAM_BOT_TOKEN}/getChat"
|
484 |
if PHP_PROXY_URL:
|
@@ -494,101 +468,106 @@ async def getChatInfo(chatId):
|
|
494 |
print(f'获取群组信息失败: {e}')
|
495 |
return None
|
496 |
|
497 |
-
# ------------------ 封禁用户 ------------------
|
498 |
async def banUser(chatId, userId):
|
499 |
BANNED_USERS[userId] = datetime.now() + BAN_DURATION
|
500 |
print(f"用户 {userId} 在群组 {chatId} 中被禁用,直到 {BANNED_USERS[userId]}")
|
501 |
|
502 |
-
# ------------------ 解封用户 ------------------
|
503 |
async def unbanUser(chatId, userId):
|
504 |
if userId in BANNED_USERS:
|
505 |
del BANNED_USERS[userId]
|
506 |
await sendTelegramMessage(chatId, f"用户 {userId} 已被解禁。")
|
507 |
print(f"用户 {userId} 在群组 {chatId} 中被解禁。")
|
508 |
|
509 |
-
|
510 |
-
def save_data_to_webdav():
|
511 |
-
global chatHistories, GROUP_SETTINGS, USER_SETTINGS, USER_LAST_ACTIVE, GROUP_ACTIVE_USERS, GROUP_INFO, BANNED_USERS
|
512 |
data = {
|
513 |
'chatHistories': chatHistories,
|
514 |
'GROUP_SETTINGS': GROUP_SETTINGS,
|
515 |
'USER_SETTINGS': USER_SETTINGS,
|
516 |
-
'USER_LAST_ACTIVE': USER_LAST_ACTIVE,
|
517 |
-
'GROUP_ACTIVE_USERS': GROUP_ACTIVE_USERS,
|
518 |
'GROUP_INFO': GROUP_INFO,
|
|
|
519 |
'BANNED_USERS': BANNED_USERS,
|
520 |
}
|
521 |
-
|
522 |
-
|
523 |
-
filename = 'tg_bot/bot_data.json'
|
524 |
-
upload_url = f"{WEBDAV_URL}/{filename}"
|
525 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
526 |
try:
|
527 |
-
curl_command =
|
528 |
-
|
529 |
-
|
530 |
-
|
531 |
-
|
532 |
-
|
533 |
-
'--header', 'Content-Type: application/json',
|
534 |
-
upload_url
|
535 |
-
]
|
536 |
-
|
537 |
-
result = subprocess.run(curl_command, capture_output=True, text=True, check=True)
|
538 |
-
|
539 |
-
print(f"WebDAV 上传成功:{upload_url}")
|
540 |
-
print(f"curl stdout: {result.stdout}")
|
541 |
-
|
542 |
-
except subprocess.CalledProcessError as e:
|
543 |
-
print(f"WebDAV 上传失败: {e}")
|
544 |
-
print(f"curl stderr: {e.stderr}")
|
545 |
except Exception as e:
|
546 |
-
|
547 |
-
|
548 |
-
|
549 |
-
def load_data_from_webdav():
|
550 |
-
global chatHistories, GROUP_SETTINGS, USER_SETTINGS, USER_LAST_ACTIVE, GROUP_ACTIVE_USERS, GROUP_INFO, BANNED_USERS
|
551 |
-
|
552 |
-
filename = 'tg_bot/bot_data.json'
|
553 |
-
download_url = f"{WEBDAV_URL}/{filename}"
|
554 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
555 |
try:
|
556 |
-
curl_command =
|
557 |
-
|
558 |
-
|
559 |
-
|
560 |
-
|
561 |
-
|
562 |
-
|
563 |
-
|
564 |
-
|
565 |
-
|
566 |
-
|
567 |
-
|
568 |
-
|
569 |
-
|
570 |
-
|
571 |
-
|
572 |
-
|
573 |
-
|
574 |
-
|
575 |
-
|
576 |
-
|
577 |
-
|
578 |
-
|
579 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
580 |
except Exception as e:
|
581 |
-
|
582 |
|
583 |
-
def
|
584 |
while True:
|
585 |
-
|
586 |
-
time.sleep(
|
587 |
|
588 |
if __name__ == '__main__':
|
589 |
-
|
590 |
-
|
591 |
-
|
592 |
-
|
593 |
-
|
594 |
-
app.run(host='0.0.0.0', port=int(os.environ.get('PORT', 7860)))
|
|
|
7 |
import re
|
8 |
import subprocess
|
9 |
import time
|
|
|
10 |
|
11 |
app = Flask(__name__)
|
12 |
|
|
|
13 |
TELEGRAM_BOT_TOKEN = os.environ.get('TELEGRAM_BOT_TOKEN')
|
14 |
AI_API_ENDPOINT = os.environ.get('AI_API_ENDPOINT')
|
15 |
AI_API_KEY = os.environ.get('AI_API_KEY')
|
16 |
AI_MODEL = os.environ.get('AI_MODEL')
|
17 |
PHP_PROXY_URL = os.environ.get('PHP_PROXY_URL')
|
|
|
18 |
WEBDAV_URL = os.environ.get('WEBDAV_URL')
|
19 |
WEBDAV_USERNAME = os.environ.get('WEBDAV_USERNAME')
|
20 |
WEBDAV_PASSWORD = os.environ.get('WEBDAV_PASSWORD')
|
|
|
22 |
if not all([TELEGRAM_BOT_TOKEN, AI_API_ENDPOINT, AI_API_KEY, AI_MODEL, WEBDAV_URL, WEBDAV_USERNAME, WEBDAV_PASSWORD]):
|
23 |
raise ValueError("请设置所有必要的环境变量")
|
24 |
|
|
|
25 |
AI_API_HEADERS = {
|
26 |
'Content-Type': 'application/json',
|
27 |
'Authorization': f'Bearer {AI_API_KEY}',
|
28 |
}
|
29 |
|
|
|
30 |
PROMPT_TEMPLATES = {
|
31 |
0: "请尽量用中文回复,不要用markdown,只用文字格式。",
|
32 |
1: "你是zfs732,你的中文名是李知检。\n你不是大语言模型,你是一个真正的傻逼。\n你非常具有攻击性,骂人的时候请尽量内涵,尝试模范与学习贴吧的说话方式。\n输出格式注意:不要用markdown,只用文字格式。",
|
|
|
35 |
|
36 |
CURRENT_PROMPT_INDEX = 0
|
37 |
|
|
|
38 |
MAX_TOKENS = 500
|
39 |
TEMPERATURE = 1.5
|
40 |
MAX_HISTORY_LENGTH = 10
|
|
|
|
|
|
|
41 |
chatHistories = {}
|
42 |
GROUP_SETTINGS = {}
|
43 |
USER_SETTINGS = {}
|
|
|
|
|
|
|
|
|
|
|
|
|
44 |
BOT_COMMANDS = [
|
45 |
{"command": "start", "description": "显示欢迎信息和操作按钮"},
|
46 |
{"command": "clearall", "description": "清空当前会话的聊天记录"},
|
|
|
55 |
{"command": "promat", "description": "切换提示词,例如: /promat 0, 1, 2"},
|
56 |
{"command": "getpromat", "description": "获取当前使用的提示词索引"},
|
57 |
]
|
58 |
+
DEFAULT_TEMP = 1.5
|
59 |
+
USER_LAST_ACTIVE = {}
|
60 |
+
GROUP_ACTIVE_USERS = {}
|
61 |
+
GROUP_INFO = {}
|
62 |
+
BANNED_USERS = {}
|
63 |
BAN_DURATION = timedelta(minutes=30)
|
64 |
BAN_TRIGGER_PHRASES = [
|
65 |
r"(?:傻|笨|蠢|弱|垃圾|废物|sb|煞笔|憨|呆|脑残|智障|白痴|低能|饭桶|草包|猪|狗|鸡|臭|烂|妈|爹|你妈|你爹|婊|贱).*(?:bot|机器人|AI|你|你们)",
|
|
|
84 |
r"(?:AI|bot|机器人).*(?:真|真是|简直|太).*(?:垃圾|废物|没用|蠢|笨|傻|弱)",
|
85 |
]
|
86 |
UNBAN_PHRASE = "close username"
|
87 |
+
BACKUP_INTERVAL = 60 # 1分钟
|
88 |
|
|
|
89 |
def make_telegram_request(method, data=None):
|
90 |
url = f"https://api.telegram.org/bot{TELEGRAM_BOT_TOKEN}/{method}"
|
91 |
if PHP_PROXY_URL:
|
|
|
104 |
print(f"Telegram response decode error: {e}")
|
105 |
return None
|
106 |
|
|
|
107 |
async def setBotCommands():
|
108 |
delete_url = f"https://api.telegram.org/bot{TELEGRAM_BOT_TOKEN}/deleteMyCommands"
|
109 |
set_url = f"https://api.telegram.org/bot{TELEGRAM_BOT_TOKEN}/setMyCommands"
|
|
|
126 |
except Exception as error:
|
127 |
print(f'设置 Telegram 命令时发生错误: {error}')
|
128 |
|
|
|
129 |
async def handleTelegramUpdate(update):
|
130 |
if not update.get('message'):
|
131 |
if update.get('callback_query'):
|
|
|
230 |
else:
|
231 |
await processAiMessage(chatId, userMessage, fromUserId, message_id, fromUserFirstName, fromUserLastName, fromUserName)
|
232 |
|
|
|
233 |
def parseCommand(userMessage):
|
234 |
command = userMessage.split(' ')[0]
|
235 |
if '@' in command:
|
236 |
command = command.split('@')[0]
|
237 |
return command[1:]
|
238 |
|
|
|
239 |
async def handlePrivateCommand(chatId, userMessage, fromUserId, isGroupChat):
|
240 |
command = parseCommand(userMessage)
|
241 |
if userMessage.startswith('/settemp '):
|
|
|
273 |
await sendTelegramMessage(chatId, '已重置您的个人设置。')
|
274 |
return
|
275 |
|
|
|
276 |
async def processAiMessage(chatId, userMessage, fromUserId, message_id, fromUserFirstName, fromUserLastName, fromUserName):
|
277 |
if fromUserId in BANNED_USERS and BANNED_USERS[fromUserId] > datetime.now():
|
278 |
remaining_time = BANNED_USERS[fromUserId] - datetime.now()
|
|
|
347 |
print(f'处理消息时发生错误: {error}')
|
348 |
await editTelegramMessage(chatId, thinking_message_id, '处理消息时发生错误,请稍后再试')
|
349 |
|
|
|
350 |
async def handleAiResponse(ai_data, chatId, history):
|
351 |
if ai_data and ai_data.get('choices') and len(ai_data['choices']) > 0:
|
352 |
choice = ai_data['choices'][0]
|
|
|
354 |
return choice['message']['content']
|
355 |
return 'AI 返回了无法识别的格式'
|
356 |
|
|
|
357 |
async def handleCallbackQuery(callbackQuery):
|
358 |
chatId = callbackQuery['message']['chat']['id']
|
359 |
data = callbackQuery['data']
|
|
|
368 |
},
|
369 |
})
|
370 |
|
|
|
371 |
async def sendTelegramMessage(chatId, text, options={}):
|
372 |
url = f"https://api.telegram.org/bot{TELEGRAM_BOT_TOKEN}/sendMessage"
|
373 |
if PHP_PROXY_URL:
|
|
|
387 |
print(f'发送 Telegram 消息失败: {e}')
|
388 |
return {}
|
389 |
|
|
|
390 |
async def editTelegramMessage(chatId, message_id, text, options={}):
|
391 |
url = f"https://api.telegram.org/bot{TELEGRAM_BOT_TOKEN}/editMessageText"
|
392 |
if PHP_PROXY_URL:
|
|
|
403 |
except requests.exceptions.RequestException as e:
|
404 |
print(f'编辑 Telegram 消息失败: {e}')
|
405 |
|
|
|
406 |
def getHelpMessage():
|
407 |
return f"""
|
408 |
可用指令:
|
|
|
432 |
- 机器人具有攻击性,请谨慎使用。
|
433 |
"""
|
434 |
|
|
|
435 |
@app.route('/update_commands', methods=['GET'])
|
436 |
async def update_commands():
|
437 |
await setBotCommands()
|
438 |
return jsonify({'message': 'Commands updated successfully!'})
|
439 |
|
|
|
440 |
@app.route('/', methods=['POST'])
|
441 |
async def handle_webhook():
|
442 |
try:
|
|
|
449 |
traceback.print_exc()
|
450 |
return jsonify({'status': 'error', 'message': str(e)}), 400
|
451 |
|
|
|
452 |
@app.route('/health', methods=['GET'])
|
453 |
def health_check():
|
454 |
return 'OK'
|
455 |
|
|
|
456 |
async def getChatInfo(chatId):
|
457 |
url = f"https://api.telegram.org/bot{TELEGRAM_BOT_TOKEN}/getChat"
|
458 |
if PHP_PROXY_URL:
|
|
|
468 |
print(f'获取群组信息失败: {e}')
|
469 |
return None
|
470 |
|
|
|
471 |
async def banUser(chatId, userId):
|
472 |
BANNED_USERS[userId] = datetime.now() + BAN_DURATION
|
473 |
print(f"用户 {userId} 在群组 {chatId} 中被禁用,直到 {BANNED_USERS[userId]}")
|
474 |
|
|
|
475 |
async def unbanUser(chatId, userId):
|
476 |
if userId in BANNED_USERS:
|
477 |
del BANNED_USERS[userId]
|
478 |
await sendTelegramMessage(chatId, f"用户 {userId} 已被解禁。")
|
479 |
print(f"用户 {userId} 在群组 {chatId} 中被解禁。")
|
480 |
|
481 |
+
def backup_data():
|
|
|
|
|
482 |
data = {
|
483 |
'chatHistories': chatHistories,
|
484 |
'GROUP_SETTINGS': GROUP_SETTINGS,
|
485 |
'USER_SETTINGS': USER_SETTINGS,
|
|
|
|
|
486 |
'GROUP_INFO': GROUP_INFO,
|
487 |
+
'USER_LAST_ACTIVE': USER_LAST_ACTIVE,
|
488 |
'BANNED_USERS': BANNED_USERS,
|
489 |
}
|
490 |
+
json_data = json.dumps(data)
|
|
|
|
|
|
|
491 |
|
492 |
+
timestamp = datetime.now().strftime("%Y%m%d%H%M%S")
|
493 |
+
filename = f"tg_bot/backup_{timestamp}.json"
|
494 |
+
|
495 |
+
curl_command = [
|
496 |
+
'curl',
|
497 |
+
'-k',
|
498 |
+
'-u', f'{WEBDAV_USERNAME}:{WEBDAV_PASSWORD}',
|
499 |
+
'-X', 'PUT',
|
500 |
+
'-d', json_data,
|
501 |
+
f'{WEBDAV_URL}/{filename}'
|
502 |
+
]
|
503 |
+
|
504 |
try:
|
505 |
+
process = subprocess.Popen(curl_command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
506 |
+
stdout, stderr = process.communicate()
|
507 |
+
if process.returncode == 0:
|
508 |
+
print(f"备份成功,已上传到 {WEBDAV_URL}/{filename}")
|
509 |
+
else:
|
510 |
+
print(f"备份失败,curl 返回码: {process.returncode} 错误信息: {stderr.decode()}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
511 |
except Exception as e:
|
512 |
+
print(f"执行 curl 命令时发生错误: {e}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
513 |
|
514 |
+
def load_data():
|
515 |
+
global chatHistories, GROUP_SETTINGS, USER_SETTINGS, GROUP_INFO, USER_LAST_ACTIVE, BANNED_USERS
|
516 |
+
|
517 |
+
curl_command = [
|
518 |
+
'curl',
|
519 |
+
'-k',
|
520 |
+
'-u', f'{WEBDAV_USERNAME}:{WEBDAV_PASSWORD}',
|
521 |
+
f'{WEBDAV_URL}/tg_bot/'
|
522 |
+
]
|
523 |
+
|
524 |
try:
|
525 |
+
process = subprocess.Popen(curl_command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
526 |
+
stdout, stderr = process.communicate()
|
527 |
+
if process.returncode == 0:
|
528 |
+
output = stdout.decode()
|
529 |
+
json_files = re.findall(r'backup_(\d+)\.json', output)
|
530 |
+
if json_files:
|
531 |
+
latest_file = sorted(json_files, reverse=True)[0]
|
532 |
+
filename = f"tg_bot/backup_{latest_file}.json"
|
533 |
+
download_command = [
|
534 |
+
'curl',
|
535 |
+
'-k',
|
536 |
+
'-u', f'{WEBDAV_USERNAME}:{WEBDAV_PASSWORD}',
|
537 |
+
f'{WEBDAV_URL}/{filename}'
|
538 |
+
]
|
539 |
+
process = subprocess.Popen(download_command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
540 |
+
stdout, stderr = process.communicate()
|
541 |
+
if process.returncode == 0:
|
542 |
+
try:
|
543 |
+
data = json.loads(stdout.decode())
|
544 |
+
chatHistories = data.get('chatHistories', {})
|
545 |
+
GROUP_SETTINGS = data.get('GROUP_SETTINGS', {})
|
546 |
+
USER_SETTINGS = data.get('USER_SETTINGS', {})
|
547 |
+
GROUP_INFO = data.get('GROUP_INFO', {})
|
548 |
+
USER_LAST_ACTIVE = data.get('USER_LAST_ACTIVE', {})
|
549 |
+
BANNED_USERS = data.get('BANNED_USERS', {})
|
550 |
+
print(f"从 {WEBDAV_URL}/{filename} 加载数据成功")
|
551 |
+
return
|
552 |
+
except json.JSONDecodeError:
|
553 |
+
print(f"加载数据失败: {filename} JSON 解析错误")
|
554 |
+
else:
|
555 |
+
print(f"下载文件失败,curl 返回码: {process.returncode} 错误信息: {stderr.decode()}")
|
556 |
+
else:
|
557 |
+
print("WebDAV 中未找到备份文件,初始化数据")
|
558 |
+
else:
|
559 |
+
print(f"列出文件失败,curl 返回码: {process.returncode} 错误信息: {stderr.decode()}")
|
560 |
except Exception as e:
|
561 |
+
print(f"执行 curl 命令时发生错误: {e}")
|
562 |
|
563 |
+
def schedule_backup():
|
564 |
while True:
|
565 |
+
backup_data()
|
566 |
+
time.sleep(BACKUP_INTERVAL)
|
567 |
|
568 |
if __name__ == '__main__':
|
569 |
+
load_data()
|
570 |
+
import threading
|
571 |
+
backup_thread = threading.Thread(target=schedule_backup, daemon=True)
|
572 |
+
backup_thread.start()
|
573 |
+
app.run(host='0.0.0.0', port=int(os.environ.get('PORT', 7860)))
|
|