update
This commit is contained in:
133
telegram_bot.py
133
telegram_bot.py
@@ -8,11 +8,12 @@ from functools import wraps
|
||||
from pathlib import Path
|
||||
from typing import Optional
|
||||
|
||||
from telegram import Update, Bot, BotCommand
|
||||
from telegram import Update, Bot, BotCommand, InlineKeyboardButton, InlineKeyboardMarkup
|
||||
from telegram.ext import (
|
||||
Application,
|
||||
CommandHandler,
|
||||
MessageHandler,
|
||||
CallbackQueryHandler,
|
||||
filters,
|
||||
ContextTypes,
|
||||
)
|
||||
@@ -50,7 +51,7 @@ from config import (
|
||||
)
|
||||
from utils import load_team_tracker, get_all_incomplete_accounts
|
||||
from bot_notifier import BotNotifier, set_notifier, progress_finish
|
||||
from s2a_service import s2a_get_dashboard_stats, format_dashboard_stats
|
||||
from s2a_service import s2a_get_dashboard_stats, format_dashboard_stats, s2a_get_keys_with_usage, format_keys_usage
|
||||
from email_service import gptmail_service, unified_create_email
|
||||
from logger import log
|
||||
|
||||
@@ -118,6 +119,7 @@ class ProvisionerBot:
|
||||
("reload", self.cmd_reload),
|
||||
("s2a_config", self.cmd_s2a_config),
|
||||
("clean", self.cmd_clean),
|
||||
("keys_usage", self.cmd_keys_usage),
|
||||
]
|
||||
for cmd, handler in handlers:
|
||||
self.app.add_handler(CommandHandler(cmd, handler))
|
||||
@@ -128,6 +130,12 @@ class ProvisionerBot:
|
||||
self.handle_json_file
|
||||
))
|
||||
|
||||
# 注册回调查询处理器 (InlineKeyboard)
|
||||
self.app.add_handler(CallbackQueryHandler(
|
||||
self.callback_keys_usage,
|
||||
pattern="^keys_usage:"
|
||||
))
|
||||
|
||||
# 注册定时检查任务
|
||||
if TELEGRAM_CHECK_INTERVAL > 0 and AUTH_PROVIDER == "s2a":
|
||||
self.app.job_queue.run_repeating(
|
||||
@@ -189,6 +197,7 @@ class ProvisionerBot:
|
||||
BotCommand("reload", "重载配置文件"),
|
||||
BotCommand("clean", "清理数据文件"),
|
||||
BotCommand("dashboard", "查看 S2A 仪表盘"),
|
||||
BotCommand("keys_usage", "查看 API 密钥用量"),
|
||||
BotCommand("stock", "查看账号库存"),
|
||||
BotCommand("s2a_config", "配置 S2A 参数"),
|
||||
BotCommand("import", "导入账号到 team.json"),
|
||||
@@ -231,6 +240,7 @@ class ProvisionerBot:
|
||||
|
||||
<b>📊 S2A 专属:</b>
|
||||
/dashboard - 查看 S2A 仪表盘
|
||||
/keys_usage - 查看 API 密钥用量
|
||||
/stock - 查看账号库存
|
||||
/s2a_config - 配置 S2A 参数
|
||||
|
||||
@@ -1184,6 +1194,125 @@ class ProvisionerBot:
|
||||
except Exception as e:
|
||||
await update.message.reply_text(f"❌ 错误: {e}")
|
||||
|
||||
@admin_only
|
||||
async def cmd_keys_usage(self, update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
"""查看 API 密钥用量 - 显示时间选择菜单"""
|
||||
if AUTH_PROVIDER != "s2a":
|
||||
await update.message.reply_text(
|
||||
f"⚠️ 密钥用量查询仅支持 S2A 模式\n"
|
||||
f"当前模式: {AUTH_PROVIDER}"
|
||||
)
|
||||
return
|
||||
|
||||
# 创建时间选择按钮
|
||||
keyboard = [
|
||||
[
|
||||
InlineKeyboardButton("📅 今天", callback_data="keys_usage:today"),
|
||||
InlineKeyboardButton("📅 昨天", callback_data="keys_usage:yesterday"),
|
||||
],
|
||||
[
|
||||
InlineKeyboardButton("📆 近 7 天", callback_data="keys_usage:7d"),
|
||||
InlineKeyboardButton("📆 近 14 天", callback_data="keys_usage:14d"),
|
||||
],
|
||||
[
|
||||
InlineKeyboardButton("📆 近 30 天", callback_data="keys_usage:30d"),
|
||||
InlineKeyboardButton("📆 本月", callback_data="keys_usage:this_month"),
|
||||
],
|
||||
[
|
||||
InlineKeyboardButton("📆 上月", callback_data="keys_usage:last_month"),
|
||||
],
|
||||
]
|
||||
reply_markup = InlineKeyboardMarkup(keyboard)
|
||||
|
||||
await update.message.reply_text(
|
||||
"<b>🔑 API 密钥用量查询</b>\n\n请选择时间范围:",
|
||||
reply_markup=reply_markup,
|
||||
parse_mode="HTML"
|
||||
)
|
||||
|
||||
async def callback_keys_usage(self, update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
"""处理密钥用量查询的回调"""
|
||||
query = update.callback_query
|
||||
await query.answer()
|
||||
|
||||
# 验证权限
|
||||
user_id = update.effective_user.id
|
||||
if user_id not in TELEGRAM_ADMIN_CHAT_IDS:
|
||||
await query.edit_message_text("⛔ 无权限")
|
||||
return
|
||||
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
# 解析回调数据
|
||||
data = query.data.replace("keys_usage:", "")
|
||||
today = datetime.now()
|
||||
|
||||
if data == "today":
|
||||
start_date = today.strftime("%Y-%m-%d")
|
||||
end_date = today.strftime("%Y-%m-%d")
|
||||
period_text = "今天"
|
||||
elif data == "yesterday":
|
||||
yesterday = today - timedelta(days=1)
|
||||
start_date = yesterday.strftime("%Y-%m-%d")
|
||||
end_date = yesterday.strftime("%Y-%m-%d")
|
||||
period_text = "昨天"
|
||||
elif data == "7d":
|
||||
start_date = (today - timedelta(days=6)).strftime("%Y-%m-%d")
|
||||
end_date = today.strftime("%Y-%m-%d")
|
||||
period_text = "近 7 天"
|
||||
elif data == "14d":
|
||||
start_date = (today - timedelta(days=13)).strftime("%Y-%m-%d")
|
||||
end_date = today.strftime("%Y-%m-%d")
|
||||
period_text = "近 14 天"
|
||||
elif data == "30d":
|
||||
start_date = (today - timedelta(days=29)).strftime("%Y-%m-%d")
|
||||
end_date = today.strftime("%Y-%m-%d")
|
||||
period_text = "近 30 天"
|
||||
elif data == "this_month":
|
||||
start_date = today.replace(day=1).strftime("%Y-%m-%d")
|
||||
end_date = today.strftime("%Y-%m-%d")
|
||||
period_text = "本月"
|
||||
elif data == "last_month":
|
||||
first_of_this_month = today.replace(day=1)
|
||||
last_month_end = first_of_this_month - timedelta(days=1)
|
||||
last_month_start = last_month_end.replace(day=1)
|
||||
start_date = last_month_start.strftime("%Y-%m-%d")
|
||||
end_date = last_month_end.strftime("%Y-%m-%d")
|
||||
period_text = "上月"
|
||||
else:
|
||||
await query.edit_message_text("❌ 未知的时间选项")
|
||||
return
|
||||
|
||||
await query.edit_message_text(f"⏳ 正在获取密钥用量 ({period_text})...")
|
||||
|
||||
try:
|
||||
keys = s2a_get_keys_with_usage(start_date, end_date)
|
||||
if keys is not None:
|
||||
text = format_keys_usage(keys, period_text)
|
||||
# 消息太长时分段发送
|
||||
if len(text) > 4000:
|
||||
# 先更新原消息
|
||||
await query.edit_message_text(text[:4000], parse_mode="HTML")
|
||||
# 剩余部分新消息发送
|
||||
remaining = text[4000:]
|
||||
while remaining:
|
||||
chunk = remaining[:4000]
|
||||
remaining = remaining[4000:]
|
||||
await context.bot.send_message(
|
||||
chat_id=update.effective_chat.id,
|
||||
text=chunk,
|
||||
parse_mode="HTML"
|
||||
)
|
||||
else:
|
||||
await query.edit_message_text(text, parse_mode="HTML")
|
||||
else:
|
||||
await query.edit_message_text(
|
||||
"❌ 获取密钥用量失败\n"
|
||||
"请检查 S2A 配置和 API 连接"
|
||||
)
|
||||
except Exception as e:
|
||||
await query.edit_message_text(f"❌ 错误: {e}")
|
||||
|
||||
@admin_only
|
||||
async def cmd_stock(self, update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
"""查看账号存货"""
|
||||
|
||||
Reference in New Issue
Block a user