From 0e50249ab24292caff3cc72c63b3421662d68f18 Mon Sep 17 00:00:00 2001 From: 27942 Date: Thu, 20 Nov 2025 18:12:52 +0800 Subject: [PATCH] rgfewfger --- telegram/bot-n2.0.py | 233 ------------ telegram/bot_session.session | Bin 28672 -> 28672 bytes telegram/bot_session.session-journal | Bin 4616 -> 0 bytes telegram/bot_session_23612.session | Bin 0 -> 28672 bytes telegram/bot_session_35072.session | Bin 0 -> 28672 bytes telegram/bot_test.py | 135 ------- telegram/bot已实现签到.py | 161 -------- telegram/gpt.py | 538 +++++++++++++++++++++++++++ telegram/sign.db | Bin 20480 -> 28672 bytes test.py | 80 ++-- 10 files changed, 560 insertions(+), 587 deletions(-) delete mode 100644 telegram/bot-n2.0.py delete mode 100644 telegram/bot_session.session-journal create mode 100644 telegram/bot_session_23612.session create mode 100644 telegram/bot_session_35072.session delete mode 100644 telegram/bot_test.py delete mode 100644 telegram/bot已实现签到.py create mode 100644 telegram/gpt.py diff --git a/telegram/bot-n2.0.py b/telegram/bot-n2.0.py deleted file mode 100644 index 210dbf3..0000000 --- a/telegram/bot-n2.0.py +++ /dev/null @@ -1,233 +0,0 @@ -from telethon import TelegramClient, events -import sqlite3 -from datetime import date -import os -import asyncio - -# ========== 配置区 ========== -API_ID = 2040 -API_HASH = "b18441a1ff607e10a989891a5462e627" -BOT_TOKEN = "8451724418:AAGTGqCmc1JiUr88IABhMiQTHeVLcAcnT5Y" -DB_PATH = "sign.db" -SIGN_POINTS = 10 - -ALLOWED_GROUPS = [-1003238845008] # 只允许的群聊 - -PROXY = { - 'proxy_type': "socks5", - 'addr': "202.155.144.102", - 'port': 31102, - 'username': "SyNuejCtrQ", - 'password': "MH8ioL7EXf" -} - - -# ============================ - -# ---------- 数据库操作 ---------- -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 - ) - ''') - # 发言统计 - cursor.execute(''' - 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 - ) - ''') - conn.commit() - conn.close() - - -def add_or_update_user(user_id, username): - conn = sqlite3.connect(DB_PATH) - cursor = conn.cursor() - cursor.execute("INSERT OR IGNORE INTO users (user_id, username) VALUES (?, ?)", (user_id, username)) - cursor.execute("UPDATE users SET username=? WHERE user_id=?", (username, user_id)) - conn.commit() - conn.close() - - -def can_sign(user_id): - conn = sqlite3.connect(DB_PATH) - cursor = conn.cursor() - cursor.execute("SELECT last_sign_date FROM users WHERE user_id=?", (user_id,)) - row = cursor.fetchone() - today = date.today().isoformat() - conn.close() - return False if row and row[0] == today else True - - -def add_points(user_id, points): - today = date.today().isoformat() - 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)) - conn.commit() - conn.close() - - -def get_points(user_id): - conn = sqlite3.connect(DB_PATH) - cursor = conn.cursor() - cursor.execute("SELECT points FROM users WHERE user_id=?", (user_id,)) - points = cursor.fetchone() - conn.close() - return points[0] if points else 0 - - -# ---------- 发言统计 ---------- -def add_message(user_id): - today = date.today().isoformat() - 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)) - conn.commit() - conn.close() - - -def get_daily_message_ranking(): - today = date.today().isoformat() - 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,)) - results = cursor.fetchall() - conn.close() - return results - - -# ---------- 邀请统计 ---------- -def add_invite(inviter_id, invitee_id): - conn = sqlite3.connect(DB_PATH) - cursor = conn.cursor() - cursor.execute("INSERT OR IGNORE INTO invites (inviter_id, invitee_id) VALUES (?, ?)", (inviter_id, invitee_id)) - conn.commit() - conn.close() - - -def get_invite_count(inviter_id): - conn = sqlite3.connect(DB_PATH) - cursor = conn.cursor() - cursor.execute("SELECT COUNT(*) FROM invites WHERE inviter_id=?", (inviter_id,)) - count = cursor.fetchone()[0] - conn.close() - return count - - -# ---------- Bot 主逻辑 ---------- -async def main(): - # 初始化数据库,保证缺失表也会创建 - init_db() - - bot = TelegramClient('bot_session', API_ID, API_HASH, proxy=PROXY) - await bot.start(bot_token=BOT_TOKEN) - - @bot.on(events.NewMessage) - async def message_handler(event): - # 限制群聊 - if event.chat_id not in ALLOWED_GROUPS: - return - - user = await event.get_sender() - user_id = user.id - username = user.username or user.first_name or "未知用户" - - add_or_update_user(user_id, username) - - # 只统计普通消息,不统计命令 - if not event.raw_text.startswith('/'): - add_message(user_id) - - # 处理签到命令 - if event.raw_text in ['签到', '/sign']: - if not can_sign(user_id): - await event.reply(f"🌞 @{username},你今天已经签到过啦!") - return - - add_points(user_id, SIGN_POINTS) - total = get_points(user_id) - await event.reply(f"✅ @{username} 签到成功!你获得 {SIGN_POINTS} 积分。\n当前总积分:{total}") - - # 查询每日发言排行 - elif event.raw_text == '/daily_rank': - ranking = get_daily_message_ranking() - if not ranking: - await event.reply("📊 今日还没有人发言哦~") - return - msg = "📊 今日发言排行:\n" - for i, (uname, count) in enumerate(ranking, 1): - msg += f"{i}. {uname}: {count} 条\n" - await event.reply(msg) - - # 查询自己邀请人数 - elif event.raw_text == '/my_invites': - count = get_invite_count(user_id) - await event.reply(f"👥 @{username},你邀请了 {count} 人。") - - print("🤖 签到机器人已启动,等待群聊消息...") - await bot.run_until_disconnected() - - -if __name__ == "__main__": - asyncio.run(main()) diff --git a/telegram/bot_session.session b/telegram/bot_session.session index 311d1d0e89b82195e51232ad94aaee6acadc4474..31690a3e274d3d505149b402cb9967d8e37eb1e5 100644 GIT binary patch delta 205 zcmZp8z}WDBae@>Rqu)dsCpJbu2EE=N8&ekO^KkGTXW(DNZ^`$b@AzgugYA48N;Cic z|H8!1z$VKe&0-m`^JSKVyiG=FW_o5~O0lJdg=JP|MyA}|kCWfq$urB{vz#nwZ^110 za^_?odu?X9hozIN?8BMmUU*HuVy_9JH#smWaPz-oVB$Z@%zu>s#%4i*o&45<3~UUH zEG$g2Ce^W@Gl9w&4Fq~RHg5@FV_@Q7=irccyyd;K1_lOxMh>7tpq)~T22Lk3 E0EbjS_W%F@ delta 146 zcmZp8z}WDBae@>R!>frhPHYUX81%Y?Hl{4l=VIr3&%nQk-;(eBW&wlkd=n>VO@41D z&n#;1HCfQ!f?3q*(qtcdZDvu&kCUtH!-4!$ldsrog6K^Sj0)Tg3=B;CHyHTe@!!}i yC~$^fL!hT)^OgWM1||-64(8*Iw_F3ZO!eI*z`(}9$il)X#iPb5nWeIX^QmBqKjJ zu{cvicbOn?tb`R9Vk``d-w%s4Wr{jo(wM#K*iJjJ;p!~y<_l!j<`$WQsa|1X}dsaVc1}G)u;Atv8e0*iEal(=!t*a|@sMZBlsJF#~Ao z361~%|9{-Pa?aEZU`MI4OuoNI>$~f}hp9#B>FGtOscBDlG(OqA{rT*P&$f00b(~V0 pzprN{6Hv7>gDi`|rndN#r#`I)x+66k=#HfP5*QPt7C7#61OVjGcjEv6 diff --git a/telegram/bot_session_23612.session b/telegram/bot_session_23612.session new file mode 100644 index 0000000000000000000000000000000000000000..6b4eb94b749c146cd91ac3af18f09aa3fbb0a32c GIT binary patch literal 28672 zcmeI)e@q)?7zgmXuCx_a$`WIzSa*cr3IjrAm0&V67z~%;qJV;%raQQ!9JD>SULBA) zMJ}@eU8i) z+jv(c$I86LDU*3%UA-kQJEI_*Dagpo&1M4MVT|ESkRou5;E;JMFEN#pU}vQorh>0Y z3>sT0JAJ{y1FAv=c#>Xv7f!y)7qB3Qcz3!|t&fSJ8#Z|noV-J}lnOT9>92*&1MqKO zr1^HvY~che@06Khn^+vYS)M~!oI-7g)a9DW5D|Xt;0G#Won^k(2agEoBcng}MCQK~ z6B$n$@eA!z!&Lg57@86s9AE9MvXRRv3+s|a@4CegWik2dDl*bFp3&}(U8U9=40OZ2 zUU=dz$O7*P^e&b2(0yAMA@?JM9&v#nj6;+ehs$OQF5`0Yl7qGLjLcWd!9yy`L`R4o z3bBX4@w<@N9j@>y)m!I=r_(8j4l+1rm#gL}`L-^i#Fbe74-{$q^SoqXIZh%+TgpI` zJH3n8-=yy%hxGF*s}ORMzJ(R7uUg5>6*m|H03LCkGrjJ`^c^HIF# zBA?dXrpSZ>0SG_<0uX=z1Rwwb2tWV=5P-l66i}!Y-kbb%M#o99`JglyCfLXl+Z@ zp`uG4{MOI)ogAEQ`E&jyP)|!S9NRG8>3=+&XM68-E8aU<{MWM8h6?az2p7odmeeJuDw^c zi`#bO&BRe%Tguj+ys=*gU)V-xjYheScbaeJ#{9quXO5jXTAN>S%>0h#+Ww@D=l1Mv z?%QGBEq&kD`&G@wkGI7A{9R$o9^@sf)hh9P=}>pwFXy_3n_j=(`3m_&k+JE$3!gknq7Bq~ zi^W_amkIi_B0U009U<00Izz00bZa0SG_<0uWe!0#S`G jw|6|Dq7)jnMtw8mN>1nHgdKlGP%4VnDDN_Oo)!2PO=>cb literal 0 HcmV?d00001 diff --git a/telegram/bot_session_35072.session b/telegram/bot_session_35072.session new file mode 100644 index 0000000000000000000000000000000000000000..cb3289af2cf4a9d170fcc78de7f2842bed706eb6 GIT binary patch literal 28672 zcmeI(e@q)?7zgn8y3!(BS7yu_nYaUj!oa!)wvHeQGsw0OhYryhLM`;AoRnVMyDB&` zL%}&2i08Zh9I(r`x4PsC0R891-jmS}i$kY&vB!yJgY0Zwf$}41vCiReGei+C2#i)VkPMuHjA} zJaZRhfqDadTjdmV|Ir!90|?BOEWg-@y8I$55QB#3raoHw@%rYQN3&Y)x|GyNYZHu&eL%Vf4#T6hAOHafKmY;|fB*y_009U<00Q$+K%rI;-~4~^MZz9v5P$##AOHafKmY;| zfB*y_0D(C!;L$17Bw5k0h#1l{^oCXGdc$g?KEuGBbU14hM&pZ*JhlG7eaH4*-Wx;4 zE{H`pj04?!w%Da7UO(NxDZALI$;`9#?uq(Tx3(@d8b-Dn4A(x2KczbOM#uK$W8WkUACD<%Y#u(lWB>h+Y|Khq^MHI{F#WBk ze@GdqIM=0WY$1m;A4-4nYSG&_*1c0AeL}jnR6G0LT<%`VgyY<~s-xq8hZ8>4QVkj8=?ytzPfnzgca zaE{+-qz?fIKmY;|fB*y_009U<00I!WH3Cc68v2_n=ehAO@9+qBf18%H@4epR52}eO zmfWj++1Py72cpYp5z8vspZRHy-7ZjmooKU}?G_fjB57h`;+OWL`}ef6Pb?>i%H2af zE5>vG8Ky3))#{?OeDveG3n#lT?b~&+a|ioG$~^}^Z91x8(Fr70xw37WsjvU)`|SL* zlAXU)l>J?Atatv;7X70^00Izz00bZa0SG_<0uX=z1RyYv1){uT!~B09-(d_50uX=z z1Rwwb2tWV=5P$##AV7TU{}tNvMEfgyL4yDUAOHafKmY;|fB*y_009U= target: + target = target + datetime.timedelta(days=1) + wait_seconds = (target - now).total_seconds() + print(f"[settlement] 下次结算(12:00)在 {target.isoformat()},等待 {int(wait_seconds)} s") + await asyncio.sleep(wait_seconds) + + # 执行结算 + date_iso = (target - datetime.timedelta(days=1)).date().isoformat() # 结算前一天(也可结算今天到目前为止) + print(f"[settlement] 执行结算,目标日期:{date_iso}") + ranking = get_daily_message_ranking(date_iso=date_iso, limit=DAILY_SPEAK_TOP_N) + if ranking: + for i, (uid, uname, cnt) in enumerate(ranking): + try: + add_points_immediate(uid, DAILY_SPEAK_REWARD, reason=f"daily_speak_rank_{i+1}") + except Exception as e: + print(f"[settlement] 给用户 {uid} 发奖励失败: {e}") + # 给管理员或群组发送结算通知(可选) + try: + summary_lines = [f"📅 {date_iso} 发言排行榜结算结果:"] + for i, (uid, uname, cnt) in enumerate(ranking): + summary_lines.append(f"{i+1}. @{uname or uid} — {cnt} 条 — 获得 {DAILY_SPEAK_REWARD} 积分") + summary = "\n".join(summary_lines) + for gid in ALLOWED_GROUPS: + await bot.send_message(gid, summary) + except Exception as e: + print("[settlement] 发送结算通知失败:", e) + else: + print("[settlement] 当日无发言记录,跳过发言奖励") + + # 清空那天的统计 + try: + reset_daily_messages(date_iso=date_iso) + print(f"[settlement] 清理完成:{date_iso}") + except Exception as e: + print("[settlement] 清理 daily_messages 失败:", e) + + +# ---------- 主逻辑 ---------- +async def main(): + init_db() + # 使用代理时传 proxy=PROXY,若不需要代理则移除该参数 + bot = TelegramClient('bot_session', API_ID, API_HASH, proxy=PROXY) + await bot.start(bot_token=BOT_TOKEN) + + # 启动每小时发送币价任务(对每个白名单群) + for gid in ALLOWED_GROUPS: + asyncio.create_task(send_price_periodically(bot, gid)) + + # 启动每日结算任务(12:00 America/New_York) + asyncio.create_task(daily_settlement_task(bot)) + + @bot.on(events.ChatAction) + async def welcome(event: events.ChatAction.Event): + # 欢迎新成员并尝试记录邀请者(若存在) + if event.user_added or event.user_joined: + for user in event.users: + name = user.username or user.first_name or "新成员" + # 尝试获得 inviter id(不同版本的 Telethon 结构不完全一致) + inviter_id = None + try: + # 若是邀请添加,action_message 的 from_id 通常是 inviter + if hasattr(event, 'action_message') and event.action_message: + maybe = getattr(event.action_message, "from_id", None) + if isinstance(maybe, types.PeerUser): + inviter_id = maybe.user_id + elif isinstance(maybe, (int,)): + inviter_id = maybe + # Telethon 也可能直接暴露 actor_id + if getattr(event, "actor_id", None): + inviter_id = event.actor_id + except Exception: + inviter_id = None + + # 如果 inviter_id 存在且与新成员不同,则记录邀请并奖励 + try: + if inviter_id and inviter_id != user.id: + # 确保 inviter 存在 users 表 + add_or_update_user(inviter_id, "unknown") + inc_invite(inviter_id, user.id) + except Exception as e: + print("记录邀请失败:", e) + + # 更新/插入新成员到 users 表 + add_or_update_user(user.id, user.username or user.first_name or "新成员") + + # 欢迎消息(发送到群内) + try: + await event.reply(f"欢迎 @{name} 加入群聊!\n{get_command_list_text()}") + except Exception: + pass + + @bot.on(events.NewMessage) + async def on_message(event): + # 只处理白名单群组 + if event.chat_id not in ALLOWED_GROUPS: + return + + # 普通消息处理:命令或记录发言计数 + text = (event.raw_text or "").strip() + if not text: + return + + # 去掉命令中的 @botname(如 /sign@mybot) + if "@" in text and text.startswith("/"): + text = text.split("@")[0] + + # 小写匹配命令(命令与 data 映射) + lowered = text.lower() + # 命令集合 + cmds_map = { + "签到": ["/sign", "签到", "/tanda"], + "发言": ["/daily_rank", "发言", "/kedudukan_harian"], + "邀请": ["/my_invites", "邀请", "/daily_position"], + "币价": ["/btc", "币价"] + } + for group_cmds in cmds_map.values(): + if lowered in [c.lower() for c in group_cmds]: + await handle_command(event, lowered) + return + + # 不是命令则记录发言次数 + sender = await event.get_sender() + if sender: + add_or_update_user(sender.id, sender.username or sender.first_name or "未知用户") + add_message_count(sender.id) + + @bot.on(events.CallbackQuery) + async def callback(event): + await event.answer("正在处理...", alert=False) + cmd = event.data.decode() + if "@" in cmd and cmd.startswith("/"): + cmd = cmd.split("@")[0] + + if cmd.startswith("price_"): + symbol = cmd.split("_", 1)[1] + await handle_price_command(event, symbol) + else: + await handle_command(event, cmd) + + print("🤖 机器人已启动,等待群聊消息...") + await bot.run_until_disconnected() + + +if __name__ == "__main__": + try: + asyncio.run(main()) + except KeyboardInterrupt: + print("机器人已停止") diff --git a/telegram/sign.db b/telegram/sign.db index ca58a4703d17eb9655b20c4e7e550c966698b706..b22152a98731a8d9dcaa30a10eba631216319dc0 100644 GIT binary patch delta 783 zcmZozz}WDBQ71UiC$l6~AuYcsH?c&)m_dMniHX5ML4kpRArXk#ffxo@Ch8bVCNk*t z{@~>|V_@S+X5hEuQ|0@~JBMd0Px8jb*WC31Y;5A%+KiDUiAg!B#f3RQqvMNH3rkb; zlF_;B&Oxq@A+8D`j!r(V3TSFI@)C1Xb$~iG8&g=>#T6A9n}xw<7UXB z=I`rS2^3Q1U`WYNPR%YVPEE=$nVcmrCkKoXS&&)MjEbds*?IZpc}PYXOkO7MuZ|?Z z3slan4v6s9z&ZO6!W@$m^p{9*@vAcM@8?hFSLJ`rU&|lJf0chS|4M#qpgo-Y zlhf^m^^FX;M6nsm2^B>%b#uD?OaU&C7Z~}^GVq_>Ea-5U-`0?kje(U>)EDApuHww} xJcLU^3{0$yjI0a|^-PQ`O)M>R4NR>J3?N2)WZ?e@G~ziwKQAM*A}1oP007P&$WQ71UiC$l6~AuYcsH?c&)m_dMnk&(ecL4kpRApnS3ffxpuC+ZlB1~BM# z3GwoqF|hE?Vc@spQ|0@~J7=?^fClg8IlQS%fva{dIMX