diff --git a/main.py b/main.py deleted file mode 100644 index 68db9f7..0000000 --- a/main.py +++ /dev/null @@ -1,3356 +0,0 @@ -# -*- coding: UTF-8 -*- - -import os -import re -import sys -import time -import yaml -import json -import requests -import random -import string -import urllib -import base64 -import telebot -import threading -from urllib import parse -from urllib.parse import unquote -from datetime import datetime - -import sqlite3 -import telebot -import pandas as pd -from time import sleep -from loguru import logger -from bs4 import BeautifulSoup - - -# 定义bot -bot = telebot.TeleBot('6079843734:AAHG36G3AjYugqvfSpv6-KlC0vKCnbPnSZE') -#token 6079843734:AAHG36G3AjYugqvfSpv6-KlC0vKCnbPnSZE -#test token 6098444927:AAHe8IN4-WhIZk_XEi79yK1NstUZn_NuSos - -version_text = "3.0.8 (23111211) Master" - -bot_name = "" - -# 日志功能 记录用户使用的指令和获取的订阅日志 -logger.add('bot.log') - -# 定义bot管理员的telegram userid -administrator_id = ['5505027523', '5865970813', '5965795367'] -admin_id = [] -admin_backup = ['5965795367', # 狗修金 - '5505027523', # 波塞冬 - '5865970813', # 波塞冬の小号 - '5629602810', # 波塞冬の朋友 - '5381972909', # 小小 - '6221455367', # sam - '1474655075', # 铭哥 - '965900925' , # Mio - '5528000138', # TCS - '5970730087', # 锤 - '5841382675', # 搬运工 - '5231739605' # zz - ] - -# 定义群聊开关状态 -ban_chat = ['-1001733623785', # Hello World - '-1001671208239', # 科学上网 - '-1001328661960', # Speed Centre - '-1001802462711' # 汪汪队 - ] - -# 定义醉花阴小号id -ban_id = [6095910914] -already = [] - -# 定义白名单群组 -white_list = [-1001334652417, -1001695961075, -1001514577112, -1001553585037, -1001661258040, -1001802462711, -1001671208239, -1001328661960] - -# 定义信任群组 -trust_list = [-1001832182243] - -# 定义窥屏群组 -peep_list = [] - -# 定义测速记录 -record = 1 - -# 定义进度条更新频率 -send_percent = 5 - -# 定义数据库 -conn = sqlite3.connect('My_sub.db', check_same_thread=False) -c = conn.cursor() - -# 定义自我介绍内容 -intro = '本bot为 @C1oudF1are 的私人订阅小仓库bot 不对外公开\n本机器人获取的订阅禁止分享' - - -# 定义订阅转换 -backend = "https://api.nexconvert.com/" -target = "clash" -shortlink = "https://jyf.icu/api/url?url=" -config = "https://paste.gg/p/anonymous/58555e25bdb243999a0a8a1acb19855b/files/2ed3525348ce4d718176e6bef1ba9fd5/raw" -parameter = "&emoji=true&remove_emoji=false&interval=3600&udp=true&expand=false&list=false&scv=true&fdn=true&new_name=true" - -# 定义User-Agent -sub_ua = 'ClashforWindows/0.18.1' -link_ua = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36' - -# 定义bot更新位置 -bot_web = "https://71fddc23658d274091d044ea40fccf2b.pages.dev/main.py" - -# 定义密码 -password = "2147483647" - -# 定义超时尝试次数 -try_time = 7 - -# 定义临期天数 -impend = 10 - -# 定义订阅获取状态 -testsub_flag = 0 - -stop_updatesub = 0 -stop_prune = 0 - -# 定义防拉群 -anti_group = 1 - -# 定义唯一管理模式 -admin_only = 0 - -# 定义允许管理邀请 -allow_invite = 0 - -# 定义回调 -callback_url = "" - -# 定义监测 -cron_enable = 0 -cron_delay = 3600 -cron_list = [] - -# 定义流量查询 -auto_check = {} - -# 创建表 -c.execute('''CREATE TABLE IF NOT EXISTS My_sub(URL text, comment text)''') - -# 定义代理 -proxies = { - 'http': 'http://127.0.0.1:7890', - 'https': 'http://127.0.0.1:7890' -} - -# 加载管理员名单 -def load_admin() : - try : - global admin_id - with open('./config.yaml', 'r', encoding='utf-8') as f: - data = yaml.load(stream=f, Loader=yaml.FullLoader) - for user_id in data['admin']: - admin_id.append(str(user_id)) - admin_id = list(set(admin_id)) - except : - pass - -# 加载管理员名单 -def save_admin() : - try : - global admin_id - with open('./config.yaml', 'r', encoding='utf-8') as f: - data = yaml.load(stream=f, Loader=yaml.FullLoader) - tempid = [] - for user_id in admin_id: - tempid.append(int(user_id)) - tempid = list(set(tempid)) - data['admin'] = tempid - with open('./config.yaml', 'w', encoding='utf-8') as f: - yaml.dump(data=data, stream=f, allow_unicode=True, sort_keys=False) - except: - pass - -# 保存监测列表 -def save_cron() : - try : - with open('./config.yaml', 'r', encoding='utf-8') as f: - data = yaml.load(stream=f, Loader=yaml.FullLoader) - data['cron']['list'] = cron_list - with open('./config.yaml', 'w', encoding='utf-8') as f: - yaml.dump(data=data, stream=f, allow_unicode=True, sort_keys=False) - except : - pass - -def reload_config(): - try: - with open('./config.yaml', 'r', encoding='utf-8') as f: - data = yaml.load(stream=f, Loader=yaml.FullLoader) - except: - pass - try: - if int(data['default']) == 1: - return - except: - pass - global try_time, impend, intro, backend, config, target, shortlink, password, send_percent, anti_group, admin_only, allow_invite, callback_url, cron_enable, cron_delay, cron_list, trust_list - try: - try_time = int(data['timeout']) - except: - pass - try: - impend = int(data['impend']) - except: - pass - try: - password = data['password'] - except: - pass - try: - shortlink = data['shortlink'] - except: - pass - try: - anti_group = int(data['avoidJoinGroups']) - except: - pass - try: - admin_only = int(data['adminOnlyMode']) - except: - pass - try: - allow_invite = int(data['allowAdminToInvite']) - except: - pass - try: - send_percent = int(data['refreshFrequency']) - except: - pass - try: - callback_url = data['callbackUrl'] - except: - pass - try: - backend = data['convert']['backend'] - except: - pass - try: - config = data['convert']['config'] - except: - pass - try: - target = data['convert']['target'] - except: - pass - try: - parameter = data['convert']['parameter'] - except: - pass - try: - sub_ua = data['overridedUA']['subscribtion'] - except: - pass - try: - link_ua = data['overridedUA']['request'] - except: - pass - try: - cron_enable = int(data['cron']['enable']) - except: - pass - try: - cron_delay = int(data['cron']['interval']) - except: - pass - try: - for cron_id in data['cron']['list']: - if not cron_id in cron_list: - cron_list.append(cron_id) - except: - pass - try: - for trust_id in data['trust']: - if not trust_id in trust_list: - trust_list.append(trust_id) - except: - pass - try: - for user_id in data['admin']: - admin_id.append(str(user_id)) - admin_id = list(set(admin_id)) - except: - pass - -def save_config(): - try: - with open('./config.yaml', 'r', encoding='utf-8') as f: - data = yaml.load(stream=f, Loader=yaml.FullLoader) - except: - pass - tempid = [] - for user_id in admin_id: - tempid.append(int(user_id)) - tempid = list(set(tempid)) - data['admin'] = tempid - data['password'] = password - data['shortlink'] = shortlink - data['impend'] = int(impend) - data['timeout'] = int(try_time) - data['adminOnlyMode'] = int(admin_only) - data['avoidJoinGroups'] = int(anti_group) - data['allowAdminToInvite'] = int(allow_invite) - data['refreshFrequency'] = int(send_percent) - if not callback_url == "": - data['callbackUrl'] = callback_url - data['trust'] = trust_list - data['convert'] = {'backend': backend, 'config': config, 'target': target, 'parameter': parameter} - data['overridedUA'] = {'request': link_ua, 'subscribtion': sub_ua} - data['cron'] = {'enable': cron_enable, 'interval': cron_delay, 'list': cron_list} - - with open('./config.yaml', 'w', encoding='utf-8') as f: - yaml.dump(data=data, stream=f, allow_unicode=True, sort_keys=False) - -def convert_time_to_str(time): - # 时间数字转化成字符串,不够10的前面补个0 - if (time < 10): - time = '0' + str(time) - else: - time = str(time) - return time - - -def sec_to_data(y): - h = int(y // 3600 % 24) - d = int(y // 86400) - h = convert_time_to_str(h) - d = convert_time_to_str(d) - return d + "天" + h + '小时' - - -def StrOfSize(size): - def strofsize(integer, remainder, level): - if integer >= 1024: - remainder = integer % 1024 - integer //= 1024 - level += 1 - return strofsize(integer, remainder, level) - elif integer < 0: - integer = 0 - return strofsize(integer, remainder, level) - else: - return integer, remainder, level - - units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'] - integer, remainder, level = strofsize(size, 0, 0) - if level + 1 > len(units): - level = -1 - return ('{}.{:>03d} {}'.format(integer, remainder, units[level])) - -def remove_convert(url): - #if "sub?target=" in url: - # pattern = r"url=([^&]*)" - # match = re.search(pattern, url) - # if match: - # encoded_url = match.group(1) - # decoded_url = unquote(encoded_url) - # url = decoded_url - # else: - # pass - #try: - # headers = {'User-Agent': sub_ua} - # res = requests.get(url, headers=headers, allow_redirects=False, timeout=try_time) - # url = res.headers['location'] - #except: - # pass - if "sub?target=" in url: - pattern = r"url=([^&]*)" - match = re.search(pattern, url) - if match: - encoded_url = match.group(1) - decoded_url = unquote(encoded_url) - url = decoded_url - else: - pass - return url - -# 初始化 -def botinit(): - global bot_name - bot_name = '@' + bot.get_me().username - bot.delete_my_commands(scope=None, language_code=None) - -## bot.set_my_commands( -## commands=[ -## telebot.types.BotCommand("help", "帮助菜单"), -## telebot.types.BotCommand("add", "添加订阅"), -## telebot.types.BotCommand("del", "删除订阅"), -## telebot.types.BotCommand("short", "生成短链"), -## telebot.types.BotCommand("search", "查找订阅"), -## telebot.types.BotCommand("update", "更新订阅"), -## telebot.types.BotCommand("random", "随机订阅"), -## telebot.types.BotCommand("notice", "发送消息"), -## telebot.types.BotCommand("subinfo", "订阅信息"), -## telebot.types.BotCommand("convert", "订阅转换"), -## telebot.types.BotCommand("restart", "重新启动"), -## ], -## ) - - f = open("airport.list","a", encoding="utf8") - - reload_config() - - logger.debug(f"[初始化完成]") - load_admin() - for send_id in administrator_id : - try : - bot.send_message(send_id, '[初始化完成]') - except : - continue - - -# 接收用户输入的指令 -@bot.message_handler(commands=['add', 'del', 'search', 'update', 'sort', 'notice', 'chat', 'random', 'auto', 'log', 'database', 'record', 'time', 'a', 'd', 's', 'u', 'n', 'r', 'c']) -def handle_command(message): - if not message.chat.type == "private" : - if not bot_name in message.text : - if not str(message.from_user.id) in admin_id: - return - if str(message.chat.id) in ban_chat : - if not str(message.from_user.id) in admin_id: - return - if str(message.from_user.id) in admin_id: - command = message.text.split()[0] - logger.debug(f"用户{message.from_user.id}使用了{command}功能") - if '/add' in command : - add_sub(message) - elif '/del' in command : - delete_sub(message) - elif '/search' in command : - search_sub(message) - elif '/update' in command : - update_sub(message) - elif '/sort' in command : - sort_sub(message) - elif '/notice' in command : - notice(message) - elif '/chat' in command : - chat(message) - elif '/random' in command : - random_sub(message) - elif '/auto' in command : - auto_sub(message) - elif '/log' in command: - get_log(message) - elif '/database' in command : - get_database(message) - elif '/record' in command : - get_record(message) - elif '/time' in command : - get_time(message) - elif '/a' in command : - add_sub(message) - elif '/d' in command : - delete_sub(message) - elif '/s' in command : - search_sub(message) - elif '/u' in command : - update_sub(message) - elif '/n' in command : - notice(message) - elif '/r' in command : - random_sub(message) - elif '/c' in command : - chat(message) - else: - bot.reply_to(message, "[WRONG][你没有操作权限]") - -# 更新临期订阅 -@bot.message_handler(commands=['updatesub']) -def get_impend(message) : - if not message.chat.type == "private" : - if not bot_name in message.text : - if not str(message.from_user.id) in admin_id : - return - if str(message.from_user.id) in admin_id : - try : - logger.debug(f"用户{message.from_user.id}使用了获取临期功能") - try : - search_str = message.text.split()[1] - except : - search_str = '临期' - global testsub_flag, stop_updatesub - if testsub_flag == 1 : - bot.reply_to(message, "[WRONG][临期订阅正在获取中]") - return - testsub_flag = 1 - sent_message = bot.reply_to(message, "准备获取订阅中...") - - w = open('Sub/Sub.txt', 'wb+') - c.execute("SELECT rowid,URL,comment FROM My_sub WHERE URL LIKE ? OR comment LIKE ?",('%' + search_str + '%', '%' + search_str + '%')) - result = c.fetchall() - - total = len(result) - - if total == 0 : - bot.edit_message_text(chat_id=sent_message.chat.id, message_id=sent_message.message_id, text="[WRONG][无临期订阅]") - return - keyboard = [] - keyboard.append([telebot.types.InlineKeyboardButton('❎ 停止获取', callback_data='stop_updatesub')]) - reply_markup = telebot.types.InlineKeyboardMarkup(keyboard) - i = 0 - sending_time = 0 - global send_percent - for item in result: - try : - if stop_updatesub == 1: - stop_updatesub = 0 - testsub_flag = 0 - reply_markup = [] - bot.edit_message_text(chat_id=sent_message.chat.id, message_id=sent_message.message_id, text="[获取已停止]", reply_markup=reply_markup) - return - i = i + 1 - cal = i / total * 100 - if cal > sending_time: - sending_time += send_percent - equal_signs = int(cal / 5) - space_count = 20 - equal_signs - bot.edit_message_text(chat_id=sent_message.chat.id, message_id=sent_message.message_id, text="正在获取订阅中\n\n \[`" + "=" * equal_signs + " " * space_count + "`]\n\n目前剩余任务数量为: `" + str(total - i + 1) + "`", parse_mode = 'Markdown', reply_markup=reply_markup) - url = item[1] - n = requests.get(backend + 'sub?target=mixed&url=' + url) - n = n.content.decode().replace('=', 'A') - if not '!' in n: - if not 'contain' in n: - w.write(n.encode()) - except : - pass - reply_markup = [] - bot.edit_message_text(chat_id=sent_message.chat.id, message_id=sent_message.message_id, text="防删除哒咩", reply_markup=reply_markup) - bot.delete_message(sent_message.chat.id, sent_message.message_id) - bot.reply_to(message, "[✅][更新成功]") - testsub_flag = 0 - except : - bot.reply_to(message, "[WRONG][更新失败]") - testsub_flag = 0 - else: - bot.reply_to(message, "[WRONG][你没有操作权限]") - -# 测活 -@bot.message_handler(commands=['prune']) -def get_test(message) : - if not message.chat.type == "private" : - if not bot_name in message.text : - if not str(message.from_user.id) in admin_id : - return - if str(message.from_user.id) in admin_id : - try : - try : - search_str = message.text.split()[1] - except : - search_str = 'h' - global testsub_flag, stop_prune - if testsub_flag == 1 : - bot.reply_to(message, "[WRONG][订阅正在获取中]") - return - testsub_flag = 1 - sent_message = bot.reply_to(message, "准备获取订阅中...") - search_str1 = '失效' - c.execute("SELECT rowid,URL,comment FROM My_sub WHERE URL LIKE ? OR comment LIKE ?",('%' + search_str1 + '%', '%' + search_str1 + '%')) - result = c.fetchall() - expto = len(result) - c.execute("SELECT rowid,URL,comment FROM My_sub WHERE URL LIKE ? OR comment LIKE ?",('%' + search_str + '%', '%' + search_str + '%')) - result = c.fetchall() - total = len(result) - if total == 0 : - bot.edit_message_text(chat_id=sent_message.chat.id, message_id=sent_message.message_id, text="[WRONG][无订阅]") - testsub_flag = 0 - return - keyboard = [] - keyboard.append([telebot.types.InlineKeyboardButton('❎ 停止获取', callback_data='stop_prune')]) - reply_markup = telebot.types.InlineKeyboardMarkup(keyboard) - i = 0 - sending_time = 0 - global send_percent - expire = [] - random.shuffle(result) - for item in result: - i = i + 1 - cal = i / total * 100 - if cal > sending_time: - sending_time += send_percent - equal_signs = int(cal / 5) - space_count = 20 - equal_signs - temp_text = "正在获取订阅中...\n\n \[`" + "=" * equal_signs + " " * space_count + "`]\n\n目前剩余任务数量为: `" + str(total - i + 1) + "`" - equal_signs = int(len(expire) / (((len(expire) + 1) * total / i) * 80 / 100 + expto * 20 / 100) * 20) - space_count = 20 - equal_signs - temp_text = temp_text + "\n\n \[`" + "=" * equal_signs + " " * space_count + "`]\n\n目前失效任务数量为: `" + str(len(expire)) + "`" - bot.edit_message_text(chat_id=sent_message.chat.id, message_id=sent_message.message_id, text=temp_text, parse_mode = 'Markdown', reply_markup=reply_markup) - url = item[1] - c.execute("SELECT * FROM My_sub WHERE URL LIKE ?", ('%' + url + '%',)) - result = c.fetchall() - print(result) - if len(result) > 1: - c.execute("DELETE FROM My_sub WHERE rowid=?", (item[0],)) - conn.commit() - continue - headers = {'User-Agent': sub_ua} - if stop_prune == 1: - stop_prune = 0 - testsub_flag = 0 - reply_markup = [] - bot.edit_message_text(chat_id=sent_message.chat.id, message_id=sent_message.message_id, text="[获取已停止]", reply_markup=reply_markup) - return - try: - res = requests.get(url, headers=headers, timeout=try_time) - except: - expire.append(item[0]) - c.execute("UPDATE My_sub SET URL=?, comment=? WHERE rowid=?", (item[1], item[2].replace('-过期', '').replace('-临期', '').replace('-失效', '').replace('-耗尽', '') + '-失效', item[0])) - conn.commit() - continue - c.execute("UPDATE My_sub SET URL=?, comment=? WHERE rowid=?", (item[1], item[2].replace('-过期', '').replace('-临期', '').replace('-失效', '').replace('-耗尽', ''), item[0])) - conn.commit() - try: - info = res.headers['subscription-userinfo'] - info_num = re.findall(r'\d+', info) - time_now = int(time.time()) - if int(info_num[2])-int(info_num[1])-int(info_num[0])<=1: - c.execute("UPDATE My_sub SET URL=?, comment=? WHERE rowid=?", (item[1], item[2].replace('-过期', '').replace('-临期', '').replace('-失效', '').replace('-耗尽', '') + '-耗尽', item[0])) - conn.commit() - except: - pass - try: - if res.status_code == 200: - info = res.headers['subscription-userinfo'] - info_num = re.findall(r'\d+', info) - time_now = int(time.time()) - if len(info_num) >= 4: - lasttime = int(info_num[3]) - time_now - d = int(lasttime // 86400) - if time_now > int(info_num[3]): - c.execute("UPDATE My_sub SET URL=?, comment=? WHERE rowid=?", (item[1], item[2].replace('-过期', '').replace('-临期', '').replace('-失效', '').replace('-耗尽', '') + '-过期', item[0])) - conn.commit() - elif d < impend : - c.execute("UPDATE My_sub SET URL=?, comment=? WHERE rowid=?", (item[1], item[2].replace('-过期', '').replace('-临期', '').replace('-失效', '').replace('-耗尽', '') + '-临期', item[0])) - conn.commit() - except: - pass - try: - u = re.findall('proxies:', res.text)[0] - if u == "proxies:": - pass - except: - try: - text = res.text[:64] - text = base64.b64decode(text) - text = str(text) - if filter_base64(text): - pass - else: - expire.append(item[0]) - c.execute("UPDATE My_sub SET URL=?, comment=? WHERE rowid=?", (item[1], item[2].replace('-过期', '').replace('-临期', '').replace('-失效', '').replace('-耗尽', '') + '-失效', item[0])) - conn.commit() - except: - expire.append(item[0]) - c.execute("UPDATE My_sub SET URL=?, comment=? WHERE rowid=?", (item[1], item[2].replace('-过期', '').replace('-临期', '').replace('-失效', '').replace('-耗尽', '') + '-失效', item[0])) - conn.commit() - reply_markup = [] - bot.edit_message_text(chat_id=sent_message.chat.id, message_id=sent_message.message_id, text="防删除哒咩", reply_markup=reply_markup) - bot.delete_message(sent_message.chat.id, sent_message.message_id) - expire = list(set(expire)) - expire.sort() - if len(expire) == 0: - message_raw = "无失效订阅" - else: - message_raw = "已失效订阅共 `" + str(len(expire)) + "` 条\n\n编号如下\n`" - for id in expire: - message_raw = message_raw + str(id) + " " - message_raw = message_raw + "`" - for send_id in administrator_id : - try : - bot.send_message(send_id, message_raw, parse_mode = 'Markdown') - except : - continue - if not message.from_user.id in administrator_id : - bot.send_message(message.from_user.id, message_raw, parse_mode = 'Markdown') - bot.reply_to(message, "[✅][更新成功]") - testsub_flag = 0 - except : - testsub_flag = 0 - bot.reply_to(message, "[WRONG][更新失败]") - else: - bot.reply_to(message, "[WRONG][你没有操作权限]") - - -# 取消信任群组 -@bot.message_handler(commands=['distrust']) -def get_id(message): - if not message.chat.type == "private" : - if not bot_name in message.text : - if not str(message.from_user.id) in administrator_id: - return - try : - if str(message.from_user.id) in administrator_id : - global trust_list - trust_list.remove(message.chat.id) - bot.reply_to(message, "[✅][已取消信任该群组]") - logger.debug(f"用户{message.from_user.id}使用了取消信任了{message.chat.id}群组") - except : - return - -# 信任群组 -@bot.message_handler(commands=['trust']) -def get_id(message): - if not message.chat.type == "private" : - if not bot_name in message.text : - if not str(message.from_user.id) in administrator_id: - return - try : - if str(message.from_user.id) in administrator_id : - global trust_list - trust_list.append(message.chat.id) - bot.reply_to(message, "[✅][已信任该群组]") - logger.debug(f"用户{message.from_user.id}使用了信任了{message.chat.id}群组") - except : - return - -# 管理员名单 -@bot.message_handler(commands=['list']) -def get_id(message): - if not message.chat.type == "private" : - if not bot_name in message.text : - if not str(message.from_user.id) in administrator_id: - return - try : - if str(message.from_user.id) in administrator_id : - id_text = "" - for id in admin_id : - id_text = id_text + str(id) + "\n" - bot.reply_to(message, id_text) - except : - return - -# 窥屏说话 -@bot.message_handler(commands=['peep', 'p']) -def peep(message): - if not message.chat.type == "private" : - return - if not str(message.from_user.id) in administrator_id: - return - try : - cont = "" - c = message.text.split()[1:] - for s in c : - cont = cont + " " + s - bot.send_message(peep_list[0], cont) - bot.reply_to(message, "[✅][接收成功]") - except : - return - -# 关闭窥屏 -@bot.message_handler(commands=['peepoff', 'poff']) -def peepoff(message): - if not message.chat.type == "private" : - return - if not str(message.from_user.id) in administrator_id: - return - try : - global peep_list - peep_list = [] - bot.reply_to(message, "[✅][接收成功]") - except : - return - -# 开启窥屏 -@bot.message_handler(commands=['peepon', 'pon']) -def peepon(message): - if not message.chat.type == "private" : - return - if not str(message.from_user.id) in administrator_id: - return - - try : - global peep_list - id = message.text.split()[1] - peep_list = [] - peep_list.append(id) - m = bot.reply_to(message, "[✅][接收成功]") - except : - return - -# 离开群聊 -@bot.message_handler(commands=['leave']) -def get_id(message): - if not message.chat.type == "private" : - if not bot_name in message.text : - if not str(message.from_user.id) in admin_id: - return - try : - global white_list - if message.chat.id in white_list : - white_list.remove(message.chat.id) - bot.leave_chat(message.chat.id) - logger.debug(f"用户{message.from_user.id}使用了离开群聊{message.chat.id}") - except : - return - -# 防拉群 -@bot.message_handler(func=lambda m: True, content_types=['new_chat_members']) -def auto_leave(message): - if not message.json['new_chat_participant']['username'] in bot_name : - return - if anti_group == 0: - return - try : - if anti_group == 1: - temp_id = admin_id - else: - temp_id = administrator_id - if not str(message.from_user.id) in temp_id: - if not message.chat.id in white_list : - try : - bot.reply_to(message, "❌ 机器人已启动防拉群模式 请联系管理拉群") - bot.leave_chat(message.chat.id) - logger.debug(f"在群聊{message.chat.id}自动离开了") - except : - pass - else : - white_list.append(message.chat.id) - except : - try : - bot.reply_to(message, "❌ 机器人已启动防拉群模式 请联系管理拉群") - bot.leave_chat(message.chat.id) - logger.debug(f"在群聊{message.chat.id}自动离开了") - except : - pass - -@bot.my_chat_member_handler() -def leave_ban(message: telebot.types.ChatMemberUpdated): - try : - if new.status == "left" : - white_list.remove(message.chat.id) - except : - pass - -##@bot.my_chat_member_handler() -##def auto_leave(message: telebot.types.ChatMemberUpdated): -## try : -## global white_list -## old = message.old_chat_member -## new = message.new_chat_member -## if new.status == "member" or new.status == "administrator": -## if not str(message.from_user.id) in admin_id: -## if not message.chat.id in white_list : -## try : -## bot.send_message(message.chat.id, "❌ 机器人已启动防拉群模式 请联系管理拉群") -## bot.leave_chat(message.chat.id) -## logger.debug(f"在群聊{message.chat.id}自动离开了") -## except : -## pass -## else : -## white_list.append(message.chat.id) -## if new.status == "left" : -## white_list.remove(message.chat.id) -## except : -## pass - -# 再次ban -@bot.message_handler(commands=['reban']) -def get_id(message): - if not message.chat.type == "private" : - if not bot_name in message.text : - if not str(message.from_user.id) in admin_id: - return - try : - if str(message.from_user.id) in admin_id : - global aleady - already = [] - bot.reply_to(message, "[✅][设置成功]") - logger.debug(f"用户{message.from_user.id}使用了/reban命令") - except : - return - -# 开启群聊回复 -@bot.message_handler(commands=['banoff']) -def get_id(message): - if not message.chat.type == "private" : - if not bot_name in message.text : - if not str(message.from_user.id) in admin_id: - return - try : - if str(message.from_user.id) in admin_id : - global ban_chat - ban_chat.remove(str(message.chat.id)) - bot.reply_to(message, "[✅][已开启群聊自动回复]") - logger.debug(f"用户{message.from_user.id}使用了开启了{message.chat.id}的自动回复") - except : - return - -# 关闭群聊回复 -@bot.message_handler(commands=['banon']) -def get_id(message): - if not message.chat.type == "private" : - if not bot_name in message.text : - if not str(message.from_user.id) in admin_id: - return - try : - if str(message.from_user.id) in admin_id : - global ban_chat - ban_chat.append(str(message.chat.id)) - bot.reply_to(message, "[✅][已关闭群聊自动回复]") - logger.debug(f"用户{message.from_user.id}使用了关闭了{message.chat.id}的自动回复") - except : - return - -# 开启测速记录 -@bot.message_handler(commands=['recordon']) -def get_id(message): - if not message.chat.type == "private" : - if not bot_name in message.text : - if not str(message.from_user.id) in admin_id: - return - try : - if str(message.from_user.id) in admin_id : - global record - record = 1 - bot.reply_to(message, "[✅][开启成功]") - except : - return - -# 关闭测速记录 -@bot.message_handler(commands=['recordoff']) -def get_id(message): - if not message.chat.type == "private" : - if not bot_name in message.text : - if not str(message.from_user.id) in admin_id: - return - try : - if str(message.from_user.id) in admin_id : - global record - record = 0 - bot.reply_to(message, "[✅][关闭成功]") - except : - return - -# 获取id -@bot.message_handler(commands=['id']) -def get_id(message): - if not message.chat.type == "private" : - if not bot_name in message.text : - if not str(message.from_user.id) in admin_id: - return - try : - id = message.reply_to_message.from_user.id - bot.reply_to(message, f"该条消息的id为 `{id}`\n群聊id为 `{message.chat.id}`", parse_mode = 'Markdown') - logger.debug(f"用户{message.from_user.id}使用了查询了群聊{message.chat.id}中{id}的id") - except : - return - -# 获取时间 -def get_time(message): - try : - now_time = time.strftime("%H:%M:%S", time.localtime()) - bot.send_message(message.chat.id, f"\\[当前系统时间为 `{now_time}`]", parse_mode = 'Markdown') - except : - bot.send_message(message.chat.id, "[WRONG][获取时间失败]") - -# 获取数据库 -def get_database(message): - try : - if password in message.text : - with open('./My_sub.db', 'rb') as f: - bot.send_document(message.chat.id, f) - f.close() - else : - bot.send_message(message.chat.id, "[WRONG][获取数据库失败]") - except : - bot.send_message(message.chat.id, "[WRONG][获取数据库失败]") - -# 获取日志 -def get_log(message): - try : - if password in message.text : - with open('./bot.log', 'rb') as f: - bot.send_document(message.chat.id, f) - f.close() - else : - bot.send_message(message.chat.id, "[WRONG][获取日志失败]") - except : - bot.send_message(message.chat.id, "[WRONG][获取日志失败]") - -# 下载仓库 -@bot.message_handler(commands=['install']) -def save_database(message) : - if not bot_name in message.text : - if not message.chat.type == "private" : - return - if str(message.chat.id) in ban_chat : - if not str(message.from_user.id) in admin_id : - return - if str(message.from_user.id) in administrator_id : - try : - if password in message.text: - fil = bot.get_file(message.reply_to_message.document.file_id) - f = requests.get(f"https://api.telegram.org/file/bot{load_bottoken()}/{fil.file_path}", timeout=try_time) - with open("My_sub.db", "wb") as code: - code.write(f.content) - bot.reply_to(message, "[✅][下载成功]") - else : - bot.reply_to(message, "[WRONG][下载失败]") - except : - bot.reply_to(message, "[WRONG][下载失败]") - else: - bot.reply_to(message, "[WRONG][你没有操作权限]") - -# 获取测速日志 -def get_record(message): - try : - if password in message.text.split()[1] : - with open('./log/log.txt', 'rb') as f: - bot.send_document(message.chat.id, f) - f.close() - with open('./log/log.ini', 'rb') as f: - bot.send_document(message.chat.id, f) - f.close() - else : - bot.send_message(message.chat.id, "[WRONG][获取日志失败]") - except : - bot.send_message(message.chat.id, "[WRONG][获取日志失败]") - -# 获取关键词 -@bot.message_handler(commands=['keyword']) -def get_airport(message) : - if not message.chat.type == "private" : - if not bot_name in message.text : - if not str(message.from_user.id) in admin_id : - return - if str(message.from_user.id) in administrator_id : - try : - s = "1" - - except : - bot.reply_to(message, "[WRONG][获取失败]") - else: - bot.reply_to(message, "[WRONG][你没有操作权限]") - -# 添加关键词 -@bot.message_handler(commands=['addkeyword']) -def save_airport(message) : - if not message.chat.type == "private" : - if not bot_name in message.text : - if not str(message.from_user.id) in admin_id : - return - if str(message.from_user.id) in administrator_id : - try : - a = message.text.split()[1] - b = message.text.split()[2] - - r = open('airport.list',encoding='utf8') - while True : - line = r.readline() - if not line : - break - keyword = line.split()[0] - if a in keyword : - bot.reply_to(message, "[WRONG][已有该关键词]") - return - - with open("airport.list","a", encoding="utf8") as f : - f.write(a + ' ' + b + '\n') - bot.reply_to(message, "[✅][添加成功]") - except : - bot.reply_to(message, "[WRONG][添加失败]") - else: - bot.reply_to(message, "[WRONG][你没有操作权限]") - -# 删除机场关键词 -@bot.message_handler(commands=['delkeyword']) -def del_airport(message): - if not message.chat.type == "private" : - if not bot_name in message.text : - if not str(message.from_user.id) in admin_id : - return - if str(message.from_user.id) in administrator_id : - try : - name_list = [] - a = message.text.split()[1] - r = open('airport.list',encoding='utf8') - flag = 0 - while True : - line = r.readline() - if not line : - break - keyword = line.split()[0] - if not a == keyword : - name_list.append(line) - else : - flag = 1 - if flag == 0 : - bot.reply_to(message, "[WRONG][删除失败]") - else : - with open("airport.list","w", encoding="utf8") as f : - for name in name_list : - f.write(name) - bot.reply_to(message, "[✅][删除成功]") - except : - bot.reply_to(message, "[WRONG][删除失败]") - else: - bot.reply_to(message, "[WRONG][你没有操作权限]") - - -# 授权 -@bot.message_handler(commands=['grant']) -def grant(message): - if not bot_name in message.text : - if not message.chat.type == "private" : - return - - if str(message.from_user.id) in administrator_id : - try : - id_text = message.text.split() - if len(id_text) < 2: - logger.debug(f"用户{message.from_user.id}在群聊{message.reply_to_message.chat.id}授予了{message.reply_to_message.from_user.id}管理员权限") - if not str(message.reply_to_message.from_user.id) in admin_id : - admin_id.append(str(message.reply_to_message.from_user.id)) - else: - for i in id_text[1:]: - if not i in admin_id : - logger.debug(f"用户{message.from_user.id}授予了{i}管理员权限") - admin_id.append(i) - save_admin() - bot.reply_to(message, "[✅][授权成功]") - except : - bot.reply_to(message, "[WRONG][授权失败]") - else: - bot.reply_to(message, "[WRONG][你没有操作权限]") - -# 取消授权 -@bot.message_handler(commands=['ungrant']) -def ungrant(message): - if not bot_name in message.text : - if not message.chat.type == "private" : - return - - if str(message.from_user.id) in administrator_id : - try : - id_text = message.text.split() - if len(id_text) < 2: - logger.debug(f"用户{message.from_user.id}在群聊{message.reply_to_message.chat.id}取消了{message.reply_to_message.from_user.id}管理员权限") - if str(message.reply_to_message.from_user.id) in admin_id : - admin_id.remove(str(message.reply_to_message.from_user.id)) - else: - for i in id_text[1:]: - if i in admin_id : - logger.debug(f"用户{message.from_user.id}取消了{i}管理员权限") - admin_id.remove(i) - save_admin() - bot.reply_to(message, "[✅][消权成功]") - except : - bot.reply_to(message, "[WRONG][消权失败]") - else: - bot.reply_to(message, "[WRONG][你没有操作权限]") - -# 恢复授权 -@bot.message_handler(commands=['grantbackup']) -def grant(message): - if not message.chat.type == "private" : - if not bot_name in message.text : - if not str(message.from_user.id) in administrator_id : - return - - if str(message.from_user.id) in administrator_id : - try : - global admin_id - admin_id = [] - admin_id = admin_backup - save_admin() - bot.reply_to(message, "[✅][恢复成功]") - except : - bot.reply_to(message, "[WRONG][恢复失败]") - else: - bot.reply_to(message, "[WRONG][你没有操作权限]") - -# 清理授权 -@bot.message_handler(commands=['grantclear']) -def grant(message): - if not message.chat.type == "private" : - if not bot_name in message.text : - if not str(message.from_user.id) in administrator_id : - return - - if str(message.from_user.id) in administrator_id : - try : - global admin_id - admin_id = [] - with open("admin.txt","w") as f : - f.write('0') - bot.reply_to(message, "[✅][清理成功]") - except : - bot.reply_to(message, "[WRONG][清理失败]") - else: - bot.reply_to(message, "[WRONG][你没有操作权限]") - -# 关机 -@bot.message_handler(commands=['stop']) -def stop(message): - if not message.chat.type == "private" : - if not str(message.from_user.id) in administrator_id: - return - if str(message.from_user.id) in admin_id: - if password in message.text: - try : - bot.reply_to(message, "[✅][接收命令成功]") - print('关机中') - for send_id in administrator_id : - try : - bot.send_message(send_id, '[关机中...]') - except : - continue - os._exit(0) - except : - print('关机失败') - for send_id in administrator_id : - try : - bot.send_message(send_id, '[WRONG][关机失败]') - except : - continue - else : - bot.reply_to(message, "[WRONG][密码错误]") - else: - bot.reply_to(message, "[WRONG][你没有操作权限]") - -# 重启 -@bot.message_handler(commands=['restart']) -def restart(message): - if not message.chat.type == "private" : - if not str(message.from_user.id) in administrator_id: - return - if str(message.from_user.id) in admin_id: - try : - bot.reply_to(message, "[✅][接收命令成功]") - print('重启中') - for send_id in administrator_id : - try : - bot.send_message(send_id, '[重启中...]') - except : - continue - - f = requests.get(bot_web, timeout=try_time) - with open("main.py", "wb") as code: - code.write(f.content) - - p = sys.executable - os.execl(p, p, *sys.argv) - sys.exit() - except : - print('重启失败') - for send_id in administrator_id : - try : - bot.send_message(send_id, '[WRONG][重启失败]') - except : - continue - else: - bot.reply_to(message, "[WRONG][你没有操作权限]") - -# 注册监测任务 -@bot.message_handler(commands=['register']) -def register_cron(message): - if not message.chat.type == "private" : - if not bot_name in message.text : - if '@' in message.text : - return - if str(message.chat.id) in ban_chat : - if not str(message.from_user.id) in admin_id : - return - if str(message.from_user.id) in admin_id : - try : - task_name = str(message.chat.id) - try: - for cron in cron_list: - try: - if message.chat.id == list(cron.keys())[0]: - cron_list.remove(cron) - except: - pass - except: - pass - try: - cron_list.remove(message.chat.id) - except: - pass - try: - cron_list.append({message.chat.id: message.text.split()[1]}) - task_name = task_name + ':' + message.text.split()[1] - except: - cron_list.append(message.chat.id) - save_cron() - bot.reply_to(message, f"\[✅]\[注册任务 `{task_name}` 成功]", parse_mode = 'Markdown') - except : - bot.reply_to(message, "[WRONG][注册失败]") - else: - bot.reply_to(message, "[WRONG][你没有操作权限]") - -# 取消监测任务 -@bot.message_handler(commands=['unregister']) -def unregister_cron(message): - if not message.chat.type == "private" : - if not bot_name in message.text : - if '@' in message.text : - return - if str(message.chat.id) in ban_chat : - if not str(message.from_user.id) in admin_id : - return - if str(message.from_user.id) in admin_id : - try : - task_name = str(message.chat.id) - for cron in cron_list: - try: - if message.chat.id == list(cron.keys())[0]: - task_name = task_name + ':' + list(cron.values())[0] - cron_list.remove(cron) - except: - pass - try: - cron_list.remove(message.chat.id) - except: - pass - save_cron() - bot.reply_to(message, f"\[✅]\[取消任务 `{task_name}` 成功]", parse_mode = 'Markdown') - except : - bot.reply_to(message, "[WRONG][取消失败]") - else: - bot.reply_to(message, "[WRONG][你没有操作权限]") - -# 重载配置 -@bot.message_handler(commands=['reload']) -def reload(message): - if not message.chat.type == "private" : - if not bot_name in message.text : - if not str(message.from_user.id) in admin_id: - return - if str(message.chat.id) in ban_chat : - if not str(message.from_user.id) in admin_id : - return - if str(message.from_user.id) in administrator_id : - try : - reload_config() - bot.reply_to(message, "[✅][重载成功]") - except : - bot.reply_to(message, "[WRONG][重载失败]") - else: - bot.reply_to(message, "[WRONG][你没有操作权限]") - -# 保存配置 -@bot.message_handler(commands=['save']) -def save(message): - if not message.chat.type == "private" : - if not bot_name in message.text : - if not str(message.from_user.id) in admin_id: - return - if str(message.chat.id) in ban_chat : - if not str(message.from_user.id) in admin_id : - return - if str(message.from_user.id) in administrator_id : - try : - save_config() - bot.reply_to(message, "[✅][保存成功]") - except : - bot.reply_to(message, "[WRONG][保存失败]") - else: - bot.reply_to(message, "[WRONG][你没有操作权限]") - -# 设置配置 -@bot.message_handler(commands=['set']) -def set_value(message): - if not message.chat.type == "private" : - if not bot_name in message.text : - if not str(message.from_user.id) in admin_id: - return - if str(message.chat.id) in ban_chat : - if not str(message.from_user.id) in admin_id : - return - if str(message.from_user.id) in administrator_id : - try : - reload_config() - try: - with open('./config.yaml', 'r', encoding='utf-8') as f: - data = yaml.load(stream=f, Loader=yaml.FullLoader) - except: - pass - try: - text = message.text.split()[2] - except: - text = "" - for i in range(3, len(message.text.split())): - item = message.text.split()[i] - text = text + " " + item - if len(message.text.split()[1].split('.')) == 1: - data[message.text.split()[1].split('.')[0]] = text - elif len(message.text.split()[1].split('.')) == 2: - data[message.text.split()[1].split('.')[0]][message.text.split()[1].split('.')[1]] = text - else: - bot.reply_to(message, "[WRONG][迭代深度错误]") - return - with open('./config.yaml', 'w', encoding='utf-8') as f: - yaml.dump(data=data, stream=f, allow_unicode=True, sort_keys=False) - reload_config() - bot.reply_to(message, f"\\[✅]\\[已将配置 `{message.text.split()[1]}` 的值设置为]\n\n`{text}`", parse_mode = 'Markdown') - except : - bot.reply_to(message, "[WRONG][设置失败]") - else: - bot.reply_to(message, "[WRONG][你没有操作权限]") - -# 获取配置 -@bot.message_handler(commands=['value']) -def get_value(message): - if not message.chat.type == "private" : - if not bot_name in message.text : - if not str(message.from_user.id) in admin_id: - return - if str(message.chat.id) in ban_chat : - if not str(message.from_user.id) in admin_id : - return - if str(message.from_user.id) in administrator_id : - try : - reload_config() - try: - with open('./config.yaml', 'r', encoding='utf-8') as f: - data = yaml.load(stream=f, Loader=yaml.FullLoader) - except: - pass - if len(message.text.split()) == 1: - bot.reply_to(message, f"\\[✅]\\[全部配置的值为]\n\n`{str(data)}`", parse_mode = 'Markdown') - else: - for item in message.text.split()[1].split('.'): - data = data[item] - bot.reply_to(message, f"\\[✅]\\[配置 `{message.text.split()[1]}` 的值为]\n\n`{str(data)}`", parse_mode = 'Markdown') - except : - bot.reply_to(message, "[WRONG][读取失败]") - else: - bot.reply_to(message, "[WRONG][你没有操作权限]") - -# 随机订阅 -def random_sub(message): - data=requests.get("https://save-sub.pages.dev/",timeout=try_time) - url_list=re.findall("https?://[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|]",data.content.decode()) - cont = "" - for url in url_list : - cont = cont + '`' + url + '`\n\n' - keyboard = [] - keyboard.append([telebot.types.InlineKeyboardButton('❎ 关闭', callback_data='close')]) - reply_markup = telebot.types.InlineKeyboardMarkup(keyboard) - bot.send_message(message.chat.id, cont, parse_mode = 'Markdown', reply_markup=reply_markup) - -# 发送消息 -def chat(message): - if not message.chat.type == "private" : - return - cont = "" - try: - c = message.text.split()[1:] - for s in c : - cont = cont + " " + s - bot.reply_to(message, "[✅][发送成功]") - except: - bot.send_message(message.from_user.id, "[WRONG][输入格式有误 请检查后重新输入]") - return - for send_id in admin_id : - try : - if "None" in str(message.from_user.username) : - bot.send_message(send_id, f"\\[来自 [{str(message.from_user.id)}](tg://openmessage?user_id={str(message.from_user.id)}) 的消息]{cont}", parse_mode = 'Markdown') - else : - bot.send_message(send_id, f"[来自 @{str(message.from_user.username)} 的消息]{cont}") - except : - continue - -# 发送通知 -def notice(message): - if not message.chat.type == "private" : - return - cont = "" - try: - c = message.text.split()[1:] - for s in c : - cont = cont + " " + s - bot.reply_to(message, "[✅][发送成功]") - except: - bot.send_message(message.from_user.id, "[WRONG][输入格式有误 请检查后重新输入]") - return - for send_id in admin_id : - try : - if "None" in str(message.from_user.username) : - bot.send_message(send_id, f"\\[来自 [{str(message.from_user.id)}](tg://openmessage?user_id={str(message.from_user.id)}) 的通知]{cont}", parse_mode = 'Markdown') - else : - bot.send_message(send_id, f"[来自 @{str(message.from_user.username)} 的通知]{cont}") - except : - continue - -# 订阅链接查询 -@bot.message_handler(commands=['checksub']) -def startcheck(message): - if not message.chat.type == "private" : - if not bot_name in message.text : - if not str(message.from_user.id) in admin_id: - return - if str(message.chat.id) in ban_chat : - if not str(message.from_user.id) in admin_id: - return - if admin_only == 1: - if not str(message.from_user.id) in admin_id : - bot.reply_to(message, "[WRONG][你没有操作权限]") - return - global auto_check - identifier = ''.join(random.choices('0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', k=8)) - name = bot_name.replace('@', '') - url = f'https://t.me/{name}?start=' + identifier - keyboard = [] - keyboard.append([telebot.types.InlineKeyboardButton(text='发送订阅', url=url)]) - reply_markup = telebot.types.InlineKeyboardMarkup(keyboard) - sent_message = bot.reply_to(message, text= f'用户 `{message.from_user.first_name}` 请点击下方按键发送订阅查询流量', parse_mode = 'Markdown', reply_markup=reply_markup) - auto_check[identifier] = {'state': 0, 'user' : message.from_user.id, 'chat' : sent_message.chat.id, 'message': sent_message.message_id, 'identifier': identifier} - -# 订阅链接赠与 -@bot.message_handler(commands=['invite']) -def startinvite(message): - if not message.chat.type == "private" : - if not bot_name in message.text : - if str(message.from_user.id) in administrator_id : - if '@' in message.text : - return - else : - return - if str(message.chat.id) in ban_chat : - if not str(message.from_user.id) in admin_id: - return - if str(message.from_user.id) in admin_id or str(message.from_user.id) in administrator_id: - if message.reply_to_message : - reply = message.reply_to_message - try : - if message.text.split()[1] == "random": - flag = 0 - cnt = 0 - data=requests.get("https://save-sub.pages.dev/",timeout=try_time) - url_list=re.findall("https?://[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|]",data.content.decode()) - while (flag == 0): - if cnt >= 100: - break - random.shuffle(url_list) - search_str = url_list[random.randrange(0, len(url_list))] - c.execute("SELECT rowid,URL,comment FROM My_sub WHERE URL LIKE ? OR comment LIKE ?",('%' + search_str + '%', '%' + search_str + '%')) - resultcheck = c.fetchone() - if resultcheck: - sub_id = int(resultcheck[0]) - flag = 1 - else: - cnt = cnt + 1 - else: - if str(message.from_user.id) in administrator_id or (allow_invite == 1 and str(message.from_user.id) in admin_id): - sub_id = int(message.text.split()[1]) - else: - bot.reply_to(message, "[WRONG][你没有操作权限]") - except : - bot.reply_to(message, "[WARNING][命令格式不对呢]") - return - else : - bot.reply_to(message, "[WARNING][请回复用户消息呢]") - return - logger.debug(f"用户{message.from_user.id}赠与了用户{message.reply_to_message.from_user.id}订阅") - global auto_check - identifier = ''.join(random.choices('0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', k=8)) - name = bot_name.replace('@', '') - try: - identifier = message.text.split()[2] - except: - pass - url = f'https://t.me/{name}?start=' + identifier - c.execute("SELECT rowid,URL,comment FROM My_sub WHERE rowid=?", (sub_id,)) - result = c.fetchone() - subname = result[2] - keyboard = [] - keyboard.append([telebot.types.InlineKeyboardButton(text='获取订阅', url=url)]) - reply_markup = telebot.types.InlineKeyboardMarkup(keyboard) - sent_message = bot.reply_to(message.reply_to_message, text= f'用户 `{message.reply_to_message.from_user.first_name}` 您被 `{message.from_user.first_name}` 赠与了订阅 `{subname}` 请点击下方按键获取', parse_mode = 'Markdown', reply_markup=reply_markup) - auto_check[identifier] = {'state': 3, 'user' : message.reply_to_message.from_user.id, 'chat' : sent_message.chat.id, 'message': sent_message.message_id, 'identifier': identifier, 'result': result} - else: - bot.reply_to(message, "[WRONG][你没有操作权限]") - -# 订阅链接赠送 -@bot.message_handler(commands=['gift']) -def startgift(message): - if not message.chat.type == "private" : - if not bot_name in message.text : - if str(message.from_user.id) in administrator_id : - if '@' in message.text : - return - else : - return - if str(message.chat.id) in ban_chat : - if not str(message.from_user.id) in admin_id: - return - if str(message.from_user.id) in administrator_id: - try : - sub_id = message.text.split()[1] - try: - sub_id = int(sub_id) - except: - pass - except : - bot.reply_to(message, "[WARNING][命令格式不对呢]") - return - global auto_check - identifier = ''.join(random.choices('0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', k=8)) - try: - identifier = message.text.split()[2] - except: - pass - name = bot_name.replace('@', '') - url = f'https://t.me/{name}?start=' + identifier - if message.text.split()[1] == "random": - flag = 0 - cnt = 0 - data=requests.get("https://save-sub.pages.dev/",timeout=try_time) - url_list=re.findall("https?://[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|]",data.content.decode()) - while (flag == 0): - if cnt >= 100: - break - random.shuffle(url_list) - search_str = url_list[random.randrange(0, len(url_list))] - c.execute("SELECT rowid,URL,comment FROM My_sub WHERE URL LIKE ? OR comment LIKE ?",('%' + search_str + '%', '%' + search_str + '%')) - result = c.fetchone() - if result: - subname = "随机" - flag = 1 - else: - cnt = cnt + 1 - else: - c.execute("SELECT rowid,URL,comment FROM My_sub WHERE rowid=?", (sub_id,)) - result = c.fetchone() - subname = result[2] - keyboard = [] - keyboard.append([telebot.types.InlineKeyboardButton(text='获取订阅', url=url)]) - reply_markup = telebot.types.InlineKeyboardMarkup(keyboard) - sent_message = bot.reply_to(message, text= f'用户 `{message.from_user.first_name}` 赠送了 `{subname}` 订阅 请点击下方按键获取', parse_mode = 'Markdown', reply_markup=reply_markup) - auto_check[identifier] = {'state': 3, 'user' : -1, 'chat' : sent_message.chat.id, 'message': sent_message.message_id, 'identifier': identifier, 'result': result} - logger.debug(f"用户{message.from_user.id}赠送了{result}订阅") - else: - bot.reply_to(message, "[WRONG][你没有操作权限]") - -# 启动对话 -@bot.message_handler(commands=['start'],func = lambda message:message.chat.type == "private") -def start(message): - if not message.chat.type == "private" : - if not bot_name in message.text : - if not str(message.from_user.id) in admin_id: - return - auto_reply_text = message.text.replace('/start', '').strip() - try: - if len(auto_reply_text) > 0: - identifier = auto_reply_text - user = auto_check[identifier]['user'] - chat_id = auto_check[identifier]['chat'] - message_id = auto_check[identifier]['message'] - state = auto_check[identifier]['state'] - if user == message.from_user.id or user == -1: - if state == 0: - auto_check[identifier] = {'state': 4, 'chat' : chat_id, 'message': message_id, 'identifier': identifier} - bot.edit_message_text(chat_id=chat_id, message_id=message_id, text="正在发送订阅中...") - bot.send_message(message.from_user.id, "请发送需要查询的订阅链接 :") - auto_check[message.from_user.id] = {'state': 1, 'chat' : chat_id, 'message': message_id, 'identifier': identifier} - elif state == 3: - result = auto_check[identifier]['result'] - auto_check[identifier] = {'state': 4, 'chat' : chat_id, 'message': message_id, 'identifier': identifier} - headers = {'User-Agent': sub_ua} - output_test = '' - try : - try: - res = requests.get(result[1], headers=headers, timeout=try_time) - except: - output_text = '连接错误' - if res.status_code == 200: - try: - info = res.headers['subscription-userinfo'] - info_num = re.findall(r'\d+', info) - time_now = int(time.time()) - output_text_head = '上行:`' + StrOfSize(int(info_num[0])) + '`\n下行:`' + StrOfSize(int(info_num[1])) + '`\n剩余:`' + StrOfSize(int(info_num[2]) - int(info_num[1]) - int(info_num[0])) + '`\n总共:`' + StrOfSize(int(info_num[2])) + '`' - if len(info_num) >= 4: - timeArray = time.localtime(int(info_num[3]) + 28800) - dateTime = time.strftime("%Y-%m-%d", timeArray) - if time_now <= int(info_num[3]): - lasttime = int(info_num[3]) - time_now - output_text = output_text_head + '\n过期时间:`' + dateTime + '`\n剩余时间:`' + sec_to_data(lasttime) + '`' - elif time_now > int(info_num[3]): - output_text = output_text_head + '\n此订阅已于 `' + dateTime + '`过期' - else: - output_text = output_text_head + '\n过期时间:`没有说明`' - except: - output_text = '`无流量信息`' - else: - output_text = '`无法访问`' - - try : - d = int(lasttime // 86400) - if d < impend : - if not '临期' in result[2] : - c.execute("UPDATE My_sub SET URL=?, comment=? WHERE rowid=?", (result[1], result[2] + '-临期', result[0])) - conn.commit() - except : - pass - except: - output_text = '`无流量信息`' - logger.debug(f"用户{message.from_user.id}从BOT接受赠与了订阅{result}") - bot.edit_message_text(chat_id=chat_id, message_id=message_id, text=f"订阅已由 `{message.from_user.first_name}` 接收",parse_mode='Markdown') - bot.send_message(message.from_user.id, '编号 `{}`\n订阅 `{}`\n说明 `{}`\n\n{}'.format(result[0], result[1], result[2], output_text),parse_mode='Markdown') - else: - bot.send_message(message.chat.id, intro, parse_mode = 'Markdown') - logger.debug(f"用户{message.from_user.id}开始了对话") - except: - bot.send_message(message.chat.id, intro, parse_mode = 'Markdown') - logger.debug(f"用户{message.from_user.id}开始了对话") - -def StrSize(size): - def strofsize(integer, remainder, level): - if integer >= 1024: - remainder = integer % 1024 - integer //= 1024 - level += 1 - return strofsize(integer, remainder, level) - elif integer < 0: - integer = 0 - return strofsize(integer, remainder, level) - else: - return integer, remainder, level - - units = ['B', 'K', 'M', 'G', 'T', 'P', 'EB', 'ZB', 'YB'] - integer, remainder, level = strofsize(size, 0, 0) - if level + 1 > len(units): - level = -1 - return ('{}{}'.format(integer, units[level])) - -# 自动添加 -def auto_sub(message): - try: - url_list = [] - try : - url_list = re.findall("https?://[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|]", message.reply_to_message.text) - except : - url_list = re.findall("https?://[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|]", message.text) - if len(url_list) == 1: - try: - headers = {'User-Agent': link_ua} - res = requests.get(url_list[0], headers=headers, timeout=try_time) - temp_list = re.findall("https?://[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|]", res.text) - url_list.extend(temp_list) - except: - pass - url_list = list(set(url_list)) - for urla in url_list : - try : - url = remove_convert(urla) - c.execute("SELECT * FROM My_sub WHERE URL LIKE ?", ('%' + url + '%',)) - if c.fetchone(): - bot.reply_to(message, "[WRONG][订阅已存在]") - continue - comment = "" - name = "" - size = "" - flag = 0 - try: - r = open('airport.list',encoding='utf8') - while True : - line = r.readline() - if not line : - break - a = line.split()[0] - b = line.split()[1] - if a in url : - name = b - flag = 1 - break - except: - pass - if flag == 0 : - if "api/v1/client/subscribe?token" in url: - if "&flag=clash" not in url: - url = url + "&flag=clash" - else: - pass - try: - response = requests.get(url, timeout=try_time) - header = response.headers.get('Content-Disposition') - if header: - pattern = r"filename\*=UTF-8''(.+)" - result = re.search(pattern, header) - if result: - filename = result.group(1) - filename = parse.unquote(filename) - airport_name = filename.replace("%20", " ").replace("%2B", "+") - if not "Access denied" in airport_name: - if not "Blocked" in airport_name: - if not "Cloudflare" in airport_name: - if not "nginx" in airport_name: - name = airport_name - flag = 1 - except: - pass - else: - headers = { - 'User-Agent': link_ua} - try: - pattern = r'(https?://)([^/]+)' - match = re.search(pattern, url) - base_url = None - if match: - base_url = match.group(1) + match.group(2) - response = requests.get(base_url, headers=headers, timeout=try_time) - html = response.content - soup = BeautifulSoup(html, 'html.parser') - title = soup.title.string - if not "Access denied" in title: - if not "Blocked" in title: - if not "Cloudflare" in title: - if not "nginx" in title: - name = title - flag = 1 - except: - pass - if flag == 0 : - for send_id in administrator_id : - try : - bot.send_message(send_id, f'无法识别订阅\n`{url}`', parse_mode = 'Markdown') - except : - continue - bot.reply_to(message, f"\\[WRONG]\\[无法识别的订阅 请手动添加]\n`{url}`", parse_mode = 'Markdown') - continue - try : - headers = {'User-Agent': sub_ua} - res = requests.get(url, headers=headers, timeout=try_time) - if res.status_code == 200: - info = res.headers['subscription-userinfo'] - info_num = re.findall(r'\d+', info) - size = StrSize(int(info_num[2])) - comment = name + "-" + size - if int(info_num[2]) - int(info_num[1]) - int(info_num[0]) < 10 : - bot.reply_to(message, "[WARNING][订阅无流量]") - else : - bot.reply_to(message, "[WRONG][无法获取订阅 请检查后手动添加]") - continue - except : - bot.reply_to(message, "[WRONG][无法获取订阅 请检查后手动添加]") - continue - - c.execute("INSERT INTO My_sub VALUES(?,?)", (url, comment)) - conn.commit() - bot.reply_to(message, f"\[✅]\[订阅 `{comment}` 添加成功]", parse_mode = 'Markdown') - except : - pass - except : - bot.send_message(message.chat.id, "[WRONG][输入格式有误 请检查后重新输入]") - -# 添加数据 -def add_sub(message): - try: - url_comment = message.text.split()[1:] - url = remove_convert(url_comment[0]) - comment = url_comment[1] - c.execute("SELECT * FROM My_sub WHERE URL LIKE ?", ('%' + url + '%',)) - if c.fetchone(): - bot.reply_to(message, "[WRONG][订阅已存在]") - else: - c.execute("INSERT INTO My_sub VALUES(?,?)", (url, comment)) - conn.commit() - bot.reply_to(message, "[✅][添加成功]") - except: - bot.send_message(message.chat.id, "[WRONG][输入格式有误 请检查后重新输入]") - - -# 删除数据 -def delete_sub(message): - try: - id_text = message.text.split() - for row_num in id_text[1:]: - c.execute("DELETE FROM My_sub WHERE rowid=?", (row_num,)) - conn.commit() - bot.reply_to(message, "[✅][删除成功]") - except: - bot.send_message(message.chat.id, "[WRONG][输入格式有误 请检查后重新输入]") - -# 整理编号 -def sort_sub(message): - try: - c.execute("VACUUM") - conn.commit() - bot.reply_to(message, "[✅][整理成功]") - except: - bot.send_message(message.chat.id, "[WRONG][整理失败]") - - -items_per_page = 20 -result = None -callbacks = {} - -# 查找数据 -def search_sub(message): - global items_per_page, total, result, current_page - try: - search_str = message.text.split()[1] - c.execute("SELECT rowid,URL,comment FROM My_sub WHERE URL LIKE ? OR comment LIKE ?", - ('%' + search_str + '%', '%' + search_str + '%')) - result = c.fetchall() - if result: - try : - current_page = int(message.text.split()[2]) - except : - current_page = 1 - - pages = [result[i:i + items_per_page] for i in range(0, len(result), items_per_page)] - total = len(pages) - current_items = pages[current_page - 1] - keyboard = [] - - if current_page < 1: - bot.reply_to(message, "[WRONG][页数超出范围了]") - return - elif current_page > total: - bot.reply_to(message, "[WRONG][页数超出范围了]") - - for i in range(0, len(current_items), 2): - row = current_items[i:i + 2] - keyboard_row = [] - for item in row: - button = telebot.types.InlineKeyboardButton(item[2][0:10], callback_data=item[0]) - keyboard_row.append(button) - keyboard.append(keyboard_row) - if total > 1: - page_info = f'{current_page} / {total}' - if current_page == 1 : - prev_button = telebot.types.InlineKeyboardButton(' ', callback_data='blank') - else : - prev_button = telebot.types.InlineKeyboardButton('上一页', callback_data='prev') - if current_page == total : - next_button = telebot.types.InlineKeyboardButton(' ', callback_data='blank') - else : - next_button = telebot.types.InlineKeyboardButton('下一页', callback_data='next') - page_button = telebot.types.InlineKeyboardButton(page_info, callback_data=f'page_info {current_page} {total}') - page_buttons = [prev_button, page_button, next_button] - keyboard.append(page_buttons) - keyboard.append([telebot.types.InlineKeyboardButton('❎ 关闭', callback_data='close')]) - reply_markup = telebot.types.InlineKeyboardMarkup(keyboard) - sent_message = bot.reply_to(message, f'已查询到{str(len(result))}条订阅', reply_markup=reply_markup) - global sent_message_id - sent_message_id = sent_message.message_id - user_id = message.from_user.id - callbacks[sent_message_id] = {'total': total, 'current_page': current_page, 'result': result, 'sent_message_id': sent_message_id} - else: - keyboard = [] - keyboard.append([telebot.types.InlineKeyboardButton('❎ 关闭', callback_data='close')]) - reply_markup = telebot.types.InlineKeyboardMarkup(keyboard) - bot.reply_to(message, '[WRONG][没有查找到结果]', reply_markup = reply_markup) - except Exception as t: - print(t) - bot.send_message(message.chat.id, "[WRONG][输入格式有误 请检查后重新输入]") - -def update_buttons(callback_query, user_id): - global callbacks - callback_data = callback_query.data - message = callback_query.message - message_id = message.message_id - current_page = callbacks[message_id]['current_page'] - total = callbacks[message_id]['total'] - result = callbacks[message_id]['result'] - if callback_data == 'prev' and current_page > 1: - current_page -= 1 - elif callback_data == 'next' and current_page < total: - current_page += 1 - pages = [result[i:i + items_per_page] for i in range(0, len(result), items_per_page)] - current_items = pages[current_page - 1] - keyboard = [] - for i in range(0, len(current_items), 2): - row = current_items[i:i + 2] - keyboard_row = [] - for item in row: - button = telebot.types.InlineKeyboardButton(item[2][0:10], callback_data=item[0]) - keyboard_row.append(button) - keyboard.append(keyboard_row) - if total > 1: - page_info = f'{current_page} / {total}' - if current_page == 1 : - prev_button = telebot.types.InlineKeyboardButton(' ', callback_data='blank') - else : - prev_button = telebot.types.InlineKeyboardButton('上一页', callback_data='prev') - if current_page == total : - next_button = telebot.types.InlineKeyboardButton(' ', callback_data='blank') - else : - next_button = telebot.types.InlineKeyboardButton('下一页', callback_data='next') - page_button = telebot.types.InlineKeyboardButton(page_info, callback_data=f'page_info {current_page} {total}') - page_buttons = [prev_button, page_button, next_button] - keyboard.append(page_buttons) - keyboard.append([telebot.types.InlineKeyboardButton('❎ 关闭', callback_data='close')]) - reply_markup = telebot.types.InlineKeyboardMarkup(keyboard) - bot.edit_message_reply_markup(chat_id=message.chat.id, message_id=message_id, reply_markup=reply_markup) - callbacks[message_id]['current_page'] = current_page - -# 更新数据 -def update_sub(message): - try: - row_num = message.text.split()[1] - url_comment = message.text.split()[2:] - url = url_comment[0] - comment = url_comment[1] - c.execute("UPDATE My_sub SET URL=?, comment=? WHERE rowid=?", (url, comment, row_num)) - conn.commit() - bot.reply_to(message, "[✅][更新成功]") - except: - bot.send_message(message.chat.id, "[WRONG][输入格式有误 请检查后重新输入]") - -# 交换订阅 -@bot.message_handler(commands=['swap']) -def swap_sub(message) : - if not message.chat.type == "private" : - if not bot_name in message.text : - if not str(message.from_user.id) in admin_id : - return - if str(message.chat.id) in ban_chat : - if not str(message.from_user.id) in admin_id: - return - if str(message.from_user.id) in admin_id : - try : - try : - row_num1 = int(message.text.split()[1]) - row_num2 = int(message.text.split()[2]) - except : - bot.send_message(message.chat.id, "[WRONG][输入格式有误 请检查后重新输入]") - return - c.execute("SELECT rowid,URL,comment FROM My_sub WHERE rowid=?", (row_num1,)) - result1 = c.fetchone() - c.execute("SELECT rowid,URL,comment FROM My_sub WHERE rowid=?", (row_num2,)) - result2 = c.fetchone() - c.execute("UPDATE My_sub SET URL=?, comment=? WHERE rowid=?", (result2[1], result2[2], row_num1)) - c.execute("UPDATE My_sub SET URL=?, comment=? WHERE rowid=?", (result1[1], result1[2], row_num2)) - bot.reply_to(message, "[✅][交换成功]") - except : - bot.reply_to(message, "[WRONG][交换失败]") - else: - bot.reply_to(message, "[WRONG][你没有操作权限]") - - -# 接收xlsx表格 -#@bot.message_handler(content_types=['document'], func = lambda message:message.chat.type == "private") -def handle_document(message): - if str(message.from_user.id) in admin_id: - file_id = message.document.file_id - file_info = bot.get_file(file_id) - try: - file = bot.download_file(file_info.file_path) - with open('sub.xlsx', 'wb') as f: - f.write(file) - df = pd.read_excel('sub.xlsx') - for i in range(len(df)): - c.execute("SELECT * FROM My_sub WHERE URL=?", (df.iloc[i, 0],)) - if not c.fetchone(): - c.execute("INSERT INTO My_sub VALUES(?,?)", (df.iloc[i, 0], df.iloc[i, 1])) - conn.commit() - bot.reply_to(message, "[✅][导入成功]") - except: - bot.send_message(message.chat.id, "[WRONG][导入的文件格式错误 请检查文件后缀是否为xlsx后重新导入]") - else: - bot.reply_to(message, "[WARNING][你不是管理员 禁止操作]") - -# 修改备注 -@bot.message_handler(commands=['comment']) -def update_sub(message): - if not message.chat.type == "private" : - if not bot_name in message.text : - if not str(message.from_user.id) in admin_id: - return - if str(message.chat.id) in ban_chat : - if not str(message.from_user.id) in admin_id: - return - if str(message.from_user.id) in admin_id: - try: - row_num = message.text.split()[1] - comment = message.text.split()[2] - c.execute("UPDATE My_sub SET comment=? WHERE rowid=?", (comment, row_num)) - conn.commit() - bot.reply_to(message, "[✅][更新成功]") - except: - bot.send_message(message.chat.id, "[WRONG][输入格式有误 请检查后重新输入]") - -# 编号获取 -@bot.message_handler(commands=['get']) -def get_sub(message): - if not message.chat.type == "private" : - if not bot_name in message.text : - if not str(message.from_user.id) in admin_id: - return - if str(message.chat.id) in ban_chat : - if not str(message.from_user.id) in admin_id: - return - if str(message.from_user.id) in admin_id: - try: - row_num = int(message.text.split()[1]) - c.execute("SELECT rowid,URL,comment FROM My_sub WHERE rowid=?", (row_num,)) - result = c.fetchone() - headers = {'User-Agent': sub_ua} - output_test = '' - try : - try: - res = requests.get(result[1], headers=headers, timeout=try_time) - except: - output_text = '连接错误' - if res.status_code == 200: - try: - info = res.headers['subscription-userinfo'] - info_num = re.findall(r'\d+', info) - time_now = int(time.time()) - output_text_head = '上行:`' + StrOfSize(int(info_num[0])) + '`\n下行:`' + StrOfSize(int(info_num[1])) + '`\n剩余:`' + StrOfSize(int(info_num[2]) - int(info_num[1]) - int(info_num[0])) + '`\n总共:`' + StrOfSize(int(info_num[2])) + '`' - if len(info_num) >= 4: - timeArray = time.localtime(int(info_num[3]) + 28800) - dateTime = time.strftime("%Y-%m-%d", timeArray) - if time_now <= int(info_num[3]): - lasttime = int(info_num[3]) - time_now - output_text = output_text_head + '\n过期时间:`' + dateTime + '`\n剩余时间:`' + sec_to_data(lasttime) + '`' - elif time_now > int(info_num[3]): - output_text = output_text_head + '\n此订阅已于 `' + dateTime + '`过期' - else: - output_text = output_text_head + '\n过期时间:`没有说明`' - except: - output_text = '`无流量信息`' - else: - output_text = '`无法访问`' - - try : - d = int(lasttime // 86400) - if d < impend : - if not '临期' in result[2] : - c.execute("UPDATE My_sub SET URL=?, comment=? WHERE rowid=?", (result[1], result[2] + '-临期', result[0])) - conn.commit() - except : - pass - except: - output_text = '`无流量信息`' - keyboard = [] - keyboard.append([telebot.types.InlineKeyboardButton('❎ 关闭', callback_data='close')]) - reply_markup = telebot.types.InlineKeyboardMarkup(keyboard) - if message.chat.id in trust_list : - bot.send_message(message.chat.id, '编号 `{}`\n订阅 `{}`\n说明 `{}`\n\n{}'.format(result[0], result[1], result[2], output_text),parse_mode='Markdown', reply_markup = reply_markup) - else : - bot.send_message(message.from_user.id, '编号 `{}`\n订阅 `{}`\n说明 `{}`\n\n{}'.format(result[0], result[1], result[2], output_text),parse_mode='Markdown', reply_markup = reply_markup) - logger.debug(f"用户{message.from_user.id}从BOT获取了{result}") - except: - bot.send_message(message.chat.id, "[WARNING][该订阅已被管理员删除]") - -# 页数跳转 -@bot.message_handler(commands=['page']) -def page_change(message): - if not message.chat.type == "private" : - if not bot_name in message.text : - if not str(message.from_user.id) in admin_id: - return - if str(message.chat.id) in ban_chat : - if not str(message.from_user.id) in admin_id: - return - if str(message.from_user.id) in admin_id: - if message.reply_to_message : - reply = message.reply_to_message - try : - current_page = int(message.text.split()[1]) - except : - bot.reply_to(message, "[WARNING][命令格式不对呢]") - return - else : - bot.reply_to(message, "[WARNING][请回复订阅消息呢]") - return - - message_temp = message.reply_to_message - message_id = message_temp.message_id - total = callbacks[message_id]['total'] - result = callbacks[message_id]['result'] - if current_page < 1: - bot.reply_to(message, "[WRONG][页数超出范围了]") - return - elif current_page > total: - bot.reply_to(message, "[WRONG][页数超出范围了]") - return - pages = [result[i:i + items_per_page] for i in range(0, len(result), items_per_page)] - current_items = pages[current_page - 1] - keyboard = [] - for i in range(0, len(current_items), 2): - row = current_items[i:i + 2] - keyboard_row = [] - for item in row: - button = telebot.types.InlineKeyboardButton(item[2][0:10], callback_data=item[0]) - keyboard_row.append(button) - keyboard.append(keyboard_row) - if total > 1: - page_info = f' {current_page} / {total}' - if current_page == 1 : - prev_button = telebot.types.InlineKeyboardButton(' ', callback_data='blank') - else : - prev_button = telebot.types.InlineKeyboardButton('上一页', callback_data='prev') - if current_page == total : - next_button = telebot.types.InlineKeyboardButton(' ', callback_data='blank') - else : - next_button = telebot.types.InlineKeyboardButton('下一页', callback_data='next') - page_button = telebot.types.InlineKeyboardButton(page_info, callback_data=f'page_info {current_page} {total}') - page_buttons = [prev_button, page_button, next_button] - keyboard.append(page_buttons) - keyboard.append([telebot.types.InlineKeyboardButton('❎ 关闭', callback_data='close')]) - reply_markup = telebot.types.InlineKeyboardMarkup(keyboard) - bot.edit_message_reply_markup(chat_id=message_temp.chat.id, message_id=message_id, reply_markup=reply_markup) - callbacks[message_id]['current_page'] = current_page - else: - bot.reply_to(message, "[WRONG][你没有操作权限]") - -def subinfo(message, url): - headers = {'User-Agent': sub_ua} - try: - message_raw = url - final_output = '' - reply_list = [] - try : - reply_list = re.findall("https?://[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|]", message.reply_to_message.text) - except : - pass - url_list = re.findall("https?://[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|]",message_raw) - try : - url_list.extend(reply_list) - except : - pass - url_list = list(set(url_list)) - for urla in url_list: - url = remove_convert(urla) - logger.debug(f"用户{message.from_user.id}使用了/subinfo功能查询了{url}订阅") - try: - res = requests.get(url, headers=headers, timeout=try_time) - except: - final_output = final_output +'订阅链接:`' + url + '`\n连接错误' + '\n\n' - continue - if res.status_code == 200: - try: - comment = "" - name = "" - size = "" - flag = 0 - try : - r = open('airport.list',encoding='utf8') - while True : - line = r.readline() - if not line : - break - a = line.split()[0] - b = line.split()[1] - if a in url : - name = b - flag = 1 - break - except : - pass - if flag == 0 : - if "api/v1/client/subscribe?token" in url: - if "&flag=clash" not in url: - url = url + "&flag=clash" - else: - pass - try: - response = requests.get(url, timeout=try_time) - header = response.headers.get('Content-Disposition') - if header: - pattern = r"filename\*=UTF-8''(.+)" - result = re.search(pattern, header) - if result: - filename = result.group(1) - filename = parse.unquote(filename) - airport_name = filename.replace("%20", " ").replace("%2B", "+") - if not "Access denied" in airport_name: - if not "Blocked" in airport_name: - if not "Cloudflare" in airport_name: - if not "nginx" in airport_name: - name = airport_name - flag = 1 - except: - pass - else: - headers = { - 'User-Agent': link_ua} - try: - pattern = r'(https?://)([^/]+)' - match = re.search(pattern, url) - base_url = None - if match: - base_url = match.group(1) + match.group(2) - response = requests.get(base_url, headers=headers, timeout=try_time) - html = response.content - soup = BeautifulSoup(html, 'html.parser') - title = soup.title.string - if not "Access denied" in title: - if not "Blocked" in title: - if not "Cloudflare" in title: - if not "nginx" in title: - name = title - flag = 1 - except: - pass - info = res.headers['subscription-userinfo'] - info_num = re.findall(r'\d+', info) - time_now = int(time.time()) - if flag == 1: - output_text_head = '订阅链接:`' + url + '`\n机场名称:`' + name + '`\n已用上行:`' + StrOfSize(int(info_num[0])) + '`\n已用下行:`' + StrOfSize(int(info_num[1])) + '`\n剩余:`' + StrOfSize(int(info_num[2]) - int(info_num[1]) - int(info_num[0])) + '`\n总共:`' + StrOfSize(int(info_num[2])) - else: - output_text_head = '订阅链接:`' + url + '`\n已用上行:`' + StrOfSize(int(info_num[0])) + '`\n已用下行:`' + StrOfSize(int(info_num[1])) + '`\n剩余:`' + StrOfSize(int(info_num[2]) - int(info_num[1]) - int(info_num[0])) + '`\n总共:`' + StrOfSize(int(info_num[2])) - if len(info_num) >= 4: - timeArray = time.localtime(int(info_num[3]) + 28800) - dateTime = time.strftime("%Y-%m-%d", timeArray) - if time_now <= int(info_num[3]): - lasttime = int(info_num[3]) - time_now - output_text = output_text_head + '`\n过期时间:`' + dateTime + '`\n剩余时间:`' + sec_to_data(lasttime) + '`' - elif time_now > int(info_num[3]): - output_text = output_text_head + '`\n此订阅已于`' + dateTime + '`过期' - else: - output_text = output_text_head + '`\n到期时间:`没有说明`' - except: - output_text = '订阅链接:`' + url + '`\n无流量信息' - else: - output_text = '订阅链接:`' + url + '`\n无法访问\n' - final_output = final_output + output_text + '\n\n' - return (final_output) - except: - return ('参数错误') - -@bot.message_handler(commands=['subinfo', 'info', 'i']) -def get_subinfo(message): - if str(message.chat.id) in ban_chat : - if not str(message.from_user.id) in admin_id: - return - if not message.chat.type == "private" : - if not bot_name in message.text : - if not str(message.from_user.id) in admin_id: - return - if admin_only == 1: - if not str(message.from_user.id) in admin_id : - bot.reply_to(message, "[WRONG][你没有操作权限]") - return - info_text = subinfo(message, message.text) - try: - bot.reply_to(message, info_text,parse_mode='Markdown') - except: - return - -def sub_convert(message): - try: - try : - reply_list = re.findall("[-A-Za-z0-9+&@#/%?=~_|!:,.;]+://[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|]", message.reply_to_message.text) - except : - pass - url_list = re.findall("[-A-Za-z0-9+&@#/%?=~_|!:,.;]+://[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|]", message.text) - try : - url_list.extend(reply_list) - except : - pass - result = "[订阅链接]("+ backend + "sub?target=" + target + "&url=" + parse.quote_plus(remove_convert(url_list[0])) - logger.debug(f"用户{message.from_user.id}使用了/convert功能转换了{url_list[0]}订阅") - for url in url_list[1:]: - logger.debug(f"用户{message.from_user.id}使用了/convert功能转换了{url}订阅") - if len(url) != 0: - result = result + "|" + parse.quote_plus(remove_convert(url)) - result = result + "&insert=false&config=" + config + "&emoji=true&remove_emoji=false&filename=FacMata®&udp=true&expand=false&list=false&scv=true&fdn=true&interval=3600&new_name=true)" - return result - except: - return ('参数错误') - -@bot.message_handler(commands=['convert']) -def get_subzh(message): - if not message.chat.type == "private" : - if not bot_name in message.text : - if not str(message.from_user.id) in admin_id: - return - if str(message.chat.id) in ban_chat : - if not str(message.from_user.id) in admin_id: - return - if admin_only == 1: - if not str(message.from_user.id) in admin_id : - bot.reply_to(message, "[WRONG][你没有操作权限]") - return - atext = sub_convert(message) - bot.reply_to(message, atext, parse_mode = 'Markdown') - -@bot.message_handler(commands=['short']) -def short_sub(message): - if not message.chat.type == "private" : - if not bot_name in message.text : - if not str(message.from_user.id) in admin_id: - return - if str(message.chat.id) in ban_chat : - if not str(message.from_user.id) in admin_id: - return - if admin_only == 1: - if not str(message.from_user.id) in admin_id : - bot.reply_to(message, "[WRONG][你没有操作权限]") - return - url = "" - try : - url = re.findall("[-A-Za-z0-9+&@#/%?=~_|!:,.;]+://[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|]", message.reply_to_message.text) - except : - url = re.findall("[-A-Za-z0-9+&@#/%?=~_|!:,.;]+://[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|]", message.text) - url = url[0] - try : - data = requests.get(shortlink + url, timeout=try_time) - url = re.findall("https?://[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|]",data.content.decode()) - url = url[0] - except : - pass - - bot.reply_to(message, url, parse_mode = 'Markdown') - -class sspanel(): - def __init__(self,url,proxy=None): - self._proxies = proxy - self._name='' - self._url = url - self._reg_url='' - self._login_url = '' - self._user_url = '' - self._sub='' - - def set_env(self): - self._name = urllib.parse.urlparse(self._url).netloc - self._reg_url = 'https://' + self._name + '/auth/register' - self._login_url = 'https://' + self._name + '/auth/login' - self._user_url = 'https://' + self._name + '/user' - - def register(self,email,password): - headers= { - "User-Agent":link_ua, - "referer": self._reg_url - } - data={ - "email":email, - "name":password, - "passwd":password, - "repasswd":password, - "invite_code":None, - "email_code":None - } - geetest={ - "geetest_challenge": "98dce83da57b0395e163467c9dae521b1f", - "geetest_validate": "bebe713_e80_222ebc4a0", - "geetest_seccode": "bebe713_e80_222ebc4a0|jordan"} - data.update(geetest) - with requests.session() as session: - resp = session.post(self._reg_url,headers=headers,data=data,timeout=5,proxies=self._proxies) - - data ={ - 'email': email, - 'passwd': password, - 'code': '', - 'remember_me': 1, - } - try: - resp = session.post(self._login_url,headers=headers,data=data,timeout=5,proxies=self._proxies) - except: - pass - - resp = session.get(self._user_url,headers=headers,timeout=5,proxies=self._proxies) - try: - token = re.search("https?://[-A-Za-z0-9+&@#/%?=~_|!:,.;]+clash=1", resp.text).group(0) - except: - token= re.search("https?://[-A-Za-z0-9+&@#/%?=~_|!:,.;]+sub=3", resp.text).group(0) - self._sub = token - return token - - - def getSubscribe(self): - password=''.join(random.sample(string.ascii_letters + string.digits + string.ascii_lowercase, 10)) - email=password+"@gmail.com" - subscribe=self.register(email,password) - return subscribe - -class v2board(): - def __init__(self,url,proxy=None): - self._proxies = proxy - self._name='' - self._url = url - self._reg_url='' - self._sub='' - - def set_env(self): - self._name = urllib.parse.urlparse(self._url).netloc - self._reg_url = 'https://' + self._name + '/api/v1/passport/auth/register' - self._sub = 'https://' + self._name + '/api/v1/client/subscribe?token={token}' - - def register(self,email,password): - headers= { - "User-Agent":link_ua, - "Refer": self._url - } - data={ - "email":email, - "password":password, - "invite_code":None, - "email_code":None - } - req=requests.post(self._reg_url,headers=headers,data=data,timeout=5,proxies=self._proxies) - return req - - def getSubscribe(self): - password=''.join(random.sample(string.ascii_letters + string.digits + string.ascii_lowercase, 10)) - email=password+"@gmail.com" - req=self.register(email,password) - token=req.json()["data"]["token"] - subscribe=self._sub.format(token=token) - return subscribe - -@bot.message_handler(commands=['free']) -def get_baipiao(message): - if not message.chat.type == "private" : - if not bot_name in message.text : - if not str(message.from_user.id) in admin_id: - return - if str(message.chat.id) in ban_chat : - if not str(message.from_user.id) in admin_id: - return - if admin_only == 1: - if not str(message.from_user.id) in admin_id : - bot.reply_to(message, "[WRONG][你没有操作权限]") - return - url = remove_convert(message.text.split()[1]) - if not '://' in url : - url = 'https://' + url - sent_message = bot.reply_to(message, '[✅][获取中...]') - logger.debug(f"用户{message.from_user.id}使用了/register功能获取了{url}订阅") - link = "" - try : - v2b = v2board(url) - v2b.set_env() - link = v2b.getSubscribe() - bot.edit_message_text(chat_id=sent_message.chat.id, message_id=sent_message.message_id, text = '`' + link + '`', parse_mode = 'Markdown') - except : - try : - ss = sspanel(url) - ss.set_env() - link = ss.getSubscribe() - bot.edit_message_text(chat_id=sent_message.chat.id, message_id=sent_message.message_id, text = '`' + link + '`', parse_mode = 'Markdown') - except : - bot.edit_message_text(chat_id=sent_message.chat.id, message_id=sent_message.message_id, text = '[WRONG][获取失败]') - -def auto_checksubinfo(url): - headers = {'User-Agent': sub_ua} - try: - message_raw = url - final_output = '' - reply_list = [] - try : - reply_list = re.findall("https?://[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|]", message.reply_to_message.text) - except : - pass - url_list = re.findall("https?://[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|]",message_raw) - try : - url_list.extend(reply_list) - except : - pass - url_list = list(set(url_list)) - for urla in url_list: - url = remove_convert(urla) - try: - res = requests.get(url, headers=headers, timeout=try_time) - except: - final_output = final_output +'订阅链接域名:`' + urllib.parse.urlparse(url).netloc + '`\n连接错误' + '\n\n' - continue - if res.status_code == 200: - try: - comment = "" - name = "" - size = "" - flag = 0 - try : - r = open('airport.list',encoding='utf8') - while True : - line = r.readline() - if not line : - break - a = line.split()[0] - b = line.split()[1] - if a in url : - name = b - flag = 1 - break - except: - pass - if flag == 0 : - if "api/v1/client/subscribe?token" in url: - if "&flag=clash" not in url: - url = url + "&flag=clash" - else: - pass - try: - response = requests.get(url, timeout=try_time) - header = response.headers.get('Content-Disposition') - if header: - pattern = r"filename\*=UTF-8''(.+)" - result = re.search(pattern, header) - if result: - filename = result.group(1) - filename = parse.unquote(filename) - airport_name = filename.replace("%20", " ").replace("%2B", "+") - if not "Access denied" in airport_name: - if not "Blocked" in airport_name: - if not "Cloudflare" in airport_name: - if not "nginx" in airport_name: - name = airport_name - flag = 1 - except: - pass - else: - headers = { - 'User-Agent': link_ua} - try: - pattern = r'(https?://)([^/]+)' - match = re.search(pattern, url) - base_url = None - if match: - base_url = match.group(1) + match.group(2) - response = requests.get(base_url, headers=headers, timeout=try_time) - html = response.content - soup = BeautifulSoup(html, 'html.parser') - title = soup.title.string - if not "Access denied" in title: - if not "Blocked" in title: - if not "Cloudflare" in title: - if not "nginx" in title: - name = title - flag = 1 - except: - pass - info = res.headers['subscription-userinfo'] - info_num = re.findall(r'\d+', info) - time_now = int(time.time()) - if flag == 1: - output_text_head = '订阅链接域名:`' + urllib.parse.urlparse(url).netloc + '`\n机场名称:`' + name + '`\n已用上行:`' + StrOfSize(int(info_num[0])) + '`\n已用下行:`' + StrOfSize(int(info_num[1])) + '`\n剩余:`' + StrOfSize(int(info_num[2]) - int(info_num[1]) - int(info_num[0])) + '`\n总共:`' + StrOfSize(int(info_num[2])) - else: - output_text_head = '订阅链接域名:`' + urllib.parse.urlparse(url).netloc + '`\n已用上行:`' + StrOfSize(int(info_num[0])) + '`\n已用下行:`' + StrOfSize(int(info_num[1])) + '`\n剩余:`' + StrOfSize(int(info_num[2]) - int(info_num[1]) - int(info_num[0])) + '`\n总共:`' + StrOfSize(int(info_num[2])) - if len(info_num) >= 4: - timeArray = time.localtime(int(info_num[3]) + 28800) - dateTime = time.strftime("%Y-%m-%d", timeArray) - if time_now <= int(info_num[3]): - lasttime = int(info_num[3]) - time_now - output_text = output_text_head + '`\n过期时间:`' + dateTime + '`\n剩余时间:`' + sec_to_data(lasttime) + '`' - elif time_now > int(info_num[3]): - output_text = output_text_head + '`\n此订阅已于`' + dateTime + '`过期' - else: - output_text = output_text_head + '`\n到期时间:`没有说明`' - except: - output_text = '订阅链接域名:`' + urllib.parse.urlparse(url).netloc + '`\n无流量信息' - else: - output_text = '订阅链接域名:`' + urllib.parse.urlparse(url).netloc + '`\n无法访问\n' - final_output = final_output + output_text + '\n\n' - return (final_output) - except: - return ('参数错误') - - -# 自走对接 -@bot.message_handler(commands=['connect']) -def page_change(message): - if not message.chat.type == "private" : - if not bot_name in message.text : - if not str(message.from_user.id) in admin_id: - return - if str(message.chat.id) in ban_chat : - if not str(message.from_user.id) in admin_id: - return - if str(message.from_user.id) in admin_id: - command = message.text.split()[1] - if command == "index": - try: - search_str = message.text.split()[2] - c.execute("SELECT rowid,URL,comment FROM My_sub WHERE URL LIKE ? OR comment LIKE ?",('%' + search_str + '%', '%' + search_str + '%')) - result = c.fetchall() - try : - current_page = int(message.text.split()[3]) - except : - current_page = 1 - - pages = [result[i:i + items_per_page] for i in range(0, len(result), items_per_page)] - total = len(pages) - current_items = pages[current_page - 1] - - output_text = str(len(result)) + ' ' + str(current_page) + ' ' + str(total) + ' ' - for item in current_items: - output_text = output_text + str(item[0]) + ' ' + str(item[2]).replace(' ', '') + ' ' - output_text = base64.b64encode(output_text.encode('utf-8')) - bot.reply_to(message, output_text) - except: - output_text = "None" - output_text = base64.b64encode(output_text.encode('utf-8')) - bot.reply_to(message, output_text) - return - elif command == "get": - row_num = int(message.text.split()[2]) - c.execute("SELECT rowid,URL,comment FROM My_sub WHERE rowid=?", (row_num,)) - result = c.fetchone() - if result: - output_text = str(result[0]) + ' ' + str(result[1]).replace(' ', '') + ' ' + str(result[2]).replace(' ', '') - logger.debug(f"用户{message.from_user.id}从BOT获取了{result}") - else: - output_text = "None" - output_text = base64.b64encode(output_text.encode('utf-8')) - bot.reply_to(message, output_text) - elif command == "edit": - resp = base64.b64decode(message.text.split()[2]).decode('utf-8') - - else: - bot.reply_to(message, "[WRONG][你没有操作权限]") - -# 测试延迟 -@bot.message_handler(commands=['ping']) -def get_ping(message): - if not message.chat.type == "private" : - if not bot_name in message.text : - if '@' in message.text : - return - if str(message.chat.id) in ban_chat : - if not str(message.from_user.id) in admin_id : - return - if admin_only == 1: - if not str(message.from_user.id) in admin_id : - bot.reply_to(message, "[WRONG][你没有操作权限]") - return - start = datetime.now() - message = bot.reply_to(message,"Ping : ",disable_notification=True) - end = datetime.now() - msg_delay = (end-start).microseconds/1000 - start = datetime.now() - bot.edit_message_text(f"Ping : `{msg_delay:.2f}ms`",message.chat.id,message.id,parse_mode='Markdown') - end = datetime.now() - msg_delay = (msg_delay + (end-start).microseconds/1000) / 2 - start = datetime.now() - bot.edit_message_text(f"Ping : `{msg_delay:.2f}ms`",message.chat.id,message.id,parse_mode='Markdown') - end = datetime.now() - msg_delay = (msg_delay + (end-start).microseconds/1000) / 2 - bot.edit_message_text(f"Ping : `{msg_delay:.2f}ms`",message.chat.id,message.id,parse_mode='Markdown') - - -# 版本信息 -@bot.message_handler(commands=['version']) -def get_version(message): - if not message.chat.type == "private" : - if not bot_name in message.text : - if '@' in message.text : - return - if str(message.chat.id) in ban_chat : - if not str(message.from_user.id) in admin_id : - return - if admin_only == 1: - if not str(message.from_user.id) in admin_id : - bot.reply_to(message, "[WRONG][你没有操作权限]") - return - bot.reply_to(message, "Version: `" + version_text + "`", parse_mode = 'Markdown') - -# 使用帮助 -@bot.message_handler(commands=['help']) -def help_sub(message): - if not message.chat.type == "private" : - if not bot_name in message.text : - if '@' in message.text : - return - if str(message.chat.id) in ban_chat : - if not str(message.from_user.id) in admin_id : - return - if admin_only == 1: - doc = '''[已开启唯一管理模式] - ''' - else: - doc = '''[游客] -查询订阅 /subinfo -转换订阅 /convert -生成短链 /short -注册试用 /free -订阅监测 /checksub -消息延迟 /ping -版本信息 /version - ''' - if str(message.from_user.id) in admin_id : - doc = doc + ''' -[管理] -''' - if admin_only == 1: - doc = '''[管理] -查询订阅 /subinfo -转换订阅 /convert -注册试用 /free -订阅监测 /checksub -消息延迟 /ping -版本信息 /version -''' - doc = doc + '''重启 /restart -发送消息 /chat 内容 -发送通知 /notice 内容 -随机订阅 /random -添加订阅 /add 订阅链接 备注 -删除订阅 /del 编号 -查找订阅 /search 内容 -更新订阅 /update 编号 订阅链接 备注 -整理订阅 /sort -自动添加 /auto 回复/内容 -获取订阅 /get 编号 -页面跳转 /page 页数 -交换订阅 /swap 编号 编号 -修改备注 /comment 编号 备注 -更新临期 /updatesub -测活订阅 /prune''' - if allow_invite == 1: - doc = doc + ''' -赠与订阅 /invite''' - doc = doc + ''' -注册任务 /register -取消任务 /unregister -离开群聊 /leave - ''' - if str(message.from_user.id) in administrator_id : - doc = doc + ''' -[超管] -给予授权 /grant -取消授权 /ungrant -还原授权 /grantbackup -清除授权 /grantclear -授权列表 /list -信任群组 /trust -取消信任 /distrust''' - if not str(message.from_user.id) in admin_id or allow_invite == 0: - doc = doc + ''' -赠与订阅 /invite''' - doc = doc + ''' -赠送订阅 /gift -添加域名 /addkeyword -删除域名 /delkeyword -获取数据 /database -安装数据 /install -查询日志 /log -重载配置 /reload -保存配置 /save -获取配置 /value -设置配置 /set - ''' - bot.send_message(message.chat.id, doc) - -@bot.message_handler() -def auto_message(message): - try : - if str(message.chat.id) in peep_list : - for send_id in administrator_id : - try : - bot.forward_message(send_id, message.chat.id, message.message_id) - except : - continue - except : - pass - try : - if message.chat.type == "private" : - state = auto_check[message.from_user.id]['state'] - identifier = auto_check[message.from_user.id]['identifier'] - chat_id = auto_check[message.from_user.id]['chat'] - message_id = auto_check[message.from_user.id]['message'] - - if state == 1 : - url_list = re.findall("https?://[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|]", message.text) - if len(url_list) == 0: - del auto_check[message.from_user.id] - bot.send_message(message.chat.id, text='[WRONG][不包含订阅链接 请重新发起查询]') - bot.edit_message_text(chat_id=chat_id, message_id=message_id, text='[WRONG][不包含订阅链接 请重新发起查询]') - return - url_list = list(set(url_list)) - url = url_list[0] - logger.debug(f"用户{message.from_user.id}使用了/checksub功能查询了{url}订阅") - del auto_check[message.from_user.id] - auto_check[message_id] = {'state': 0, 'chat' : chat_id, 'message': message_id, 'identifier': identifier, 'url': url} - bot.send_message(message.chat.id, text='[✅][已收到订阅 请返回群组查看]') - bot.edit_message_text(chat_id=chat_id, message_id=message_id, text='正在获取订阅中...') - keyboard = [] - keyboard.append([telebot.types.InlineKeyboardButton('刷新', callback_data='refresh')]) - reply_markup = telebot.types.InlineKeyboardMarkup(keyboard) - bot.edit_message_text(chat_id=chat_id, message_id=message_id, text=auto_checksubinfo(url), parse_mode = 'Markdown', reply_markup=reply_markup) - return - except : - pass - if record == 1 : - try : - global already - if not message.chat.id in already : - for id in ban_id : - try : - bot.ban_chat_member(message.chat.id, id, 1) - logger.debug(f"在群聊{message.chat.id}中ban了{id}") - except : - pass - already.append(message.chat.id) - except : - pass - try : - if "apply" in message.text : - if not message.from_user.id in admin_id : - now_time = time.strftime("%H:%M:%S", time.localtime()) - with open("./log/log.txt","a") as f: - f.write(f"{now_time}时用户{message.from_user.first_name}{message.from_user.last_name}(@{message.from_user.username})({message.from_user.id})在群聊{message.chat.id}使用了apply\n") - with open("./log/log.ini","a") as f: - f.write(f"{message.from_user.first_name},{message.from_user.last_name},{message.from_user.username},{message.from_user.id},{message.chat.id},{now_time},apply\n") - except : - pass - try : - if "小狗" in message.text : - if not message.from_user.id in admin_id : - now_time = time.strftime("%H:%M:%S", time.localtime()) - with open("./log/log.txt","a") as f: - f.write(f"{now_time}时用户{message.from_user.first_name}{message.from_user.last_name}(@{message.from_user.username})({message.from_user.id})在群聊{message.chat.id}使用了Dog\n") - with open("./log/log.ini","a") as f: - f.write(f"{message.from_user.first_name},{message.from_user.last_name},{message.from_user.username},{message.from_user.id},{message.chat.id},{now_time},dog\n") - except : - pass - try : - if "/invite" in message.text : - if not message.from_user.id in admin_id : - now_time = time.strftime("%H:%M:%S", time.localtime()) - with open("./log/log.txt","a") as f: - f.write(f"{now_time}时用户{message.reply_to_message.from_user.first_name}{message.reply_to_message.from_user.last_name}(@{message.reply_to_message.from_user.username})({message.reply_to_message.from_user.id})在群聊{message.reply_to_message.chat.id}接受了测速邀请\n") - with open("./log/log.ini","a") as f: - f.write(f"{message.reply_to_message.from_user.first_name},{message.reply_to_message.from_user.last_name},{message.reply_to_message.from_user.username},{message.reply_to_message.from_user.id},{message.reply_to_message.chat.id},{now_time},invite\n") - - except : - pass - - try: - - try: - if not callback_url == "": - headers = {'User-Agent': link_ua} - data = json.dumps(str(message)) - res = requests.post(callback_url, headers=headers, data=data, timeout=try_time) - if str(message.chat.id) in ban_chat : - return - if res.status_code == 403: - pass - bot.reply_to(message, res.text.encode().decode("unicode_escape"), parse_mode = 'Markdown') - except: - pass - - - if "/info" in message.text : - return - if "/i" in message.text : - return - if "/subinfo" in message.text : - return - if "github" in message.text : - return - - url_list = re.findall("https?://[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|]", message.text) - url_list = list(set(url_list)) - headers = {'User-Agent': sub_ua} - final_output = '' - for url in url_list: - url_temp = remove_convert(url) - logger.debug(f"用户{message.from_user.id}发送了链接{url_temp}") - try: - res = requests.get(remove_convert(url), headers=headers, timeout=try_time) - except: - continue - if res.status_code == 200: - try: - comment = "" - name = "" - size = "" - flag = 0 - try: - r = open('airport.list',encoding='utf8') - while True : - line = r.readline() - if not line : - break - a = line.split()[0] - b = line.split()[1] - if a in remove_convert(url) : - name = b - flag = 1 - break - except: - pass - if flag == 0 : - if "api/v1/client/subscribe?token" in url: - if "&flag=clash" not in remove_convert(url): - url = remove_convert(url) + "&flag=clash" - else: - pass - try: - response = requests.get(remove_convert(url), timeout=try_time) - header = response.headers.get('Content-Disposition') - if header: - pattern = r"filename\*=UTF-8''(.+)" - result = re.search(pattern, header) - if result: - filename = result.group(1) - filename = parse.unquote(filename) - airport_name = filename.replace("%20", " ").replace("%2B", "+") - if not "Access denied" in airport_name: - if not "Blocked" in airport_name: - if not "Cloudflare" in airport_name: - if not "nginx" in airport_name: - name = airport_name - flag = 1 - except: - pass - else: - headers = { - 'User-Agent': link_ua} - try: - pattern = r'(https?://)([^/]+)' - match = re.search(pattern, remove_convert(url)) - base_url = None - if match: - base_url = match.group(1) + match.group(2) - response = requests.get(base_url, headers=headers, timeout=try_time) - html = response.content - soup = BeautifulSoup(html, 'html.parser') - title = soup.title.string - if not "Access denied" in title: - if not "Blocked" in title: - if not "Cloudflare" in title: - if not "nginx" in title: - name = title - flag = 1 - except: - pass - info = res.headers['subscription-userinfo'] - info_num = re.findall(r'\d+', info) - time_now = int(time.time()) - if flag == 1: - output_text_head = '机场名称:`' + name + '`\n已用上行:`' + StrOfSize(int(info_num[0])) + '`\n已用下行:`' + StrOfSize(int(info_num[1])) + '`\n剩余:`' + StrOfSize(int(info_num[2]) - int(info_num[1]) - int(info_num[0])) + '`\n总共:`' + StrOfSize(int(info_num[2])) - else: - output_text_head = '已用上行:`' + StrOfSize(int(info_num[0])) + '`\n已用下行:`' + StrOfSize(int(info_num[1])) + '`\n剩余:`' + StrOfSize(int(info_num[2]) - int(info_num[1]) - int(info_num[0])) + '`\n总共:`' + StrOfSize(int(info_num[2])) - if len(info_num) >= 4: - timeArray = time.localtime(int(info_num[3]) + 28800) - dateTime = time.strftime("%Y-%m-%d", timeArray) - if time_now <= int(info_num[3]): - lasttime = int(info_num[3]) - time_now - output_text = output_text_head + '`\n过期时间:`' + dateTime + '`\n剩余时间:`' + sec_to_data(lasttime) + '`' - elif time_now > int(info_num[3]): - output_text = output_text_head + '`\n此订阅已于`' + dateTime + '`过期' - else: - output_text = output_text_head + '`\n到期时间:`没有说明`' - except: - return - else: - return - final_output = final_output + output_text + '\n\n' - if not message.chat.type == "private" : - c.execute("SELECT * FROM My_sub WHERE URL=?", (url_temp,)) - if not c.fetchone(): - for send_id in administrator_id : - try : - bot.send_message(send_id, '订阅链接:`' + url_temp + '`\n' + output_text, parse_mode = 'Markdown') - except : - continue - - if str(message.chat.id) in ban_chat : - return - bot.reply_to(message, final_output, parse_mode = 'Markdown') - except: - pass - -# 按钮点击事件 -@bot.callback_query_handler(func=lambda call: True) -def callback_inline(call): - global sent_message_id, current_page, callbacks - user_id = call.from_user.id - if call.data == 'refresh': - url = auto_check[call.message.message_id]['url'] - keyboard = [] - keyboard.append([telebot.types.InlineKeyboardButton('刷新', callback_data='refresh')]) - reply_markup = telebot.types.InlineKeyboardMarkup(keyboard) - info_text = auto_checksubinfo(url) - if not call.message.text == info_text: - bot.edit_message_text(chat_id=call.message.chat.id, message_id=call.message.message_id, text=info_text, parse_mode = 'Markdown', reply_markup=reply_markup) - if str(call.from_user.id) in admin_id: - if call.data == 'close': - reply_markup = [] - bot.edit_message_text(chat_id=call.message.chat.id, message_id=call.message.message_id, text="防删除哒咩", reply_markup=reply_markup) - delete_result = bot.delete_message(call.message.chat.id, call.message.message_id) - if delete_result is None: - sent_message_id = None - elif call.data == 'prev' or call.data == 'next': - update_buttons(call, user_id) - elif call.data.startswith('page_info'): - result = callbacks[call.message.message_id]['result'] - v2b = ssp = imp = emp = old = fai = 0 - for sub in result: - if "/api/v1/" in sub[1] : - v2b = v2b + 1 - if "/link/" in sub[1] : - ssp = ssp + 1 - if "临期" in sub[2] : - imp = imp + 1 - if "临期" in sub[2] : - emp = emp + 1 - if "过期" in sub[2] : - old = old + 1 - if "失效" in sub[2] : - fai = fai + 1 - bot.answer_callback_query(call.id, f"第 {call.data.split()[1]} 页 共 {call.data.split()[2]} 页\n\nV2Board 订阅 共 {v2b} 个\nSSPanel 订阅 共 {ssp} 个\n\n临期订阅 共 {imp} 个\n耗尽订阅 共 {emp} 个\n过期订阅 共 {old} 个\n失效订阅 共 {fai} 个", show_alert=True) - elif call.data == 'blank': - pass - elif call.data == 'stop_prune': - global stop_prune - stop_prune = 1 - elif call.data == 'stop_updatesub': - global stop_updatesub - stop_updatesub = 1 - elif call.data == 'refresh': - pass - else: - try: - row_num = call.data - c.execute("SELECT rowid,URL,comment FROM My_sub WHERE rowid=?", (row_num,)) - result = c.fetchone() - - headers = {'User-Agent': sub_ua} - output_test = '' - try : - try: - res = requests.get(result[1], headers=headers, timeout=try_time) - except: - output_text = '连接错误' - if res.status_code == 200: - try: - info = res.headers['subscription-userinfo'] - info_num = re.findall(r'\d+', info) - time_now = int(time.time()) - output_text_head = '上行:`' + StrOfSize(int(info_num[0])) + '`\n下行:`' + StrOfSize(int(info_num[1])) + '`\n剩余:`' + StrOfSize(int(info_num[2]) - int(info_num[1]) - int(info_num[0])) + '`\n总共:`' + StrOfSize(int(info_num[2])) + '`' - if len(info_num) >= 4: - timeArray = time.localtime(int(info_num[3]) + 28800) - dateTime = time.strftime("%Y-%m-%d", timeArray) - if time_now <= int(info_num[3]): - lasttime = int(info_num[3]) - time_now - output_text = output_text_head + '\n过期时间:`' + dateTime + '`\n剩余时间:`' + sec_to_data(lasttime) + '`' - elif time_now > int(info_num[3]): - output_text = output_text_head + '\n此订阅已于 `' + dateTime + '`过期' - else: - output_text = output_text_head + '\n过期时间:`没有说明`' - except: - output_text = '`无流量信息`' - else: - output_text = '`无法访问`' - - try : - d = int(lasttime // 86400) - if d < impend : - if not '临期' in result[2] : - c.execute("UPDATE My_sub SET URL=?, comment=? WHERE rowid=?", (result[1], result[2] + '-临期', result[0])) - conn.commit() - except : - pass - except: - output_text = '`无流量信息`' - keyboard = [] - keyboard.append([telebot.types.InlineKeyboardButton('❎ 关闭', callback_data='close')]) - reply_markup = telebot.types.InlineKeyboardMarkup(keyboard) - if call.message.chat.id in trust_list : - bot.send_message(call.message.chat.id, '编号 `{}`\n订阅 `{}`\n说明 `{}`\n\n{}'.format(result[0], result[1], result[2], output_text),parse_mode='Markdown', reply_markup = reply_markup) - else : - bot.send_message(call.from_user.id, '编号 `{}`\n订阅 `{}`\n说明 `{}`\n\n{}'.format(result[0], result[1], result[2], output_text),parse_mode='Markdown', reply_markup = reply_markup) - logger.debug(f"用户{call.from_user.id}从BOT获取了{result}") - except: - bot.send_message(call.message.chat.id, "[WARNING][该订阅已被管理员删除]") - else: - if call.data == 'refresh': - return - try : - logger.debug(f"用户{call.from_user.id}尝试使用按钮") - bot.answer_callback_query(call.id, f"❌ 你没有权限 请不要点按钮呢", show_alert=True) - except : - pass - - - -def cron_sub(): - while True: - try: - try: - with open('./config.yaml', 'r', encoding='utf-8') as f: - data = yaml.load(stream=f, Loader=yaml.FullLoader) - global cron_enable, cron_delay - cron_enable = int(data['cron']['enable']) - cron_delay = int(data['cron']['interval']) - except: - pass - if not cron_enable == 0: - c.execute("SELECT rowid,URL,comment FROM My_sub") - result = c.fetchall() - random.shuffle(result) - for item in result: - headers = {'User-Agent': sub_ua} - url = item[1] - try: - res = requests.get(url, headers=headers, timeout=try_time) - except: - c.execute("UPDATE My_sub SET URL=?, comment=? WHERE rowid=?", (item[1], item[2].replace('-过期', '').replace('-临期', '').replace('-失效', '').replace('-耗尽', '') + '-失效', item[0])) - conn.commit() - continue - c.execute("UPDATE My_sub SET URL=?, comment=? WHERE rowid=?", (item[1], item[2].replace('-过期', '').replace('-临期', '').replace('-失效', '').replace('-耗尽', ''), item[0])) - conn.commit() - try: - info = res.headers['subscription-userinfo'] - info_num = re.findall(r'\d+', info) - time_now = int(time.time()) - if int(info_num[2])-int(info_num[1])-int(info_num[0])<=1: - c.execute("UPDATE My_sub SET URL=?, comment=? WHERE rowid=?", (item[1], item[2].replace('-过期', '').replace('-临期', '').replace('-失效', '').replace('-耗尽', '') + '-耗尽', item[0])) - conn.commit() - except: - pass - try: - if res.status_code == 200: - info = res.headers['subscription-userinfo'] - info_num = re.findall(r'\d+', info) - time_now = int(time.time()) - if len(info_num) >= 4: - lasttime = int(info_num[3]) - time_now - d = int(lasttime // 86400) - if time_now > int(info_num[3]): - c.execute("UPDATE My_sub SET URL=?, comment=? WHERE rowid=?", (item[1], item[2].replace('-过期', '').replace('-临期', '').replace('-失效', '').replace('-耗尽', '') + '-过期', item[0])) - conn.commit() - elif d < impend : - c.execute("UPDATE My_sub SET URL=?, comment=? WHERE rowid=?", (item[1], item[2].replace('-过期', '').replace('-临期', '').replace('-失效', '').replace('-耗尽', '') + '-临期', item[0])) - conn.commit() - except: - pass - try: - u = re.findall('proxies:', res.text)[0] - if u == "proxies:": - pass - except: - try: - text = res.text[:64] - text = base64.b64decode(text) - text = str(text) - if filter_base64(text): - pass - else: - c.execute("UPDATE My_sub SET URL=?, comment=? WHERE rowid=?", (item[1], item[2].replace('-过期', '').replace('-临期', '').replace('-失效', '').replace('-耗尽', '') + '-失效', item[0])) - conn.commit() - except: - c.execute("UPDATE My_sub SET URL=?, comment=? WHERE rowid=?", (item[1], item[2].replace('-过期', '').replace('-临期', '').replace('-失效', '').replace('-耗尽', '') + '-失效', item[0])) - conn.commit() - - for cron in cron_list: - flag = False - try : - for i in cron: - send_id = i - search_str = cron.get(i) - flag = True - except : - send_id = cron - search_str = 'h' - c.execute("SELECT rowid,URL,comment FROM My_sub WHERE URL LIKE ? OR comment LIKE ?",('%' + search_str + '%', '%' + search_str + '%')) - result = c.fetchall() - al = [] - imp = [] - old = [] - fai = [] - emp = [] - for sub in result: - if "-临期" in sub[2]: - imp.append(sub) - if "-过期" in sub[2]: - old.append(sub) - if "-失效" in sub[2]: - fai.append(sub) - if "-耗尽" in sub[2]: - emp.append(sub) - if "临期" in sub[2] or "-耗尽" in sub[2] or "-过期" in sub[2] or "-失效" in sub[2]: - al.append(sub) - text = f'订阅监测报告\n\n计划: `every {cron_delay}s`\n任务: `{send_id}`' - if flag: - text = text + f' : `{search_str}`' - text = text + f'\n概要: `{len(result) - len(al)}/{len(result)}`\n' - if not len(al) == 0: - text = text + '详情:\n' - if len(imp) == 0: - pass - elif len(imp) > 10: - text = text + '> 临期订阅\n - `' - for sub in imp: - text = text + str(sub[0]) + ' ' - text = text + '`\n' - else: - text = text + '> 临期订阅\n' - for sub in imp: - sn = sub[2].replace('-过期', '').replace('-临期', '').replace('-失效', '').replace('-耗尽', '')[0:10] - text = text + f' - `{sub[0]} {sn}`\n' - if len(emp) == 0: - pass - elif len(emp) > 10: - text = text + '> 耗尽订阅\n - `' - for sub in emp: - text = text + str(sub[0]) + ' ' - text = text + '`\n' - else: - text = text + '> 耗尽订阅\n' - for sub in emp: - sn = sub[2].replace('-过期', '').replace('-临期', '').replace('-失效', '').replace('-耗尽', '')[0:10] - text = text + f' - `{sub[0]} {sn}`\n' - if len(old) == 0: - pass - elif len(old) > 10: - text = text + '> 过期订阅\n - `' - for sub in old: - text = text + str(sub[0]) + ' ' - text = text + '`\n' - else: - text = text + '> 过期订阅\n' - for sub in old: - sn = sub[2].replace('-过期', '').replace('-临期', '').replace('-失效', '').replace('-耗尽', '')[0:10] - text = text + f' - `{sub[0]} {sn}`\n' - if len(fai) == 0: - pass - elif len(fai) > 10: - text = text + '> 失效订阅\n - `' - for sub in fai: - text = text + str(sub[0]) + ' ' - text = text + '`\n' - else: - text = text + '> 失效订阅\n' - for sub in fai: - sn = sub[2].replace('-过期', '').replace('-临期', '').replace('-失效', '').replace('-耗尽', '')[0:10] - text = text + f' - `{sub[0]} {sn}`\n' - try: - bot.send_message(send_id, text, parse_mode = 'Markdown') - except: - pass - sleep(cron_delay) - else: - sleep(10) - except: - sleep(10) - -def pollbot(): - logger.debug(f"[程序已启动]") - for send_id in administrator_id : - try : - bot.send_message(send_id, '[程序已启动]') - except : - continue - print('') - botinit() - while True: - try: - bot.polling(none_stop=True) - except: - pass - -if __name__ == '__main__': - t1 = threading.Thread(target = pollbot) - t2 = threading.Thread(target = cron_sub) - - t1.start() - t2.start() - - t1.join() - t2.join()