Implement !tunnel command#3516
Conversation
5b4d35e to
9d2c86c
Compare
…east active off-topic channel selection)
9d2c86c to
3bf675d
Compare
|
I do have a couple of questions though, first, so currently I have made it so that only Another thing is that if I change the command method signature to use Then also, if I use the Should there be checks for whether the given channel is a DM channel or some such? Currently it just seems to treat it as incorrect channel ID (probably because it's not a Similarly, what to do about Is there a simple way to do overloads for this command? So that with one argument it's Any shortcuts/convenience functions I should use for say permission checks from the existing code base? Does this need unit or integration tests? |
jb3
left a comment
There was a problem hiding this comment.
Nice initial implementation, a few feedback comments. Will address your other comments in a second.
| for channel_id in CHANNEL_IDS: | ||
| channel = bot.get_channel(channel_id) | ||
| if channel is None: | ||
| continue | ||
|
|
||
| if not isinstance(channel, discord.TextChannel): | ||
| raise AssertionError | ||
|
|
||
| last_message = channel.last_message | ||
| if last_message is None: | ||
| continue | ||
|
|
||
| self.channel_id_to_timestamp[channel_id] = last_message.created_at.timestamp() |
There was a problem hiding this comment.
This should be done in cog load listener, not in the cog init (see other cogs for prior art)
| if ctx.guild is None: | ||
| raise AssertionError |
There was a problem hiding this comment.
Use a guild-only check here instead, also maybe worth adding a cooldown decorator as we do to prevent abuse of this feature.
| def get_least_active_channel_id(self, current_channel_id: int) -> int: | ||
| """Gets least active off-topic channel.""" | ||
| channel_id, _ = min( | ||
| [ | ||
| (channel_id, timestamp) | ||
| for channel_id, timestamp in self.channel_id_to_timestamp.items() | ||
| if channel_id != current_channel_id | ||
| ], | ||
| key=itemgetter(1), | ||
| ) | ||
| return channel_id |
There was a problem hiding this comment.
Feels cleaner to just do this:
| def get_least_active_channel_id(self, current_channel_id: int) -> int: | |
| """Gets least active off-topic channel.""" | |
| channel_id, _ = min( | |
| [ | |
| (channel_id, timestamp) | |
| for channel_id, timestamp in self.channel_id_to_timestamp.items() | |
| if channel_id != current_channel_id | |
| ], | |
| key=itemgetter(1), | |
| ) | |
| return channel_id | |
| def get_least_active_channel_id(self, current_channel_id: int) -> int: | |
| """Gets least active off-topic channel.""" | |
| return min( | |
| (channel for channel in self.channel_id_to_timestamp if channel != current_channel_id), | |
| key=self.channel_id_to_timestamp.get | |
| ) |
| if not isinstance(least_active_channel, discord.TextChannel): | ||
| raise AssertionError |
There was a problem hiding this comment.
I understand why you've got a few AssertionErrors throughout your implementation here, but this is not a pattern we have through the rest of this project and I'm not sure how I feel about implementing it just for this cog.
We have found that trying to do precise typing is almost impossible with how many updates the upstream discord.py types get as well as when new features are released to the Discord API that suddenly then start breaking assertions.
I'd rather see any genuine failures handled but otherwise do not think we should have these in the implementation.
Sounds fine — with the necessary cooldown added as mentioned so users cannot spam this in places we have less visibility.
This sounds weird, do you get the same if you try use
I wonder if using a https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.TextChannelConverter might help?
You can use a guild-only decorator to enforce this.
Same as above.
Not easily without doing most of the argument handling yourself. I was going to suggest that for this initial implementation though we ditch the source channel support. Especially since the user who did the tunneling isn't mentioned in the tunneling messages it seems ripe for abuse (e.g. someone spamming in bot commands with another source & dest). For now, let's keep things simple and just implement an optional destination channel.
You can if you want to (and if you remove the source stuff it should be easier), we do have some utilities for mocking Discord components here and it's not too hard to add new bits. |
|
Also, on the last point about abuse: can we include the user who tunneled on both the source and destination message (username is fine, doesn't need to be a mention), so that we can easily see any problems without having to look through message logs. |
Fixes #3512