Files
derp/plugins/alias.py
user e9d17e8b00 feat: voice profiles, rubberband FX, per-bot plugin filtering
- Add rubberband package to container for pitch-shifting FX
- Split FX chain: rubberband CLI for pitch, ffmpeg for filters
- Configurable voice profile (voice, fx, piper params) in [voice]
- Extra bots inherit voice config (minus trigger) for own TTS
- Greeting is voice-only, spoken directly by the greeting bot
- Per-bot only_plugins/except_plugins filtering on Mumble
- Alias plugin, core plugin tests

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 11:41:00 +01:00

86 lines
2.7 KiB
Python

"""Plugin: user-defined command aliases (persistent)."""
from __future__ import annotations
import logging
from derp.plugin import command
log = logging.getLogger(__name__)
_NS = "alias"
@command("alias", help="Aliases: !alias add|del|list|clear")
async def cmd_alias(bot, message):
"""Create short aliases for existing bot commands.
Usage:
!alias add <name> <target> Create alias (e.g. !alias add s skip)
!alias del <name> Remove alias
!alias list Show all aliases
!alias clear Remove all aliases (admin only)
"""
parts = message.text.split(None, 3)
if len(parts) < 2:
await bot.reply(message, "Usage: !alias <add|del|list|clear> [args]")
return
sub = parts[1].lower()
if sub == "add":
if len(parts) < 4:
await bot.reply(message, "Usage: !alias add <name> <target>")
return
name = parts[2].lower()
target = parts[3].lower()
# Cannot shadow an existing registered command
if name in bot.registry.commands:
await bot.reply(message, f"'{name}' is already a registered command")
return
# Cannot alias to another alias (single-level only)
if bot.state.get(_NS, target) is not None:
await bot.reply(message, f"'{target}' is itself an alias; no chaining")
return
# Target must resolve to a real command
if target not in bot.registry.commands:
await bot.reply(message, f"unknown command: {target}")
return
bot.state.set(_NS, name, target)
await bot.reply(message, f"alias: {name} -> {target}")
elif sub == "del":
if len(parts) < 3:
await bot.reply(message, "Usage: !alias del <name>")
return
name = parts[2].lower()
if bot.state.delete(_NS, name):
await bot.reply(message, f"alias removed: {name}")
else:
await bot.reply(message, f"no alias: {name}")
elif sub == "list":
keys = bot.state.keys(_NS)
if not keys:
await bot.reply(message, "No aliases defined")
return
entries = []
for key in sorted(keys):
target = bot.state.get(_NS, key)
entries.append(f"{key} -> {target}")
await bot.reply(message, "Aliases: " + ", ".join(entries))
elif sub == "clear":
if not bot._is_admin(message):
await bot.reply(message, "Permission denied: clear requires admin")
return
count = bot.state.clear(_NS)
await bot.reply(message, f"Cleared {count} alias(es)")
else:
await bot.reply(message, "Usage: !alias <add|del|list|clear> [args]")