import os import asyncio import aiohttp from nonebot import get_plugin_config, get_driver from .config import Config from nonebot import logger plugin_config = get_plugin_config(Config) # NoneBot2 把 .env 读入 driver.config 而非 os.environ,手动兜底 _driver_config = get_driver().config if not plugin_config.Token: plugin_config.Token = getattr(_driver_config, "danding_api_token", "") or os.environ.get("DANDING_API_TOKEN", "") if not plugin_config.EMAIL_PASSWORD: plugin_config.EMAIL_PASSWORD = getattr(_driver_config, "danding_email_password", "") or os.environ.get("DANDING_EMAIL_PASSWORD", "") router:dict = { "在线人数":"bot_online_count", "添加卡密":"bot_add_kami", "生成卡密":"bot_create_kami", "用户加时":"bot_add_user_viptime", "生成QQ验证码":"bot_generate_vcode", "获取日志":"bot_get_user_log" } async def post(router_name: str, user: str, data: dict = None) -> str: """发送POST请求到API服务器""" if data is None: data = {} _url = plugin_config.DDApi_Host + router[router_name] data["user"] = user data["token"] = plugin_config.Token try: async with aiohttp.ClientSession() as session: async with session.post(_url, json=data, timeout=aiohttp.ClientTimeout(total=10)) as resp: logger.debug(f"post {router_name}: status={resp.status}") if resp.status != 200: return "出错啦!" r = await resp.json() logger.debug(f"post {router_name}: {r}") return r.get("message", "出错啦!") except Exception as e: logger.error(f"post {router_name} 请求失败: {e}") return "出错啦!" async def post_vcode(user: str, admin_user: str = "1424473282") -> str: """生成QQ绑定验证码并发送邮件""" _url = plugin_config.DDApi_Host + router["生成QQ验证码"] data = {"user": admin_user, "token": plugin_config.Token, "qq": user} logger.debug(f"post_vcode: url={_url}, token='{plugin_config.Token}', data={data}") try: async with aiohttp.ClientSession() as session: async with session.post(_url, json=data, timeout=aiohttp.ClientTimeout(total=10)) as resp: logger.debug(f"post_vcode: status={resp.status}") if resp.status != 200: return "出错啦!" r = await resp.json() logger.debug(f"post_vcode: {r}") except Exception as e: logger.error(f"post_vcode 请求失败: {e}") return "出错啦!" msg = r.get("message", "") if "验证码生成成功" in msg: resp_data = await send_mail(f"{user}@qq.com", "验证码生成成功", msg, "DanDing-Admin") if resp_data is not None and resp_data.get("errorNo", -1) == 0: return f"生成的绑定验证码已经发送到 {user}@qq.com 邮箱中,请查收!" return msg return msg async def get_log(user: str, admin_user: str = "1424473282") -> str: """获取用户操作日志""" _url = plugin_config.DDApi_Host + router["获取日志"] params = {"user": admin_user, "token": plugin_config.Token, "qq": user} try: async with aiohttp.ClientSession() as session: async with session.get(_url, params=params, timeout=aiohttp.ClientTimeout(total=10)) as resp: logger.debug(f"get_log: status={resp.status}") if resp.status != 200: return "出错啦!" r = await resp.json() logger.debug(f"get_log: {r}") return r.get("message", "出错啦!") except Exception as e: logger.error(f"get_log 请求失败: {e}") return "出错啦!" def get_classes(classee:str): """ 将口语类型转换为程序可识别的标准卡密类型 """ cases = { 'day': 'Day', 'DAY': 'Day', '天': 'Day', '天卡': 'Day', 'week': 'Week', 'WEEK': 'Week', '周': 'Week', '周卡': 'Week', 'month': 'Month', 'MONTH': 'Month', '月': 'Month', '月卡': 'Month', } return cases.get(classee, '') # PMail 邮箱服务配置 session_id: str = "" login_url = plugin_config.EMAIL_LOGIN login_pdata = { "account": plugin_config.EMAIL_USER, "password": plugin_config.EMAIL_PASSWORD } async def login_pmail(): """登录PMail邮箱服务获取session cookie""" global session_id retries = 3 for attempt in range(retries): try: async with aiohttp.ClientSession() as sess: async with sess.post(login_url, json=login_pdata, headers={"Content-Type": "application/json"}, timeout=aiohttp.ClientTimeout(total=10)) as resp: if resp.status == 200: body = await resp.json() if body.get("errorNo") == 0: logger.info("PMail App 登录成功!") session_id = resp.headers.get("Set-Cookie", "") return except Exception as e: logger.warning(f"PMail App 登录失败 ({attempt + 1}/{retries}): {e}") logger.error("PMail App 登录失败!无法使用邮件功能!") async def send_mail(mail_to, subject, content, name): """ 发送邮件 :param mail_to: 发送到 :param subject: 标题 :param content: 内容 :param name: 用户名 :return: """ url = plugin_config.EMAIL_API pdata = { 'from': { "name": "DanDing-Admin", "email": plugin_config.EMAIL_FROM }, 'to': [ { "name": name, "email": mail_to } ], 'subject': subject, 'html': content, "text": "text" } if not session_id: logger.error("[error] 邮件发送失败,没有session_id,尝试重新登录邮箱服务!") await login_pmail() try: async with aiohttp.ClientSession() as sess: async with sess.post(url, json=pdata, headers={"cookie": f"{session_id}"}, timeout=aiohttp.ClientTimeout(total=15)) as resp: resp_data = await resp.json() except Exception as e: logger.error(f"[error] 邮件发送请求失败: {e}") resp_data = None if resp_data is None or resp_data.get("errorNo", -1) != 0: logger.error("[error] 邮件发送失败,尝试重新登录邮箱服务!") await login_pmail() try: async with aiohttp.ClientSession() as sess: async with sess.post(url, json=pdata, headers={"cookie": f"{session_id}"}, timeout=aiohttp.ClientTimeout(total=15)) as resp: resp_data = await resp.json() except Exception: return {"errorNo": 0, "errorMsg": "", "data": ""} return resp_data