feat: 默认节点池重置订阅链接+显示当前链接
This commit is contained in:
36
bot.py
36
bot.py
@@ -15,6 +15,11 @@ SUB_SECRET = os.environ.get('SUB_SECRET', 'changeme')
|
|||||||
SUB_HOST = os.environ.get('SUB_HOST', 'substore.mjjtop.com')
|
SUB_HOST = os.environ.get('SUB_HOST', 'substore.mjjtop.com')
|
||||||
WAITING_ADD = set() # user_ids waiting to add sub
|
WAITING_ADD = set() # user_ids waiting to add sub
|
||||||
|
|
||||||
|
def get_default_secret():
|
||||||
|
"""获取默认节点池的 secret,优先用 data.json 里的,没有就用环境变量"""
|
||||||
|
data = load_data()
|
||||||
|
return data.get('default_secret', SUB_SECRET)
|
||||||
|
|
||||||
def load_data():
|
def load_data():
|
||||||
if os.path.exists(DATA_FILE):
|
if os.path.exists(DATA_FILE):
|
||||||
with open(DATA_FILE) as f:
|
with open(DATA_FILE) as f:
|
||||||
@@ -135,20 +140,37 @@ async def cb_menu(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
|||||||
if action == 'menu_default':
|
if action == 'menu_default':
|
||||||
cnt = len(data['subs'])
|
cnt = len(data['subs'])
|
||||||
alive_cnt = len([s for s in data['subs'] if s.get('alive', True)])
|
alive_cnt = len([s for s in data['subs'] if s.get('alive', True)])
|
||||||
|
host = SUB_HOST
|
||||||
|
url = f"https://{host}/{get_default_secret()}/download?target=ClashMeta"
|
||||||
buttons = [
|
buttons = [
|
||||||
[InlineKeyboardButton("📋 节点列表", callback_data='menu_list'),
|
[InlineKeyboardButton("📋 节点列表", callback_data='menu_list'),
|
||||||
InlineKeyboardButton("📥 获取订阅", callback_data='menu_get')],
|
InlineKeyboardButton("📥 获取订阅", callback_data='menu_get')],
|
||||||
[InlineKeyboardButton("➕ 添加节点", callback_data='menu_add'),
|
[InlineKeyboardButton("➕ 添加节点", callback_data='menu_add'),
|
||||||
InlineKeyboardButton("🗑 删除节点", callback_data='menu_del')],
|
InlineKeyboardButton("🗑 删除节点", callback_data='menu_del')],
|
||||||
|
[InlineKeyboardButton("🔄 重置订阅链接", callback_data='menu_reset_secret')],
|
||||||
[InlineKeyboardButton("◀️ 返回主菜单", callback_data='menu_home')],
|
[InlineKeyboardButton("◀️ 返回主菜单", callback_data='menu_home')],
|
||||||
]
|
]
|
||||||
try:
|
try:
|
||||||
await q.edit_message_text(
|
await q.edit_message_text(
|
||||||
f'📦 *默认节点池*\n\n总计 {cnt} 个节点,{alive_cnt} 个可用',
|
f'📦 *默认节点池*\n\n总计 {cnt} 个节点,{alive_cnt} 个可用\n🔗 订阅链接:\n`{url}`',
|
||||||
parse_mode='Markdown', reply_markup=InlineKeyboardMarkup(buttons))
|
parse_mode='Markdown', reply_markup=InlineKeyboardMarkup(buttons))
|
||||||
except:
|
except:
|
||||||
await send_del(q.message,
|
await send_del(q.message,
|
||||||
f'📦 *默认节点池*\n\n总计 {cnt} 个节点,{alive_cnt} 个可用',
|
f'📦 *默认节点池*\n\n总计 {cnt} 个节点,{alive_cnt} 个可用\n🔗 订阅链接:\n`{url}`',
|
||||||
|
parse_mode='Markdown', reply_markup=InlineKeyboardMarkup(buttons))
|
||||||
|
|
||||||
|
elif action == 'menu_reset_secret':
|
||||||
|
new_secret = secrets.token_hex(16)
|
||||||
|
data['default_secret'] = new_secret
|
||||||
|
save_data(data)
|
||||||
|
host = SUB_HOST
|
||||||
|
url = f"https://{host}/{new_secret}/download?target=ClashMeta"
|
||||||
|
buttons = [[InlineKeyboardButton("◀️ 返回", callback_data='menu_default')]]
|
||||||
|
try:
|
||||||
|
await q.edit_message_text(f"✅ 默认订阅链接已重置\n\n旧链接已失效\n新链接:\n`{url}`",
|
||||||
|
parse_mode='Markdown', reply_markup=InlineKeyboardMarkup(buttons))
|
||||||
|
except:
|
||||||
|
await send_del(q.message, f"✅ 默认订阅链接已重置\n\n旧链接已失效\n新链接:\n`{url}`",
|
||||||
parse_mode='Markdown', reply_markup=InlineKeyboardMarkup(buttons))
|
parse_mode='Markdown', reply_markup=InlineKeyboardMarkup(buttons))
|
||||||
|
|
||||||
elif action == 'menu_home':
|
elif action == 'menu_home':
|
||||||
@@ -280,7 +302,7 @@ async def cb_getsub(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
|||||||
cm = gen_clash_meta([s])
|
cm = gen_clash_meta([s])
|
||||||
await send_del(q.message, f'```yaml\n{cm}\n```', parse_mode='Markdown')
|
await send_del(q.message, f'```yaml\n{cm}\n```', parse_mode='Markdown')
|
||||||
elif fmt == 'url':
|
elif fmt == 'url':
|
||||||
url = f'https://substore.mjjtop.com/{SUB_SECRET}/download?target=ClashMeta'
|
url = f'https://substore.mjjtop.com/{get_default_secret()}/download?target=ClashMeta'
|
||||||
await send_del(q.message, f'📎 订阅URL:\n{url}')
|
await send_del(q.message, f'📎 订阅URL:\n{url}')
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -303,7 +325,7 @@ async def cb_getsub(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
|||||||
proto, fmt = parts[1], parts[2]
|
proto, fmt = parts[1], parts[2]
|
||||||
subs = alive if proto == 'all' else [s for s in alive if s['type'] == proto]
|
subs = alive if proto == 'all' else [s for s in alive if s['type'] == proto]
|
||||||
if fmt == 'clash':
|
if fmt == 'clash':
|
||||||
url = f'https://substore.mjjtop.com/{SUB_SECRET}/download?target=ClashMeta'
|
url = f'https://substore.mjjtop.com/{get_default_secret()}/download?target=ClashMeta'
|
||||||
if proto != 'all': url += f'&type={proto}'
|
if proto != 'all': url += f'&type={proto}'
|
||||||
return await send_del(q.message, f'📎 Clash Meta 订阅链接:\n{url}')
|
return await send_del(q.message, f'📎 Clash Meta 订阅链接:\n{url}')
|
||||||
links = '\n'.join(s['link'] for s in subs)
|
links = '\n'.join(s['link'] for s in subs)
|
||||||
@@ -317,7 +339,7 @@ async def cb_getsub(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
|||||||
return
|
return
|
||||||
|
|
||||||
if action == 'get_all_clash':
|
if action == 'get_all_clash':
|
||||||
url = f'https://substore.mjjtop.com/{SUB_SECRET}/download?target=ClashMeta'
|
url = f'https://substore.mjjtop.com/{get_default_secret()}/download?target=ClashMeta'
|
||||||
await send_del(q.message, f'📎 Clash Meta 订阅链接:\n{url}')
|
await send_del(q.message, f'📎 Clash Meta 订阅链接:\n{url}')
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -408,7 +430,7 @@ async def cb_multiout(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
|||||||
await send_del(q.message, f'```yaml\n{cm}\n```', parse_mode='Markdown')
|
await send_del(q.message, f'```yaml\n{cm}\n```', parse_mode='Markdown')
|
||||||
elif fmt == 'url':
|
elif fmt == 'url':
|
||||||
names = ','.join(urllib.request.quote(s['name']) for s in chosen)
|
names = ','.join(urllib.request.quote(s['name']) for s in chosen)
|
||||||
url = f'https://substore.mjjtop.com/{SUB_SECRET}/download?target=ClashMeta&name={names}'
|
url = f'https://substore.mjjtop.com/{get_default_secret()}/download?target=ClashMeta&name={names}'
|
||||||
await send_del(q.message, f'📎 订阅URL:\n{url}')
|
await send_del(q.message, f'📎 订阅URL:\n{url}')
|
||||||
elif fmt == 'b64':
|
elif fmt == 'b64':
|
||||||
links = '\n'.join(s['link'] for s in chosen)
|
links = '\n'.join(s['link'] for s in chosen)
|
||||||
@@ -599,7 +621,7 @@ class SubHandler(BaseHTTPRequestHandler):
|
|||||||
|
|
||||||
# 匹配默认分组或自定义分组
|
# 匹配默认分组或自定义分组
|
||||||
alive = []
|
alive = []
|
||||||
if path == f'/{SUB_SECRET}/download':
|
if path == f'/{get_default_secret()}/download':
|
||||||
data = load_data()
|
data = load_data()
|
||||||
alive = [s for s in data['subs'] if s.get('alive', True)]
|
alive = [s for s in data['subs'] if s.get('alive', True)]
|
||||||
else:
|
else:
|
||||||
|
|||||||
Reference in New Issue
Block a user