适用对象:当前生产/测试实例仍运行在
ca305be7df5bf11fa4213c1b0001ae158daadcf2(feat: Enhance verification message with additional group join advertisement), 需要迁移到最新mainhead。
- Node.js:当前代码使用 Node 内置
node:sqlite(见src/interpreter/state/sqliteStore.ts), 因此必须运行 Node.js >= 22.13;package.json的engines.node与该要求一致。 - pnpm:与 lockfile 匹配,当前固定
pnpm@10.17.1。
从 ca305be 到最新 main,代码经历了大量重构与功能新增,主要包括:
- 状态后端抽象
- 旧版:仅内存
TTLMap,重启后验证会话全部丢失。 - 新版:
StateStore抽象,支持memory/sqlite;Redis 后端已归档到archive/state-redis/,不再作为主包后端。
- 旧版:仅内存
- Sentry 可观测性
- 新增
@sentry/node,支持错误监控与日志转发。 - 新增
SENTRY_DSN、SENTRY_ENVIRONMENT、SENTRY_LOG_LEVEL环境变量。
- 新增
- 日志统一
- 新增
src/logger.ts,替换散落的console.*。
- 新增
- 代码结构重构
- 单体
InterpreterMtCute.ts拆分为interpreter/下的多个模块。 - 新增
joinPolicy、quizSource、state等模块。
- 单体
- 依赖变化
- mtcute 从
^0.27升级到^0.31。 - 移除
zod。 better-sqlite3继续作为直接依赖保留,版本范围与@mtcute/node对齐为^12.10.0。
- mtcute 从
- 环境变量变化
- 必填项仍为
API_ID、API_HASH、BOT_TOKEN、LOG_PEER。 - 新增可选:
ADMIN_IDS、AD_LIST_URL、STATE_BACKEND、STATE_SQLITE_PATH、SENTRY_*。 - Redis 相关
REDIS_URL不再被主包读取。
- 必填项仍为
# 在旧部署目录执行
cp -a .env .env.bak
cp -a bot-data bot-data.bak
cp -a dist dist.bak 2>/dev/null || true重点备份:
.envbot-data/quizzes.jsonbot-data/session/(mtcute 登录会话)- 如果之前已使用 sqlite/redis:对应的 state 数据
旧版是纯内存状态,因此没有可迁移的验证会话数据。升级到新版后如果启用
STATE_BACKEND=sqlite,会新建bot-data/state.db,不需要从旧版迁移数据。
cd /path/to/genshin-group-verif
git fetch origin
git checkout main
git pull --ff-only origin main
# 或直接切换到目标 commit:
# git checkout 82e27b3确认当前 head:
git rev-parse HEAD
# 期望:82e27b3(或更新的 main head)bot-data/quizzes.json 不会被 git 跟踪。迁移构建可以在该文件缺失时完成,
但运行前仍必须恢复或创建题库,否则机器人会拒绝新的验证请求。
mkdir -p bot-data
# 如果备份中有 quizzes.json,直接恢复:
cp bot-data.bak/quizzes.json bot-data/quizzes.json
# 否则创建最小合法文件最小格式:
[
{
"Id": 1,
"Question": "示例问题?",
"Options": ["选项A", "选项B"],
"CorrectOptionIndex": 0
}
]如果需要在本机/服务器上构建:
pnpm install --frozen-lockfile如果只运行已经构建好的 dist/main.mjs,可以只装 production 依赖:
pnpm install --prod --frozen-lockfile
better-sqlite3已作为直接依赖保留,--prod安装也会把它放在顶层node_modules/better-sqlite3,dist/main.mjs可以正常解析。
从备份恢复或重新创建 .env:
cp .env.bak .env
# 然后按需编辑必填项:
API_ID=
API_HASH=
BOT_TOKEN=
LOG_PEER=推荐生产配置:
STATE_BACKEND=sqlite
STATE_SQLITE_PATH=bot-data/state.db可选 Sentry:
SENTRY_DSN=
SENTRY_ENVIRONMENT=production
SENTRY_LOG_LEVEL=info其他可选:
ADMIN_IDS=
AD_LIST_URL=注意:
- 如果旧
.env中有REDIS_URL,现在主包已不再使用,可以删除。 - 当前
STATE_BACKEND只接受memory或sqlite。 - 如果旧实例使用 Redis 后端,需要先评估是否迁移到
sqlite,或等待 Redis 作为可选后端重新引入。
pnpm build构建产物:
dist/main.mjs
dist/main.mjs.map
dist/metafile.json
dist/bot-data/quizzes.json # 仅当构建时源题库存在
在正式切换前,先用前台方式验证:
node --env-file=.env --enable-source-maps dist/main.mjs预期:
- 日志出现
[State] Using ... backend - 日志出现
Loaded N quizzes from ... - 日志出现
🚀 Starting bot - 使用真实 Telegram 凭据时应能正常登录
如果使用假凭据,可能会在登录阶段报 API_ID_INVALID 等 Telegram 错误,这属于预期行为;只要没有 ERR_MODULE_NOT_FOUND 或模块加载错误即可。
确认 service 文件中的:
WorkingDirectory指向新代码目录EnvironmentFile指向新.envExecStart使用生产 bundle:
ExecStart=/usr/bin/node --enable-source-maps dist/main.mjs重启:
sudo systemctl daemon-reload
sudo systemctl restart genshin-group-verif
sudo systemctl status genshin-group-verif
journalctl -u genshin-group-verif -f镜像构建不要求题库进入构建上下文。启动前应在宿主机恢复
bot-data/quizzes.json,由 compose volume 在运行时挂载:
docker compose up -d --builddocker-compose.yaml 会挂载 ./bot-data:/app/bot-data,因此题库、SQLite state 和 session 会持久化在宿主机。
/ping应返回Pong/reload应由管理员触发并成功重载题库- 实际入群/入群申请流程应正常工作
- 如果配置了 Sentry,可在 Sentry 后台看到 environment 与日志
- 如果启用
STATE_BACKEND=sqlite,确认bot-data/state.db可写且重启后会话仍可恢复
如果迁移后出现问题,可以回滚到旧版本:
# 回到旧 commit
git checkout ca305be7df5bf11fa4213c1b0001ae158daadcf2
pnpm install --frozen-lockfile
pnpm build
# 恢复旧环境变量和题库
cp .env.bak .env
cp -a bot-data.bak/. bot-data/
# 重启服务
sudo systemctl restart genshin-group-verif
# 或
docker compose up -d --build注意:如果新版已经写入了
bot-data/state.db或修改了 mtcute session, 回滚前建议再备份一次新数据。
- mtcute 从
^0.27升到^0.31属于大版本升级,bot-data/session/中的会话文件可能出现不兼容。迁移前务必备份;如果登录异常,可删除 session 后让机器人用BOT_TOKEN重新登录。 - 旧版是纯内存状态,迁移到新版后若希望重启不丢验证会话,请设置
STATE_BACKEND=sqlite。 - Redis 后端已从主包移除并归档,不要在新部署中继续依赖
STATE_BACKEND=redis或REDIS_URL。