Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 30 additions & 13 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,33 +3,50 @@ services:
build: .
container_name: sheerid-tgbot
restart: unless-stopped

# 环境变量
depends_on:
- mysql
environment:
- TZ=Asia/Shanghai
- PYTHONUNBUFFERED=1
# Telegram Bot 配置
# Telegram Bot Config
- BOT_TOKEN=${BOT_TOKEN}
- CHANNEL_USERNAME=${CHANNEL_USERNAME:-pk_oa}
- CHANNEL_URL=${CHANNEL_URL:-https://t.me/pk_oa}
- ADMIN_USER_ID=${ADMIN_USER_ID}
# MySQL配置
- MYSQL_HOST=${MYSQL_HOST:-localhost}
- MYSQL_PORT=${MYSQL_PORT:-3306}
# MySQL Config
- MYSQL_HOST=mysql
- MYSQL_PORT=3306
- MYSQL_USER=${MYSQL_USER:-tgbot_user}
- MYSQL_PASSWORD=${MYSQL_PASSWORD}
- MYSQL_PASSWORD=${MYSQL_PASSWORD:-tgbot_password}
- MYSQL_DATABASE=${MYSQL_DATABASE:-tgbot_verify}

# 日志持久化
volumes:
- ./logs:/app/logs

# 日志配置
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
networks:
- tgbot-net

mysql:
image: mysql:5.7
platform: linux/amd64
container_name: sheerid-mysql
restart: unless-stopped
environment:
- MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD:-root_password}
- MYSQL_DATABASE=${MYSQL_DATABASE:-tgbot_verify}
- MYSQL_USER=${MYSQL_USER:-tgbot_user}
- MYSQL_PASSWORD=${MYSQL_PASSWORD:-tgbot_password}
volumes:
- mysql_data:/var/lib/mysql
networks:
- tgbot-net

volumes:
mysql_data:

# 网络模式
network_mode: bridge
networks:
tgbot-net:
driver: bridge
38 changes: 19 additions & 19 deletions handlers/verify_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ async def verify3_command(update: Update, context: ContextTypes.DEFAULT_TYPE, db

try:
async with semaphore:
verifier = SpotifyVerifier(verification_id)
verifier = SpotifyVerifier(verification_id)
result = await asyncio.to_thread(verifier.verify)

db.add_verification(
Expand Down Expand Up @@ -324,7 +324,7 @@ async def verify4_command(update: Update, context: ContextTypes.DEFAULT_TYPE, db
f"已退回 {VERIFY_COST} 积分"
)
return

vid = result.get("verification_id", "")
if not vid:
db.add_balance(user_id, VERIFY_COST)
Expand All @@ -333,18 +333,18 @@ async def verify4_command(update: Update, context: ContextTypes.DEFAULT_TYPE, db
f"已退回 {VERIFY_COST} 积分"
)
return

# 更新消息
await processing_msg.edit_text(
f"✅ 文档已提交!\n"
f"📋 验证ID: `{vid}`\n\n"
f"🔍 正在自动获取认证码...\n"
f"(最多等待20秒)"
)

# 第2步:自动获取认证码(最多20秒)
code = await _auto_get_reward_code(vid, max_wait=20, interval=5)

if code:
# 成功获取
result_msg = (
Expand All @@ -356,9 +356,9 @@ async def verify4_command(update: Update, context: ContextTypes.DEFAULT_TYPE, db
)
if result.get("redirect_url"):
result_msg += f"\n🔗 跳转链接:\n{result['redirect_url']}"

await processing_msg.edit_text(result_msg)

# 保存成功记录
db.add_verification(
user_id,
Expand All @@ -378,7 +378,7 @@ async def verify4_command(update: Update, context: ContextTypes.DEFAULT_TYPE, db
f"`/getV4Code {vid}`\n\n"
f"注意:积分已消耗,稍后查询无需再付费"
)

# 保存待处理记录
db.add_verification(
user_id,
Expand All @@ -388,7 +388,7 @@ async def verify4_command(update: Update, context: ContextTypes.DEFAULT_TYPE, db
"Waiting for review",
vid
)

except Exception as e:
logger.error("Bolt.new 验证过程出错: %s", e)
db.add_balance(user_id, VERIFY_COST)
Expand All @@ -404,39 +404,39 @@ async def _auto_get_reward_code(
interval: int = 5
) -> Optional[str]:
"""自动获取认证码(轻量级轮询,不影响并发)

Args:
verification_id: 验证ID
max_wait: 最大等待时间(秒)
interval: 轮询间隔(秒)

Returns:
str: 认证码,如果获取失败返回None
"""
import time
start_time = time.time()
attempts = 0

async with httpx.AsyncClient(timeout=30.0) as client:
while True:
elapsed = int(time.time() - start_time)
attempts += 1

# 检查是否超时
if elapsed >= max_wait:
logger.info(f"自动获取code超时({elapsed}秒),让用户手动查询")
return None

try:
# 查询验证状态
response = await client.get(
f"https://my.sheerid.com/rest/v2/verification/{verification_id}"
)

if response.status_code == 200:
data = response.json()
current_step = data.get("currentStep")

if current_step == "success":
# 获取认证码
code = data.get("rewardCode") or data.get("rewardData", {}).get("rewardCode")
Expand All @@ -448,14 +448,14 @@ async def _auto_get_reward_code(
logger.warning(f"审核失败: {data.get('errorIds', [])}")
return None
# else: pending,继续等待

# 等待下次轮询
await asyncio.sleep(interval)

except Exception as e:
logger.warning(f"查询认证码出错: {e}")
await asyncio.sleep(interval)

return None


Expand Down