Skip to content
This repository was archived by the owner on Feb 7, 2026. It is now read-only.

Commit 1c8c994

Browse files
committed
Add server member verification system
1 parent 56765f6 commit 1c8c994

3 files changed

Lines changed: 112 additions & 1 deletion

File tree

cogs/serverconfig.py

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# Imports
22
import discord
3+
import random
4+
import json
35
from discord import option, ApplicationContext
46
from discord.commands import SlashCommandGroup
57
from discord.ext import commands
@@ -12,6 +14,10 @@
1214
class ServerConfig(commands.Cog):
1315
def __init__(self, bot):
1416
self.bot = bot
17+
18+
# Load Verification Database
19+
with open("database/serververification.json", 'r', encoding="utf-8") as f:
20+
self.verification_db: dict = json.load(f)
1521

1622
serverconfig_cmds = SlashCommandGroup(name="serverconfig", description="Commands related to server customization and configuration.")
1723

@@ -65,6 +71,98 @@ async def autorole(self, ctx: ApplicationContext, channel: discord.TextChannel =
6571
)
6672
await ctx.respond(embed=localembed)
6773

74+
# Server Member Verification System
75+
@serverconfig_cmds.command(
76+
name="enable_verification",
77+
description="Enable new member verification for this server."
78+
)
79+
@option(name="verified_role", description="The role to provide to all verified members.", type=discord.Role)
80+
async def enable_verification(self, ctx: ApplicationContext, verified_role: discord.Role):
81+
"""Enable new user verification for this server."""
82+
if not ctx.author.guild_permissions.administrator:
83+
return await ctx.respond("You can't use this command! You need the `Administrator` permission to run this.", ephemeral=True)
84+
serverconf.set_verification_role(ctx.guild.id, verified_role.id)
85+
localembed = discord.Embed(
86+
title=f":white_check_mark: Server Member Verification successfully enabled for **{ctx.guild.name}**!",
87+
description=f"From now onwards, all new members will have to verify with `/verify` command, and will receive the {verified_role.mention} once verified.",
88+
color=discord.Color.green()
89+
)
90+
await ctx.respond(embed=localembed)
91+
92+
@serverconfig_cmds.command(
93+
name="disable_verification",
94+
description="Disable new member verification for this server."
95+
)
96+
async def disable_verification(self, ctx: ApplicationContext):
97+
"""Disable new member verification for this server."""
98+
if not ctx.author.guild_permissions.administrator:
99+
return await ctx.respond("You can't use this command! You need the `Administrator` permission to run this.", ephemeral=True)
100+
serverconf.set_verification_role(ctx.guild.id, None)
101+
localembed = discord.Embed(
102+
title=f":white_check_mark: Server Member Verification successfully disabled for **{ctx.guild.name}**",
103+
description=f"New members now won't have to verify in the server.",
104+
color=discord.Color.green()
105+
)
106+
await ctx.respond(embed=localembed)
107+
108+
@commands.slash_command(
109+
name="start_verification",
110+
description="Start your verification process in this server."
111+
)
112+
@commands.guild_only()
113+
async def start_verification(self, ctx: ApplicationContext):
114+
"""Start your verification process in this server."""
115+
verification_role = serverconf.fetch_verification_role(ctx.guild.id)
116+
if verification_role is None:
117+
return await ctx.respond(":warning: Verification system is disabled for this server!", ephemeral=True)
118+
if ctx.author.get_role(verification_role) is not None:
119+
return await ctx.respond(":warning: You are already verified in this server!", ephemeral=True)
120+
121+
# Construct verification data
122+
verify_code = random.randint(100000, 999999)
123+
if str(ctx.author.id) not in self.verification_db:
124+
self.verification_db[str(ctx.author.id)] = {}
125+
126+
for code in self.verification_db[str(ctx.author.id)]:
127+
if self.verification_db[str(ctx.author.id)][str(code)]["guild_id"] == ctx.guild.id:
128+
return await ctx.respond("Your verification process is already ongoing in this server!", ephemeral=True)
129+
130+
self.verification_db[str(ctx.author.id)][str(verify_code)] = {"guild_id": ctx.guild.id}
131+
with open("database/serververification.json", 'w+', encoding="utf-8") as f:
132+
json.dump(self.verification_db, f, indent=4)
133+
134+
localembed = discord.Embed(
135+
title=f"Verification for {ctx.author.name} in {ctx.guild.name} has started",
136+
description=f"Your one-time verification code is `{verify_code}`. **DO NOT share this code with anyone!**\n\nGo to isobot's DMs, and run the `/verify` command entering your verification code.",
137+
color=discord.Color.orange()
138+
)
139+
await ctx.respond(embed=localembed, ephemeral=True)
140+
141+
@commands.slash_command(
142+
name="verify",
143+
description="Enter your one-time verification code to verify membership in a server. (DM-ONLY)"
144+
)
145+
@commands.dm_only()
146+
@option(name="verification_code", description="Your one-time verification code. (6-digit number)", type=int)
147+
async def verify(self, ctx: ApplicationContext, verification_code: int):
148+
"""Enter your one-time verification code to verify membership in a server."""
149+
if str(ctx.author.id) not in self.verification_db.keys():
150+
return await ctx.respond("You are not pending verification in any servers.", ephemeral=True)
151+
if str(verification_code) not in self.verification_db[str(ctx.author.id)].keys():
152+
return await ctx.respond(":x: This verification code is invalid. Please double-check and try a different code!", ephemeral=True)
153+
154+
verification_role_id = serverconf.fetch_verification_role(self.verification_db[str(ctx.author.id)][str(verification_code)]["guild_id"])
155+
vcode_guild: discord.Guild = self.bot.get_guild(self.verification_db[str(ctx.author.id)][str(verification_code)]["guild_id"])
156+
verification_role = discord.Guild.get_role(vcode_guild, verification_role_id)
157+
server_context_user: discord.Member = vcode_guild.get_member(ctx.author.id)
158+
await server_context_user.add_roles(verification_role, reason="Member has been successfully verified in server.")
159+
160+
del self.verification_db[str(ctx.author.id)][str(verification_code)]
161+
with open("database/serververification.json", 'w+', encoding="utf-8") as f:
162+
json.dump(self.verification_db, f, indent=4)
163+
164+
return await ctx.respond(f"You have been successfully verified in **{vcode_guild.name}**!")
165+
68166
def setup(bot):
69167
bot.add_cog(ServerConfig(bot))
70168

framework/isobot/db/serverconfig.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ def generate(self, server_id: int) -> int:
3333
"channel": None,
3434
"message": None
3535
},
36-
"level_up_override_channel": None
36+
"level_up_override_channel": None,
37+
"verification_role": None
3738
}
3839
self.save(serverconf)
3940
return 0
@@ -58,6 +59,10 @@ def fetch_goodbye_message(self, server_id: int) -> dict:
5859
def fetch_levelup_override_channel(self, server_id: int) -> str:
5960
"""Fetches the level-up override channel for the specified guild. Returns `None` if not set."""
6061
return self.fetch_raw(server_id)["level_up_override_channel"]
62+
63+
def fetch_verification_role(self, server_id: int) -> str:
64+
"""Fetches the verified member role for the specified guild. Returns `None` if server verification system is disabled."""
65+
return self.fetch_raw(server_id)["verification_role"]
6166

6267
def set_autorole(self, server_id: int, role_id: int) -> int:
6368
"""Sets a role id to use as autorole for the specified guild. Returns `0` if successful."""
@@ -84,3 +89,9 @@ def set_levelup_override_channel(self, server_id: int, channel_id: int) -> int:
8489
serverconf = self.load()
8590
serverconf[str(server_id)]["level_up_override_channel"] = channel_id
8691
self.save(serverconf)
92+
93+
def set_verification_role(self, server_id: int, role_id: int) -> int:
94+
"""Sets a verified member role id for the specified guild for the specified guild, and enables server member verification. Returns `0` if successful."""
95+
serverconf = self.load()
96+
serverconf[str(server_id)]["verification_role"] = role_id
97+
self.save(serverconf)

main.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ def initial_setup():
4848
"items",
4949
"levels",
5050
"serverconfig",
51+
"serververification",
5152
"warnings",
5253
"presence",
5354
"user_data",
@@ -285,6 +286,7 @@ async def on_application_command_error(ctx: ApplicationContext, error: discord.D
285286
elif isinstance(error, commands.BotMissingPermissions): await ctx.respond(":x: I don\'t have the required permissions to use this.\nIf you think this is a mistake, please go to server settings and fix isobot's role permissions.")
286287
elif isinstance(error, commands.BadBoolArgument): await ctx.respond(":x: Invalid true/false argument.", ephemeral=True)
287288
elif isinstance(error, commands.NoPrivateMessage): await ctx.respond(":x: You can only use this command in a server!", ephemeral=True)
289+
elif isinstance(error, commands.PrivateMessageOnly): await ctx.respond(":x: You can only use this command in isobot's DMs!", ephemeral=True)
288290
else:
289291
logger.error(f"Command failure: An uncaught error occured while running the command.\n >>> {error}", module="main/Client")
290292
await ctx.respond(f"An uncaught error occured while running the command. (don't worry, developers will fix this soon)\n```\n{error}\n```")

0 commit comments

Comments
 (0)