aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Kieran Siek <[email protected]>2021-06-05 17:06:19 +0800
committerGravatar GitHub <[email protected]>2021-06-05 17:06:19 +0800
commit92102c5b0b3d59d0838b059feef5e354dd22697b (patch)
treeefeaeeb81fd2ddce512da7a118820442059401ed
parentMerge pull request #1609 from bast0006/bast0006-infraction-scheduler-fix (diff)
parentMerge branch 'main' into voice_ver_dm (diff)
Merge pull request #1587 from RohanJnr/voice_ver_dm
Prioritize DM over channel message for voice verification ping.
-rw-r--r--bot/exts/moderation/voice_gate.py41
1 files changed, 29 insertions, 12 deletions
diff --git a/bot/exts/moderation/voice_gate.py b/bot/exts/moderation/voice_gate.py
index 0cbce6a51..94b23a344 100644
--- a/bot/exts/moderation/voice_gate.py
+++ b/bot/exts/moderation/voice_gate.py
@@ -8,6 +8,7 @@ from async_rediscache import RedisCache
from discord import Colour, Member, VoiceState
from discord.ext.commands import Cog, Context, command
+
from bot.api import ResponseCodeError
from bot.bot import Bot
from bot.constants import Channels, Event, MODERATION_ROLES, Roles, VoiceGate as GateConf
@@ -40,6 +41,12 @@ VOICE_PING = (
"If you don't yet qualify, you'll be told why!"
)
+VOICE_PING_DM = (
+ "Wondering why you can't talk in the voice channels? "
+ "Use the `!voiceverify` command in {channel_mention} to verify. "
+ "If you don't yet qualify, you'll be told why!"
+)
+
class VoiceGate(Cog):
"""Voice channels verification management."""
@@ -75,35 +82,41 @@ class VoiceGate(Cog):
log.trace(f"Voice gate reminder message for user {member_id} was already removed")
@redis_cache.atomic_transaction
- async def _ping_newcomer(self, member: discord.Member) -> bool:
+ async def _ping_newcomer(self, member: discord.Member) -> tuple:
"""
See if `member` should be sent a voice verification notification, and send it if so.
- Returns False if the notification was not sent. This happens when:
+ Returns (False, None) if the notification was not sent. This happens when:
* The `member` has already received the notification
* The `member` is already voice-verified
- Otherwise, the notification message ID is stored in `redis_cache` and True is returned.
+ Otherwise, the notification message ID is stored in `redis_cache` and return (True, channel).
+ channel is either [discord.TextChannel, discord.DMChannel].
"""
if await self.redis_cache.contains(member.id):
log.trace("User already in cache. Ignore.")
- return False
+ return False, None
log.trace("User not in cache and is in a voice channel.")
verified = any(Roles.voice_verified == role.id for role in member.roles)
if verified:
log.trace("User is verified, add to the cache and ignore.")
await self.redis_cache.set(member.id, NO_MSG)
- return False
+ return False, None
log.trace("User is unverified. Send ping.")
+
await self.bot.wait_until_guild_available()
voice_verification_channel = self.bot.get_channel(Channels.voice_gate)
- message = await voice_verification_channel.send(f"Hello, {member.mention}! {VOICE_PING}")
- await self.redis_cache.set(member.id, message.id)
+ try:
+ message = await member.send(VOICE_PING_DM.format(channel_mention=voice_verification_channel.mention))
+ except discord.Forbidden:
+ log.trace("DM failed for Voice ping message. Sending in channel.")
+ message = await voice_verification_channel.send(f"Hello, {member.mention}! {VOICE_PING}")
- return True
+ await self.redis_cache.set(member.id, message.id)
+ return True, message.channel
@command(aliases=('voiceverify',))
@has_no_roles(Roles.voice_verified)
@@ -144,8 +157,12 @@ class VoiceGate(Cog):
color=Colour.red()
)
log.warning(f"Got response code {e.status} while trying to get {ctx.author.id} Metricity data.")
+ try:
+ await ctx.author.send(embed=embed)
+ except discord.Forbidden:
+ log.info("Could not send user DM. Sending in voice-verify channel and scheduling delete.")
+ await ctx.send(embed=embed)
- await ctx.author.send(embed=embed)
return
checks = {
@@ -239,11 +256,11 @@ class VoiceGate(Cog):
# To avoid race conditions, checking if the user should receive a notification
# and sending it if appropriate is delegated to an atomic helper
- notification_sent = await self._ping_newcomer(member)
+ notification_sent, message_channel = await self._ping_newcomer(member)
- # Schedule the notification to be deleted after the configured delay, which is
+ # Schedule the channel ping notification to be deleted after the configured delay, which is
# again delegated to an atomic helper
- if notification_sent:
+ if notification_sent and isinstance(message_channel, discord.TextChannel):
await asyncio.sleep(GateConf.voice_ping_delete_delay)
await self._delete_ping(member.id)