- 群聊命令「签到」(别名: 每日签到/打卡),白名单群聊或管理员可用 - 复用 xapi /bot/gacha/sign-in + /bot/points/add,与抽卡/WPF 共用 bot_gacha_daily_sign_in 表 - 积分随机 1-100,流水沿用 gacha_sign/抽卡签到;先到先得,重复签到提示已签到 - 新增 10 个单元测试,ruff 通过;更新 PLUGINS.md / README.md
79 lines
2.4 KiB
Python
79 lines
2.4 KiB
Python
"""独立每日签到插件 - 配置。
|
||
|
||
与 onmyoji_gacha 抽卡插件共用同一 xapi 服务(/bot/gacha)与鉴权配置,
|
||
签到数据天然共用 xapi `bot_gacha_daily_sign_in` 表。
|
||
"""
|
||
|
||
from pydantic import Field, field_validator
|
||
from pydantic_settings import BaseSettings, SettingsConfigDict
|
||
import os
|
||
|
||
|
||
def _read_nonebot_config(name: str) -> str:
|
||
"""从 NoneBot driver.config 读取配置;测试或独立加载模块时静默回退。"""
|
||
|
||
try:
|
||
from nonebot import get_driver
|
||
|
||
driver_config = get_driver().config
|
||
except Exception:
|
||
return ""
|
||
value = getattr(driver_config, name.lower(), "")
|
||
return str(value) if value is not None else ""
|
||
|
||
|
||
def _read_setting(name: str) -> str:
|
||
"""按单个配置名读取系统环境变量,再读取 NoneBot 配置对象。"""
|
||
|
||
return os.getenv(name, "") or _read_nonebot_config(name)
|
||
|
||
|
||
def _first_setting(*names: str, default: str = "") -> str:
|
||
"""按业务优先级读取多个兼容配置名。"""
|
||
|
||
for name in names:
|
||
value = _read_setting(name)
|
||
if value:
|
||
return value
|
||
return default
|
||
|
||
|
||
class Config(BaseSettings):
|
||
model_config = SettingsConfigDict(extra="ignore")
|
||
|
||
# xapi /bot/gacha 运行时 API 配置(与 onmyoji_gacha 共用同一服务与鉴权)
|
||
GACHA_API_HOST: str = Field(
|
||
default_factory=lambda: _first_setting(
|
||
"DANDING_GACHA_API_HOST",
|
||
default="https://api.danding.vip/bot/gacha",
|
||
)
|
||
)
|
||
BOT_TOKEN: str = Field(
|
||
default_factory=lambda: _first_setting(
|
||
"DANDING_BOT_TOKEN",
|
||
"ONMYOJI_BOT_TOKEN",
|
||
"DANDING_API_TOKEN",
|
||
"BOT_TOKEN",
|
||
)
|
||
)
|
||
BOT_USER_ID: str = Field(default_factory=lambda: _first_setting("DANDING_BOT_USER", default="1424473282"))
|
||
|
||
# 权限:白名单群聊 + 管理员
|
||
ALLOWED_GROUP_ID: int = 621016172
|
||
ALLOWED_USER_ID: int = 1424473282
|
||
|
||
# 签到积分区间(与抽卡签到一致:随机 1-100)
|
||
SIGN_IN_POINTS_MIN: int = 1
|
||
SIGN_IN_POINTS_MAX: int = 100
|
||
|
||
# 积分流水标记(与抽卡/WPF 签到共用同一事件语义,保持流水一致)
|
||
SIGN_IN_SOURCE: str = "gacha_sign"
|
||
SIGN_IN_REASON: str = "抽卡签到"
|
||
|
||
@field_validator("GACHA_API_HOST")
|
||
@classmethod
|
||
def validate_gacha_api_host(cls, value):
|
||
if not value:
|
||
raise ValueError("GACHA_API_HOST cannot be empty")
|
||
return value.rstrip("/")
|