234 lines
6.8 KiB
Python
234 lines
6.8 KiB
Python
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())
|