10 KiB
LTD-ManagerBot Module Documentation
Table of Contents
Quick Start
- Copy the example configs from
src/main/resources/toconfig/ - Edit
config/application.yaml— set database, API URLs, tokens - Edit
config/module.yaml— uncomment and configure desired modules - Place SQL templates in
config/sql/if using InvitationCodes or WhitelistAudit - Launch the bot
Minimal application.yaml additions for new modules
# Whitelist System API (required by WhitelistAuditModule)
whitelist-system:
url: "https://whitelist.your-server.top"
encrypted-token: "your-api-token-here"
Infrastructure Modules
GroupMessagePollingModule
Polls a QQ group's message history at a fixed interval and emits a SharedFlow<List<MsgHistorySpecificMsg>>. Other modules subscribe to this flow to react to messages.
- name: "talkGroup"
type: "GROUP_MESSAGE_POLLING_MODULE"
enabled: true
config:
target-group-id: 538751386
poll-interval-millis: 5000 # optional, default 5000
msg-history-check: 15 # optional, default 15
MailModule
Queues and sends emails via SMTP. Used by InvitationCodesModule and WhitelistAuditModule.
- name: "talkGroup"
type: "MAIL_MODULE"
enabled: true
SMTP settings go in application.yaml → mail: section.
New Modules
RCON Command Module
Type: RCON_COMMAND_MODULE
Allows specified QQ users to execute arbitrary Minecraft RCON commands via QQ group messages, with a configurable blocklist to prevent dangerous operations.
Workflow
QQ Group: "rcon list"
│
├── User NOT in admin-ids → reply: "no permission"
├── Command matches blocklist → reply: "blocked"
└── Execute via RCON binary → reply with output
Example Config
- name: "talkGroup"
type: "RCON_COMMAND_MODULE"
enabled: true
dependencies:
- name: "talkGroup"
type: "GROUP_MESSAGE_POLLING_MODULE"
config:
self-id: 3327379836
self-nick-name: "Bot"
command-prefix: "rcon"
admin-ids: [2561098830]
rcon-timeout-sec: 5
command-blocklist:
- "stop"
- "restart"
- "op"
- "deop"
- "whitelist"
- "ban"
- "ban-ip"
- "kick"
- "debug"
- "execute"
Config Reference
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
self-id |
long | yes | — | Bot's QQ ID |
self-nick-name |
string | yes | — | Bot's display name |
command-prefix |
string | yes | — | Trigger prefix in QQ group |
admin-ids |
long[] | yes | — | QQ IDs allowed to execute RCON |
command-blocklist |
string[] | yes | — | Blocked command prefixes (case-insensitive, /-prefix stripped) |
rcon-timeout-sec |
long | no | 5 |
RCON timeout in seconds |
The RCON binary path and config path are read from application.yaml → tools.rcon.
Blocklist Matching
The blocklist uses prefix matching after stripping leading /:
"stop"blocks:stop,stop 10s,/stop,/minecraft:stop"ban"blocks:ban Steve,ban-ip,/ban, etc.
Gitea Webhook Module
Type: GITEA_WEBHOOK_MODULE
Starts an embedded HTTP server to receive Gitea webhook events and forwards formatted notifications to a QQ group.
Supported Events
| Event | QQ Message Format |
|---|---|
push |
Author, branch, commit count, first 5 commit messages, compare URL |
issues |
Action (opened/closed/reopened), title, body preview, link |
pull_request |
Action, branches (head → base), state, link |
create |
Branch/tag created, author |
delete |
Branch/tag deleted, author |
release |
Tag name, release name, body preview, draft/prerelease flags |
repository |
Action (created/deleted/transferred) |
fork |
Source repo → forked repo |
Example Config
- name: "talkGroup"
type: "GITEA_WEBHOOK_MODULE"
enabled: true
config:
webhook-port: 8080
webhook-path: "/gitea-webhook"
webhook-secret: "your-webhook-secret"
target-group-id: 538751386
events:
- "push"
- "issues"
- "pull_request"
- "create"
- "delete"
- "release"
Config Reference
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
webhook-port |
int | yes | — | HTTP server listen port |
webhook-path |
string | no | /gitea-webhook |
Webhook endpoint path |
webhook-secret |
string | no | "" |
HMAC-SHA256 secret for signature verification |
target-group-id |
long | yes | — | QQ group to send notifications to |
events |
string[] | no | all | Event types to listen for |
Gitea-side Setup
In your Gitea repository → Settings → Webhooks → Add Webhook → Gitea:
- Target URL:
http://<server-ip>:8080/gitea-webhook - Secret: Same as
webhook-secret - Trigger On: Select desired events
Security
- Signature verification:
X-Gitea-Signatureheader validated via HMAC-SHA256 - Empty
webhook-secretdisables verification (not recommended for production)
Whitelist Audit Module
Type: WHITELIST_AUDIT_MODULE
Periodically checks the whitelist group membership against the whitelist API. Automatically rejects users who left the group, with a configurable grace period for re-activation via keywords in the main group. Supports admin-triggered manual audits.
Lifecycle States
In Whitelist Group ───────────────────────────────► OK (no action)
│
└── User left group ──► Detected ──► Rejected (grace period starts)
│
├── Keyword in main group ──► Re-Activated
├── Warning threshold ──► Email/Group notification sent
└── Grace period expired ──► Permanently Removed
Two-Trigger System
| Trigger | Group | Who | Action |
|---|---|---|---|
| Keyword (e.g. "重新激活") | Main group | Any pending user | Re-activates whitelist |
| Audit command (e.g. "审计") | Whitelist group | audit-allowed-ids only |
Runs immediate audit + posts results |
Example Config
- name: "talkGroup"
type: "WHITELIST_AUDIT_MODULE"
enabled: true
dependencies:
- name: "talkGroup"
type: "GROUP_MESSAGE_POLLING_MODULE"
- name: "whitelistGroup"
type: "GROUP_MESSAGE_POLLING_MODULE"
- name: "talkGroup" # only if enable-email: true
type: "MAIL_MODULE"
config:
self-id: 3327379836
filter-qq-list: [2561098830, 3327379836]
audit-allowed-ids: [2561098830]
whitelist-group-polling-dep-name: "whitelistGroup"
audit-command-prefix: "审计"
re-activation-keywords:
- "重新激活"
- "激活白名单"
- "reactivate"
grace-period-days: 7
expiry-warning-days: 2
poll-interval-minutes: 60
enable-email: false
Config Reference
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
self-id |
long | yes | — | Bot's QQ ID |
filter-qq-list |
long[] | yes | — | QQ IDs never auto-rejected |
audit-allowed-ids |
long[] | yes | — | QQ IDs allowed to trigger manual audit |
whitelist-group-polling-dep-name |
string | yes | — | Dependency name for the whitelist group polling module |
audit-command-prefix |
string | no | "审计" |
Command to trigger manual audit in whitelist group |
re-activation-keywords |
string[] | yes | — | Keywords to re-activate from main group |
grace-period-days |
int | yes | — | Days user has to re-activate after being rejected |
expiry-warning-days |
int | yes | — | Days before expiry to send warning |
poll-interval-minutes |
long | no | 60 |
Auto-audit interval in minutes |
enable-email |
boolean | no | false |
Enable email notifications (requires MailModule) |
Manual Audit Output Example
审计完成
────────────────
白名单总数: 42
在群正常: 35 人
新发现不在群(已拒绝): 2 人
宽限期中: Steve(剩5天), Alex(剩2天)
已过期删除: 1 人
过滤列表跳过: 3 人
State Persistence
Audit state is persisted to data/whitelist_audit_state.json with automatic backup. Survives bot restarts without losing pending reject records.
Dependencies
| Dependency | Type | Required | Purpose |
|---|---|---|---|
| Main group polling | GROUP_MESSAGE_POLLING_MODULE |
yes | Re-activation keyword monitoring |
| Whitelist group polling | GROUP_MESSAGE_POLLING_MODULE |
yes | Audit command monitoring + member list |
| Mail module | MAIL_MODULE |
if enable-email: true |
Email notifications |
Whitetelist API Config
API URL and token are in application.yaml whitelist-system: section for security (auto-encrypted):
whitelist-system:
url: "https://whitelist.your-server.top"
encrypted-token: "your-api-token-here"
Configuration Reference
SQL Templates
Some modules (InvitationCodesModule, GroupRequestHandlerModule) use SQL templates stored in config/sql/. Templates use ${placeholder} syntax:
-- config/sql/invitation/query_qualification.sql
SELECT q.player_id, q.effective, q.is_used, q.qq, q.status
FROM ltd_manager_bot.qualified_user_info q
WHERE q.qq IN (${placeholders})
Usage in code:
val sql = SqlTemplate.fromFile("invitation/query_qualification.sql")
val result = sql.bind("placeholders" to "?, ?, ?")
Message Filter Pipeline
All message-driven modules use a common TriggerMessageFilter pipeline:
IgnoreSelfFilter → NewMessageFilter → KeywordFilter → [CooldownFilter] → handler
This ensures messages from the bot itself are ignored, only new messages are processed, and only keyword-matching messages reach the handler.