feat(sign_in): 新增独立每日签到插件,与抽卡签到共用同一份签到数据
- 群聊命令「签到」(别名: 每日签到/打卡),白名单群聊或管理员可用 - 复用 xapi /bot/gacha/sign-in + /bot/points/add,与抽卡/WPF 共用 bot_gacha_daily_sign_in 表 - 积分随机 1-100,流水沿用 gacha_sign/抽卡签到;先到先得,重复签到提示已签到 - 新增 10 个单元测试,ruff 通过;更新 PLUGINS.md / README.md
This commit is contained in:
78
danding_bot/plugins/danding_sign_in/config.py
Normal file
78
danding_bot/plugins/danding_sign_in/config.py
Normal file
@@ -0,0 +1,78 @@
|
||||
"""独立每日签到插件 - 配置。
|
||||
|
||||
与 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("/")
|
||||
Reference in New Issue
Block a user