Skip to content

Commit 512a901

Browse files
authored
Merge pull request #328 from rHomelab/feat/onboarding_role_process_cmd
2 parents 3f553ec + d20e824 commit 512a901

2 files changed

Lines changed: 79 additions & 27 deletions

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,7 @@ If any such member is found, they will be granted the onboarding role.
328328
* `[p]onboarding_role status` - Status of the cog.
329329
* `[p]onboarding_role role <role name or ID>` - Set the role to be granted to users once they complete onboarding.
330330
* `[p]onboarding_role logchannel <text channel name or ID>` - Set the channel to which onboarding events should be logged.
331+
* `[p]onboarding_role process [dry_run]` - Manually process onboarding for all eligible members in the current guild. This checks all members and assigns the onboarding role to those who have completed onboarding but don't have the role yet. Use `True` for `dry_run` to see what would happen without making changes.
331332

332333
### Penis
333334

onboarding_role/onboarding_role.py

Lines changed: 78 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -48,36 +48,19 @@ async def on_member_update(self, before: discord.Member, after: discord.Member):
4848
# Onboarding state is not changed or onboarding is not complete
4949
return
5050

51-
await self.handle_onboarding(after)
51+
await self.process_onboarding_for_member(after)
5252

5353
@commands.Cog.listener()
5454
async def on_ready(self):
5555
"""
5656
Listen for on_ready event.
57-
When event fires, add onboarded role to members in all guilds who meet the following criteria:
58-
- Not in `onboarded_users` list.
59-
- Has completed onboarding.
60-
- Does not have the onboarded role.
57+
When event fires, process onboarding for all eligible members.
6158
"""
6259
# Wait until Red is fully ready and cache is populated
6360
await self.bot.wait_until_red_ready()
6461

6562
for guild in self.bot.guilds:
66-
onboarded_role_id = await self.config.guild(guild).role()
67-
if not onboarded_role_id:
68-
# No role configured for this guild
69-
continue
70-
71-
onboarded_role = guild.get_role(onboarded_role_id)
72-
if not onboarded_role:
73-
# Role not found
74-
log.warning(f"Role ID {onboarded_role_id} not found in guild {guild.name} (ID {guild.id}).")
75-
continue
76-
77-
onboarded_users = await self.config.guild(guild).onboarded_users()
78-
for member in guild.members:
79-
if member not in onboarded_users and member.flags.completed_onboarding and onboarded_role not in member.roles:
80-
await self.handle_onboarding(member)
63+
await self.process_onboarding_for_guild(guild)
8164

8265
# Commands
8366

@@ -115,7 +98,7 @@ async def get_status(self, ctx: commands.GuildContext):
11598
embed = (
11699
discord.Embed(colour=(await ctx.embed_colour()))
117100
.add_field(name="Onboarded Role", value=onboarded_role)
118-
.add_field(name="Log Channnel", value=log_channel)
101+
.add_field(name="Log Channel", value=log_channel)
119102
.add_field(name="Onboarded User Count", value=num_onboarded_users, inline=False)
120103
)
121104

@@ -134,8 +117,12 @@ async def set_role(self, ctx: commands.GuildContext, role: discord.Role):
134117
- `[p]onboarding_role role 1253932390562590999`
135118
"""
136119
await self.config.guild(ctx.guild).role.set(role.id)
137-
log.debug(f"Onboarded role set to {role.name} (ID {role.id})")
120+
log.debug(f"Onboarded role set to '{role.name}' (ID {role.id})")
138121
await ctx.tick()
122+
await ctx.send(
123+
f"Onboarding role has been set to {role.mention}. All eligible members will be assigned this role "
124+
f"next time the bot starts, or it can be triggered now with `{ctx.prefix}onboarding_role process`."
125+
)
139126

140127
@onboarding_role.command("logchannel")
141128
async def set_log_channel(self, ctx: commands.GuildContext, channel: discord.TextChannel):
@@ -148,14 +135,78 @@ async def set_log_channel(self, ctx: commands.GuildContext, channel: discord.Tex
148135
"""
149136
if channel.permissions_for(ctx.me).send_messages and channel.permissions_for(ctx.me).embed_links:
150137
await self.config.guild(ctx.guild).log_channel.set(channel.id)
151-
log.debug(f"Log channel set to {channel.name} (ID {channel.id})")
138+
log.debug(f"Log channel set to '{channel.name}' (ID {channel.id})")
152139
await ctx.tick()
153140
else:
154141
await ctx.send(f"❌ I need the `Send Messages` and `Embed Links` permissions to send logs to {channel.mention}.")
155142

143+
@onboarding_role.command("process")
144+
async def manual_onboarding(self, ctx: commands.GuildContext, dry_run: bool = False):
145+
"""
146+
Manually process onboarding for all eligible members in this guild.
147+
148+
This will check all members in the guild and assign the onboarding role
149+
to those who have completed onboarding but don't have the role yet.
150+
151+
Args:
152+
dry_run: If True, only show what would be done without making changes.
153+
"""
154+
async with ctx.typing():
155+
processed_count = await self.process_onboarding_for_guild(ctx.guild, dry_run=dry_run)
156+
157+
if dry_run:
158+
if processed_count == 0:
159+
await ctx.send("🔍 **Dry Run**: No members would need onboarding role assignment.")
160+
elif processed_count == 1:
161+
await ctx.send("🔍 **Dry Run**: 1 member would be processed for onboarding role assignment.")
162+
else:
163+
await ctx.send(f"🔍 **Dry Run**: {processed_count} members would be processed for onboarding role assignment.")
164+
elif processed_count == 0:
165+
await ctx.send("✅ No members needed onboarding role assignment.")
166+
elif processed_count == 1:
167+
await ctx.send("✅ Processed onboarding for 1 member.")
168+
else:
169+
await ctx.send(f"✅ Processed onboarding for {processed_count} members.")
170+
156171
# Helpers
157172

158-
async def handle_onboarding(self, member: discord.Member):
173+
async def process_onboarding_for_guild(self, guild: discord.Guild, dry_run: bool = False) -> int:
174+
"""
175+
Process onboarding for members in a specific guild who meet the following criteria:
176+
- Not in `onboarded_users` list.
177+
- Has completed onboarding.
178+
- Does not have the onboarded role.
179+
180+
Args:
181+
guild: The Discord guild to process onboarding for.
182+
dry_run: If True, only count eligible members without making changes.
183+
184+
Returns:
185+
int: Number of members processed (or would be processed in dry run).
186+
"""
187+
onboarded_role_id = await self.config.guild(guild).role()
188+
if not onboarded_role_id:
189+
# No role configured for this guild
190+
return 0
191+
192+
onboarded_role = guild.get_role(onboarded_role_id)
193+
if not onboarded_role:
194+
# Role not found
195+
log.warning(f"Role ID {onboarded_role_id} not found in guild '{guild.name}' (ID {guild.id}).")
196+
return 0
197+
198+
onboarded_users = await self.config.guild(guild).onboarded_users()
199+
processed_count = 0
200+
201+
for member in guild.members:
202+
if member.id not in onboarded_users and member.flags.completed_onboarding and onboarded_role not in member.roles:
203+
if not dry_run:
204+
await self.process_onboarding_for_member(member)
205+
processed_count += 1
206+
207+
return processed_count
208+
209+
async def process_onboarding_for_member(self, member: discord.Member):
159210
"""Handle onboarding completed event"""
160211
log.debug(f"User '{member.name}' (ID {member.id}) completed onboarding")
161212
guild = member.guild
@@ -171,7 +222,7 @@ async def handle_onboarding(self, member: discord.Member):
171222
# Welcome role is not found
172223
log.warning(
173224
f"Cannot grant onboarding role to '{member.name}' (ID {member.id}): "
174-
+ f"Onboarding role set to ID {role_id} but could not found."
225+
+ f"Onboarding role set to ID {role_id} but could not be found."
175226
)
176227
return
177228

@@ -186,7 +237,7 @@ async def handle_onboarding(self, member: discord.Member):
186237

187238
await self.send_log_message(member)
188239
except discord.Forbidden:
189-
error_msg = f"Adding onboarding role to {member.name} (ID {member.id}) was forbidden."
240+
error_msg = f"Adding onboarding role to '{member.name}' (ID {member.id}) was forbidden."
190241
log.warning(error_msg)
191242
await self.send_log_message(member, error_msg)
192243

@@ -226,7 +277,7 @@ async def send_log_message(self, member: discord.Member, error_msg: str = ""):
226277
try:
227278
await log_channel.send(embed=embed)
228279
except discord.Forbidden:
229-
log.warning(f"Sending onboarding log to {log_channel.name} (ID {log_channel_id}) was forbidden.")
280+
log.warning(f"Sending onboarding log to '{log_channel.name}' (ID {log_channel_id}) was forbidden.")
230281

231282

232283
def humanise_timedelta(delta: timedelta) -> str:

0 commit comments

Comments
 (0)