# Copyright (c) 2026 Krzysztof Rudnicki. MIT licence. """!good bot: the bot says thank you the one way that adds no noise. A reaction rather than a reply. "good bot" is a compliment, and answering a compliment with a line of text is the kind of thing that gets a bot muted; an emoji on the compliment itself is seen by the whole group without taking up a line. Which emoji is a draw from a small warm set, so the second thank-you of the evening does not look like a canned copy of the first. Rate-limited like every other command: a heart costs a POST to the container, and somebody typing it in a loop is the same problem as somebody typing !cat in a loop. The trigger is two words, which no other command has. That works because ``folding.fold`` keeps inner spaces and the registry matches the whole text before it looks at the first word -- so "!good bot" resolves, "!good" alone resolves to nothing, and "!good bot" typed with two spaces resolves to nothing either. The one-word spellings in aliases.json are for that last case. """ from __future__ import annotations import secrets from typing import TYPE_CHECKING, Final from signal_bot.animals import load_aliases if TYPE_CHECKING: from collections.abc import Sequence from signal_bot.context import CommandContext from signal_bot.decorators import Decorator from signal_bot.registry import CommandRegistry, Handler COMMAND_NAME: Final = "good_bot" DESCRIPTION: Final = "bot dziękuje za komplement reakcją, bez gadania" # Warm and unambiguous, nothing that reads as sarcasm in a group chat. EMOJI: Final = ("❤️", "🥰", "😊", "👍", "🎉", "🙏", "😸") def pick(choices: Sequence[str] = EMOJI) -> str: """One emoji, uniformly at random. secrets rather than random for the reason animals.paged_url gives: the choice is not security-sensitive, but ruff's ALL rule set flags `random` and this repository forbids the noqa that would silence it. """ return choices[secrets.randbelow(len(choices))] async def good_bot_handler(ctx: CommandContext) -> None: """Thank the asker on their own message; say nothing in the group.""" await ctx.react(pick()) def register_good_bot_command( registry: CommandRegistry, *, decorate: Decorator | None = None, aliases: dict[str, list[str]] | None = None, ) -> None: """Register !good bot under every spelling aliases.json gives it.""" table = load_aliases() if aliases is None else aliases handler: Handler = good_bot_handler if decorate is not None: handler = decorate(handler) registry.register(COMMAND_NAME, table[COMMAND_NAME], handler, DESCRIPTION)