sopel-irc / sopel

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

Should include CLIENTTAGDENY parsing in ISUPPORT #2501

Open dgw opened 11 months ago

dgw commented 11 months ago

Coretasks asks for message-tags now, and with that comes the world of all tag types—client-only tags included. (Even if coretasks didn't, plugins can pretty easily request the capability themselves thanks to #2341.)

Part of the message tag specification is CLIENTTAGDENY, a comma-separated list of client-only tag names (without the + prefix) that the server will ignore (remove) when forwarding messages to other clients. The list can also start with * to block all client-only tags and exempt just a few tag names with the - prefix.

Note: I typed this on a "smart"phone, which tried to auto-incorrect many things as I went. Hopefully none of its attempts escaped my notice and thus became successful.

Current state

Sopel's ISupport object handles the CLIENTTAGDENY token value as a plain string right now:

>>> i.CLIENTTAGDENY
'typing,draft/foobar'

Plugin code can certainly use this to check whether a tag is denied, but it's not as convenient as it could be.

Basic improvement

The most basic parsing needed to make things simpler for plugin code is to split the value on , into an actual list, i.e. the result above would become:

>>> i.CLIENTTAGDENY
['typing', 'draft/foobar']

All tags denied:

>>> i.CLIENTTAGDENY
['*']

Most tags denied, with exceptions:

>>> i.CLIENTTAGDENY
['*', '-typing', '-draft/foobar']

That would simplify checking whether:

Implementation considerations

An empty value is allowed, but servers are recommended to omit the CLIENTTAGDENY token entirely when empty.

With Sopel's current ISupport behavior, an empty token and an omitted token are not the same, and plugins would need to check if 'CLIENTTAGDENY' in bot.isupport in conjunction with the sample conditions I wrote above (or use bot.isupport.get('CLIENTTAGDENY', []) to ensure they will not accidentally try to check if a tag name is in None).

Further ideas

A method that takes just a tag name and distills all of the checks described above down to a boolean (e.g. client_tag_is_denied(tag_name: str) -> bool) could be a thing, too. I just don't have a solid idea yet where such a method would live in the bot's API structure.

Inspired by a recent patch submitted to irc-framework.

Neustradamus commented 8 months ago

@dgw: To follow this ticket :)