sopel-irc / sopel

:robot::speech_balloon: An easy-to-use and highly extensible IRC Bot framework. Formerly Willie.
https://sopel.chat
Other
949 stars 403 forks source link

Idea: Lazy channel-restriction decorator #2423

Open dgw opened 1 year ago

dgw commented 1 year ago

Requested Feature

New decorator (tentative name: @plugin.allowed_channels) that takes one or more functions as arguments which will be used at runtime to retrieve the list of channels, similar to how @plugin.rule_lazy and friends work.

The decorator's purpose is to allow restricting in which channels certain commands can be used, without using "a bunch of ifs" (as went the tongue-in-cheek complaint in #2082).

Problems Solved

It is relatively common that bot owners may want to add "spammy" games or other content to their bots that are not appropriate for general use in all channels where the bot is joined. While creating a second config just for such games is an option, in practice bot owners tend to make bespoke copies of plugin code instead with the channel restrictions hard-coded.

In #2082, it was requested to add an optional argument to @plugin.require_chanmsg that would allow restricting the decorated callable to a specific channel(s) named at import time. This isn't an ideal solution, because it still requires hard-coding allowed channels into the plugin file.

However, decorators like @plugin.rule_lazy and its friends are configurable at runtime via their reliance on helper functions. In the rule_lazy-and-friends case, such helper functions are given access to the bot's settings so they can generate a list of text patterns to match based on the bot's config. This approach can be applied to generating a list of allowed channels, too.

This solves the problem both the de facto and previously-suggested approaches have regarding configurability.

Alternatives

The main alternative is a custom decorator as detailed in the comments of #2082, or the aforementioned "bunch of ifs" with hard-coded channel names. An upcoming pull request will propose documentation of the custom decorator approach as part of our Advanced Tips & Tricks page for plugin devs.

Notes

A sister decorator called @plugin.restricted_channels that performs the opposite function would be logical, but that does fall squarely under the existing per-channel command blocking feature, especially once it becomes easier to configure, so it would (IMO) have a shorter useful lifespan as part of Sopel's plugin API.

However, I also think this kind of thing is ultimately best done by the bot rather than the plugin. I'm opening this issue to gather Proper Feedback™ on what could be an alternative to a previously suggested idea. (#2082)

It's obviously more useful to more bot owners if they have the freedom to allow/block channels at will for any command (or entire plugin) regardless of whether a given plugin's developer has implemented this decorator. Therefore, even if the only result of this issue is its closure as "not worth it", followed by renewed discussion on #2358, I'll still be happy.

Exirel commented 1 year ago

I like both decorators (@plugin.allowed_channel and @plugin.restricted_channels). I think it's doable without too much trouble.

And it's true, if the bot had a better way to configure which plugin is allowed in each channel, that would be probably easier for the bot owner. I'd say that both version can coexist!