diff --git a/telegram/bot-v3.0.py b/telegram/bot-v3.0.py index 6c21511..76751ab 100644 --- a/telegram/bot-v3.0.py +++ b/telegram/bot-v3.0.py @@ -1,4 +1,5 @@ -from nbformat.v4 import new_raw_cell +import datetime +import requests from telethon import TelegramClient, events, Button import sqlite3 from datetime import date @@ -33,7 +34,6 @@ COMMANDS = { } # ------------命令列表------------------- - data = { "签到": ['/sign', '签到', "haha"], "发言": ["/daily_rank"], @@ -53,52 +53,31 @@ def init_db(): conn = sqlite3.connect(DB_PATH) cursor = conn.cursor() cursor.execute(''' - CREATE TABLE IF NOT EXISTS users - ( - user_id - INTEGER - PRIMARY - KEY, - username - TEXT, - points - INTEGER - DEFAULT - 0, - last_sign_date - TEXT - ) - ''') + CREATE TABLE IF NOT EXISTS users + ( + user_id INTEGER PRIMARY KEY, + username TEXT, + points INTEGER DEFAULT 0, + last_sign_date TEXT + ) + ''') cursor.execute(''' - CREATE TABLE IF NOT EXISTS daily_messages - ( - user_id - INTEGER, - date - TEXT, - count - INTEGER - DEFAULT - 0, - PRIMARY - KEY - ( - user_id, - date - ) - ) - ''') + CREATE TABLE IF NOT EXISTS daily_messages + ( + user_id INTEGER, + date TEXT, + count INTEGER DEFAULT 0, + PRIMARY KEY(user_id, date) + ) + ''') cursor.execute(''' - CREATE TABLE IF NOT EXISTS invites - ( - inviter_id - INTEGER, - invitee_id - INTEGER - PRIMARY - KEY - ) - ''') + CREATE TABLE IF NOT EXISTS invites + ( + inviter_id INTEGER, + invitee_id INTEGER, + PRIMARY KEY(inviter_id, invitee_id) + ) + ''') conn.commit() conn.close() @@ -127,11 +106,11 @@ def add_points(user_id, points): conn = sqlite3.connect(DB_PATH) cursor = conn.cursor() cursor.execute(""" - UPDATE users - SET points = points + ?, - last_sign_date = ? - WHERE user_id = ? - """, (points, today, user_id)) + UPDATE users + SET points = points + ?, + last_sign_date = ? + WHERE user_id = ? + """, (points, today, user_id)) conn.commit() conn.close() @@ -151,11 +130,10 @@ def add_message(user_id): conn = sqlite3.connect(DB_PATH) cursor = conn.cursor() cursor.execute(""" - INSERT INTO daily_messages (user_id, date, count) - VALUES (?, ?, 1) ON CONFLICT(user_id, date) - DO - UPDATE SET count = count + 1 - """, (user_id, today)) + INSERT INTO daily_messages (user_id, date, count) + VALUES (?, ?, 1) ON CONFLICT(user_id, date) + DO UPDATE SET count = count + 1 + """, (user_id, today)) conn.commit() conn.close() @@ -165,12 +143,12 @@ def get_daily_message_ranking(): conn = sqlite3.connect(DB_PATH) cursor = conn.cursor() cursor.execute(""" - SELECT u.username, d.count - FROM daily_messages d - JOIN users u ON d.user_id = u.user_id - WHERE d.date = ? - ORDER BY d.count DESC - """, (today,)) + SELECT u.username, d.count + FROM daily_messages d + JOIN users u ON d.user_id = u.user_id + WHERE d.date = ? + ORDER BY d.count DESC + """, (today,)) results = cursor.fetchall() conn.close() return results @@ -194,6 +172,71 @@ def get_invite_count(inviter_id): return count +# ---------- 获取币价 ---------- +def get_price(): + headers = { + 'accept': 'application/json, text/plain, */*', + 'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6', + 'cache-control': 'no-cache', + 'dnt': '1', + 'origin': 'https://www.websea.com', + 'pragma': 'no-cache', + 'priority': 'u=1, i', + 'referer': 'https://www.websea.com/', + 'sec-ch-ua': '"Chromium";v="142", "Microsoft Edge";v="142", "Not_A Brand";v="99"', + 'sec-ch-ua-mobile': '?0', + 'sec-ch-ua-platform': '"Windows"', + 'sec-fetch-dest': 'empty', + 'sec-fetch-mode': 'cors', + 'sec-fetch-site': 'same-site', + 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36 Edg/142.0.0.0', + } + + tz = datetime.timezone(datetime.timedelta(hours=8)) + today = datetime.datetime.now(tz).date() + start_of_day = datetime.datetime.combine(today, datetime.time.min, tzinfo=tz) + end_of_day = datetime.datetime.combine(today, datetime.time.max, tzinfo=tz) + + params = { + 'symbol': 'SOL-USDT', + 'period': '30min', + 'start': int(start_of_day.timestamp()), + 'end': int(end_of_day.timestamp()), + } + + response = requests.get('https://eapi.websea.com/webApi/market/getKline', params=params, headers=headers) + data = response.json()["result"]["data"] + + if not data: + return 0, 0, 0, 0 + + current_price = float(data[0]['close']) + today_high = max(float(item['high']) for item in data) + today_low = min(float(item['low']) for item in data) + price_24h_ago = float(data[-1]['open']) + change_24h = (current_price - price_24h_ago) / price_24h_ago * 100 + + return current_price, change_24h, today_high, today_low + + +# ---------- 发送币价消息 ---------- +async def send_price_periodically(bot, chat_id): + while True: + try: + current_price, change_24h, today_high, today_low = get_price() + msg = ( + "SOL/USDT 现货数据\n\n" + f"💰价格:{current_price:.2f} USDT\n" + f"📈24小时涨跌幅:{change_24h:.2f}%\n" + f"⬆️最高价:{today_high:.2f} USDT\n" + f"⬇️最低价:{today_low:.2f} USDT" + ) + await bot.send_message(chat_id, msg) + except Exception as e: + print(f"发送价格失败: {e}") + await asyncio.sleep(3600) # 每小时发送一次 + + # ---------- 统一命令处理 ---------- async def handle_command(event, cmd): user = await event.get_sender() @@ -227,7 +270,6 @@ async def handle_command(event, cmd): else: reply_text = f"⚠️ 未知命令:{cmd}" - # 每次命令回复附带命令列表 reply_text += "\n\n" + get_command_list_text() await event.reply(reply_text) @@ -238,6 +280,10 @@ async def main(): bot = TelegramClient('bot_session', API_ID, API_HASH, proxy=PROXY) await bot.start(bot_token=BOT_TOKEN) + # 启动定时任务,每小时发送币价 + for group_id in ALLOWED_GROUPS: + asyncio.create_task(send_price_periodically(bot, group_id)) + # 新用户加入欢迎 @bot.on(events.ChatAction) async def welcome_new_user(event): @@ -256,25 +302,14 @@ async def main(): user = await event.get_sender() user_id = user.id - # 普通消息计入发言 - for i in data: if text in data[i]: - # 去掉 @botusername 后缀 cmd = text.split('@')[0] await handle_command(event, cmd) break - else: add_message(user_id) - # if not text.startswith('/'): - # add_message(user_id) - # else: - # # 去掉 @botusername 后缀 - # cmd = text.split('@')[0] - # await handle_command(event, cmd) - # 按钮命令发送 @bot.on(events.NewMessage(pattern='/commands')) async def send_buttons(event): @@ -287,10 +322,9 @@ async def main(): # 按钮点击处理 @bot.on(events.CallbackQuery) async def callback_handler(event): - cmd = event.data.decode() # 获取按钮绑定的命令 - print(cmd) + cmd = event.data.decode() await handle_command(event, cmd) - await event.answer() # 防止按钮 loading 一直转 + await event.answer() print("🤖 机器人已启动,等待群聊消息...") await bot.run_until_disconnected() diff --git a/telegram/bot_session.session b/telegram/bot_session.session index 363caa4..bd3b396 100644 Binary files a/telegram/bot_session.session and b/telegram/bot_session.session differ diff --git a/telegram/sign.db b/telegram/sign.db index 220ea4f..a59ef84 100644 Binary files a/telegram/sign.db and b/telegram/sign.db differ diff --git a/test.py b/test.py index 46f3ee7..ba7bee2 100644 --- a/test.py +++ b/test.py @@ -1,49 +1,16 @@ -import requests +import datetime -headers = {'vs': '05g7pXj83SRrFp94citJ7BkbjNqFc6kQ', 'language': 'zh_CN', 'sec-ch-ua-platform': '"Windows"', - 'sec-ch-ua': '"Not;A=Brand";v="99", "Google Chrome";v="139", "Chromium";v="139"', 'sec-ch-ua-mobile': '?0', - 'appVersion': '2.0.1', 'Accept': 'application/json, text/plain, */*', 'Content-Type': 'application/json', - 'locale': 'zh_CN', 'terminalCode': 'ea778f2af8f3a418595f4993fe0ed949', 'Referer': 'https://www.weeaxs.site/', - 'X-SIG': '64fbc4638b9132d0639c0864ad7b2631', - 'sidecar': '01752def6506a5c558793e0c6ea8793a0e6defd487fbe009718c20e36c7b5e16fc', - 'X-TIMESTAMP': '1762425944928', 'bundleid': '', - 'U-TOKEN': 'eyJhbGciOiJSUzI1NiJ9.eyJqdGkiOiI4MjE2MDlhOS1kMDI3LTRiOTAtOTU0OC1iZGU3YTlmNmRiOWMxMzczNjgzNjU1IiwidWlkIjoidEQzQ1FIaFJUblVYcm5MNFNwckw3UT09Iiwic3ViIjoieXgyMDI1KioqKkBnbWFpbC5jb20iLCJpcCI6IllXb3dNNkVVWnYzamdjOTkwUHVHUFE9PSIsImRpZCI6InVxSnQ1N1N2SVBZcE5oM1MzU3VxcktCVERiaHBoeTN6S2VyMmZVNnF3MktnMk12cVptaUhFNmJ0YSt0OUgrcUEiLCJzdHMiOjAsImlhdCI6MTc2MjQwOTc3NywiZXhwIjoxNzcwMTg1Nzc3LCJwdXNoaWQiOiJvTmpMNm1ab2h4T203V3ZyZlIvcWdBPT0iLCJhdGwiOiIwIiwiaXNzIjoidXBleCJ9.idUb4bjGwoDy2MRZWmaIuNZAwCRAos6t6nt4sAZBw_Urg2Jtuz5sEZQYnZxx0fczg7RG8zm0bzeAqoIRHXWLSEQs366HA55bAIcz_GM12Wik7-zWZ_CVz5VqTVCO1xUUfRX7a-qRB6HfgdUu_f-rlqG8U8l__65sWhEtDZ2mJNk', - 'terminaltype': '1', - 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36', - 'traceId': '378eb6c9-eb23-4925-a306-d437c3865a87', 'accept-encoding': 'gzip, deflate, br, zstd', - 'accept-language': 'fi', 'content-length': '68', 'origin': 'https://www.weeaxs.site', 'priority': 'u=1, i', - 'sec-fetch-dest': 'empty', 'sec-fetch-mode': 'cors', 'sec-fetch-site': 'cross-site'} +# 获取当前日期(UTC) +today = datetime.datetime.now(datetime.UTC).date() -json_data = { - 'filterCoinIdList': [ - 2, - ], - 'filterContractIdList': [], - 'filterOrderStatusList': [ - 'CANCELED', - 'FILLED', - ], - 'filterOrderTypeList': [], - 'languageType': 1, - 'limit': 20, - 'sign': 'SIGN', - 'timeZone': 'string', -} +# 获取当天开始时间(00:00:00 UTC) +start_of_day = datetime.datetime.combine(today, datetime.time.min, tzinfo=datetime.timezone.utc) +# 获取当天结束时间(23:59:59.999999 UTC) +end_of_day = datetime.datetime.combine(today, datetime.time.max, tzinfo=datetime.timezone.utc) -response = requests.post( - 'https://http-gateway2.ngsvsfx.cn/api/v1/private/order/v2/getHistoryOrderPage', - headers=headers, - json=json_data, -) +# 将时间转换为时间戳 +start_timestamp = start_of_day.timestamp() +end_timestamp = end_of_day.timestamp() -for i in response.json()["data"]["dataList"]: - print(i) - -# Note: json_data will not be serialized by requests -# exactly as it was in the original request. -# data = '{"filterCoinIdList":[2],"filterContractIdList":[],"filterOrderStatusList":["CANCELED","FILLED"],"filterOrderTypeList":[],"languageType":1,"limit":20,"sign":"SIGN","timeZone":"string"}' -# response = requests.post( -# 'https://http-gateway2.ngsvsfx.cn/api/v1/private/order/v2/getHistoryOrderPage', -# headers=headers, -# data=data, -# ) +print(f"当天开始的 UTC 时间戳: {start_timestamp}") +print(f"当天结束的 UTC 时间戳: {end_timestamp}") \ No newline at end of file diff --git a/test1.py b/test1.py index dda4746..e184e15 100644 --- a/test1.py +++ b/test1.py @@ -1,27 +1,68 @@ -import time import datetime +import requests -# 获取当前时间戳 -current_timestamp = time.time() -# 将当前时间戳转换为 datetime 对象 -current_datetime = datetime.datetime.fromtimestamp(current_timestamp) +headers = { + 'accept': 'application/json, text/plain, */*', + 'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6', + 'cache-control': 'no-cache', + 'dnt': '1', + 'origin': 'https://www.websea.com', + 'pragma': 'no-cache', + 'priority': 'u=1, i', + 'referer': 'https://www.websea.com/', + 'sec-ch-ua': '"Chromium";v="142", "Microsoft Edge";v="142", "Not_A Brand";v="99"', + 'sec-ch-ua-mobile': '?0', + 'sec-ch-ua-platform': '"Windows"', + 'sec-fetch-dest': 'empty', + 'sec-fetch-mode': 'cors', + 'sec-fetch-site': 'same-site', + 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36 Edg/142.0.0.0', +} -# 计算距离当前时间最近的整点或 30 分时刻 -if current_datetime.minute < 30: - target_datetime = current_datetime.replace(minute=0, second=0, microsecond=0) +# # 获取当前日期(UTC) +# today = datetime.datetime.now(datetime.timezone.utc).date() +# +# # 当天开始和结束时间 +# start_of_day = datetime.datetime.combine(today, datetime.time.min, tzinfo=datetime.timezone.utc) +# end_of_day = datetime.datetime.combine(today, datetime.time.max, tzinfo=datetime.timezone.utc) + +# 获取今天日期(本地时间,中国时区 UTC+8) +tz = datetime.timezone(datetime.timedelta(hours=8)) +today = datetime.datetime.now(tz).date() + +# 当天开始时间(北京时间 00:00) +start_of_day = datetime.datetime.combine(today, datetime.time.min, tzinfo=tz) +# 当天结束时间(北京时间 23:59:59.999999) +end_of_day = datetime.datetime.combine(today, datetime.time.max, tzinfo=tz) + +params = { + 'symbol': 'BTC-USDT', + 'period': '30min', + 'start': int(start_of_day.timestamp()), + 'end': int(end_of_day.timestamp()), +} + +response = requests.get('https://eapi.websea.com/webApi/market/getKline', params=params, headers=headers) +data = response.json()["result"]["data"] + +if not data: + print("没有获取到数据") else: - target_datetime = current_datetime.replace(minute=30, second=0, microsecond=0) + # 当前价格 = 最新一条 K 线的 close + current_price = float(data[0]['close']) -# 将目标 datetime 对象转换为时间戳 -target_timestamp = target_datetime.timestamp() + # 当天最高价 = 当天所有 K 线的 high + today_high = max(float(item['high']) for item in data) + # 当天最低价 = 当天所有 K 线的 low + today_low = min(float(item['low']) for item in data) -print(f"当前时间戳: {current_timestamp}") -print(f"目标时间戳: {target_timestamp}") + # 24 小时涨幅计算(用最新一条 close 与 24 小时前的价格对比) + # 如果接口只能获取当天数据,可能不足 24 小时,可根据需求扩展 + # 假设获取过去 24 小时数据,使用第一条 K 线的 open 作为 24 小时前价格 + price_24h_ago = float(data[-1]['open']) + change_24h = (current_price - price_24h_ago) / price_24h_ago * 100 -# 进行时间戳比对 -if current_timestamp == target_timestamp: - print("当前时间就是目标时间。") -elif current_timestamp < target_timestamp: - print(f"当前时间早于目标时间,还需等待 {target_timestamp - current_timestamp} 秒。") -else: - print(f"当前时间晚于目标时间,已经过去了 {current_timestamp - target_timestamp} 秒。") + print(f"当前价格: {current_price}") + print(f"24小时涨幅: {change_24h:.2f}%") + print(f"当天最高价: {today_high}") + print(f"当天最低价: {today_low}")