How HoshinoBot's Superuser Command System (sucmd) Works: Privileged Commands Explained
HoshinoBot's @sucmd decorator creates privileged commands restricted to superusers by checking hoshino.config.SUPERUSERS and setting privileged=True in the nonebot registration, optionally enforcing private-only execution.
The sucmd system in ice9coffee/hoshinobot provides the security layer for administrative functions. This decorator-based mechanism ensures that sensitive bot management commands can only be executed by designated superusers, regardless of group permissions or user roles held by the caller.
Understanding the sucmd Decorator Implementation
Core Mechanism in service.py
In hoshino/service.py (lines 402-426), the sucmd function defines a wrapper that injects kwargs['privileged'] = True before registering the command with nonebot. This flag instructs the underlying framework to bypass normal permission checks, placing full responsibility on HoshinoBot's internal validation.
The wrapper performs three critical validations before executing the command logic:
- Superuser validation: Compares
session.event.user_idagainst thehoshino.config.SUPERUSERSlist, silently returning if the user is not authorized - Privacy enforcement: When
force_private=True(the default), rejects non-private messages with a warning reply - Error isolation: Catches exceptions, logs them via the dedicated
sulogger, and prevents the error from crashing the bot instance
Registration Flow
The decorator completes registration through return nonebot.on_command(name, **kwargs)(wrapper). By this execution point, the privileged flag is already injected into the keyword arguments, ensuring the superuser check runs before any command logic.
What Are Privileged Commands?
Privileged commands are administrative functions wrapped with @sucmd that perform high-impact operations affecting multiple groups or core bot services. Unlike standard commands that respect group-specific permissions, these remain strictly limited to the user IDs configured in the superuser list.
The repository includes several built-in privileged commands:
ls(hoshino/modules/botmanage/ls.py): Lists active groups, friends, and loaded services for environment overviewquit(hoshino/modules/botmanage/group_leave.py): Forces the bot to exit specified group chatsbroadcast(hoshino/modules/botmanage/broadcast.py): Sends announcement messages to all enabled groups simultaneouslybilling(hoshino/modules/botmanage/billing.py): Retrieves usage statistics and billing informationupdate-pcr-chara(hoshino/modules/priconne/pcr_data_updater.py): Triggers data refreshes for Princess Connect character databasesreload-twitter-stream-daemon(hoshino/modules/twitter/stream/__init__.py): Restarts the Twitter streaming services
Runtime Execution Flow
When a message triggers a privileged command, the following sequence occurs:
- Command matching: nonebot identifies the registered command name from the message content
- Privilege verification: The
sucmdwrapper checks if the sender's ID exists inconfig.SUPERUSERS, silently aborting if unauthorized - Session validation: If
force_privateis enabled and the event originates from a group, the wrapper sends a privacy warning and stops execution - Logic execution: The original async function runs, performing administrative actions or data modifications
- Error handling: Any exceptions are captured by
suloggerwithout terminating the bot instance
This layered approach ensures that even group owners or administrators cannot invoke these commands unless explicitly listed in the superuser configuration.
Implementing Custom Privileged Commands
To create a superuser-only command, import sucmd from the service module and apply the decorator to your async function:
from hoshino import sucmd
import hoshino
@sucmd('clear-cache', force_private=True)
async def clear_cache(session):
"""Clear temporary cache files (superuser only)"""
user_id = session.event.user_id
# Additional validation (optional, as decorator already checks)
if user_id not in hoshino.config.SUPERUSERS:
return
# Perform administrative action
await session.send('Cache cleared successfully')
The force_private parameter defaults to True, ensuring the command only responds in private messages. Set force_private=False to allow execution from group chats while maintaining the superuser restriction.
Summary
sucmddecorator: Defined inhoshino/service.py, creates commands withprivileged=Trueand built-in superuser validation- Superuser verification: Validates
session.event.user_idagainsthoshino.config.SUPERUSERSbefore executing logic - Private enforcement:
force_privateparameter restricts commands to private chats by default for additional security - Error resilience: Uses
suloggerto capture exceptions without crashing the bot process - Administrative scope: Privileged commands manage group membership, broadcast messages, update game data, and control external service daemons
Frequently Asked Questions
How do I configure superusers in HoshinoBot?
Add the user's QQ ID to the SUPERUSERS set in your hoshino/config/__init__.py or configuration file. The sucmd decorator automatically references this list during every command invocation to verify permissions.
Can privileged commands execute in group chats?
Yes, but only if explicitly configured with force_private=False. By default, force_private=True restricts execution to private messages. Even when enabled for groups, the command still requires the user to be in the superuser list.
What happens when a non-superuser attempts a privileged command?
The command is silently ignored. The wrapper checks the sender's ID against the superuser list and returns immediately without executing the command logic or revealing the command's existence to unauthorized users.
Where are privileged command errors logged?
Exceptions are captured and logged via the dedicated sulogger instance defined in hoshino/service.py. This prevents administrative script errors from crashing the bot while maintaining an audit trail for debugging privileged operations.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →