| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135 |
- """
- 发送国内短信验证码脚本
- 扫描 verification_codes 表,查找未发送的国内短信验证码并发送
- 运行: python send_domestic_sms_code.py
- """
- import asyncio
- import sys
- import logging
- from datetime import datetime
- from typing import List, Optional
- import aiomysql
- from sqlalchemy import select
- from sqlalchemy.ext.asyncio import AsyncSession
- from config import settings
- from database import DatabaseManager
- from models_db import VerificationCode
- logger = logging.getLogger(__name__)
- async def send_domestic_sms(phone: str, code: str) -> bool:
- """
- 发送国内短信验证码
-
- Args:
- phone: 手机号
- code: 验证码
-
- Returns:
- 是否发送成功
- """
- # TODO: 实现国内短信发送 API 调用
- # 示例:
- # async with httpx.AsyncClient() as client:
- # response = await client.post(
- # "https://api.sms-provider.com/send",
- # json={
- # "phone": phone,
- # "code": code,
- # "template": "verification_code"
- # }
- # )
- # return response.status_code == 200
-
- print(f"📱 [TODO] 发送国内短信: phone={phone}, code={code}")
- return False
- async def process_domestic_sms_codes():
- """扫描并发送国内短信验证码"""
- db_manager = DatabaseManager()
-
- try:
- await db_manager.connect()
- print("✅ 数据库连接成功")
-
- async with db_manager.get_session() as session:
- # 查询未发送的国内短信验证码
- result = await session.execute(
- select(VerificationCode)
- .where(
- VerificationCode.send_type == "domestic_sms",
- VerificationCode.is_sent == False,
- VerificationCode.is_valid == True,
- VerificationCode.phone.isnot(None)
- )
- .order_by(VerificationCode.created_at.asc())
- .limit(100) # 每次处理100条
- )
- codes = result.scalars().all()
-
- if not codes:
- print("ℹ️ 没有待发送的国内短信验证码")
- return
-
- print(f"📋 找到 {len(codes)} 条待发送的国内短信验证码")
-
- success_count = 0
- fail_count = 0
-
- for code_record in codes:
- try:
- # 发送短信
- success = await send_domestic_sms(code_record.phone, code_record.code)
-
- if success:
- # 更新发送状态
- code_record.is_sent = True
- code_record.sent_at = datetime.now()
- code_record.metadata_json = code_record.metadata_json or {}
- code_record.metadata_json["send_status"] = "success"
- code_record.metadata_json["send_at"] = datetime.now().isoformat()
- success_count += 1
- print(f"✅ 发送成功: code_id={code_record.code_id}, phone={code_record.phone}")
- else:
- # 记录失败信息
- code_record.metadata_json = code_record.metadata_json or {}
- code_record.metadata_json["send_status"] = "failed"
- code_record.metadata_json["error"] = "API调用失败"
- fail_count += 1
- print(f"❌ 发送失败: code_id={code_record.code_id}, phone={code_record.phone}")
-
- await session.commit()
-
- except Exception as e:
- print(f"❌ 处理验证码失败: code_id={code_record.code_id}, error={e}")
- code_record.metadata_json = code_record.metadata_json or {}
- code_record.metadata_json["send_status"] = "error"
- code_record.metadata_json["error"] = str(e)
- await session.commit()
- fail_count += 1
-
- print(f"\n📊 处理完成: 成功 {success_count} 条, 失败 {fail_count} 条")
-
- except Exception as e:
- print(f"❌ 处理失败: {e}")
- import traceback
- traceback.print_exc()
- sys.exit(1)
- finally:
- await db_manager.close()
- if __name__ == "__main__":
- logging.basicConfig(
- level=logging.INFO,
- format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
- datefmt='%Y-%m-%d %H:%M:%S'
- )
-
- asyncio.run(process_domestic_sms_codes())
|