Skip to content

Commit

Permalink
Verify Extension update
Browse files Browse the repository at this point in the history
  • Loading branch information
GitGinocchio committed Dec 8, 2024
1 parent 5f7a4bd commit 1b571b1
Show file tree
Hide file tree
Showing 5 changed files with 198 additions and 79 deletions.
25 changes: 20 additions & 5 deletions notes.txt
Original file line number Diff line number Diff line change
Expand Up @@ -37,18 +37,33 @@ https://apidocs.cheapshark.com/
https://www.freetogame.com/api-doc
https://www.gamerpower.com/api-read

Ignoring exception in command <nextcord.application_command.MessageApplicationCommand object at 0x7c71c08f3cb0>:
Traceback (most recent call last):
File "/home/container/.local/lib/python3.12/site-packages/nextcord/application_command.py", line 918, in invoke_callback_with_hooks
await self(interaction, *args, **kwargs)
File "/home/container/src/commands/ai/Summarizer.py", line 73, in summarize_message
await interaction.response.send_message(content='Fill out the translation form:', view=view,ephemeral=True)
File "/home/container/.local/lib/python3.12/site-packages/nextcord/interactions.py", line 896, in send_message
await adapter.create_interaction_response(
File "/home/container/.local/lib/python3.12/site-packages/nextcord/webhook/async_.py", line 197, in request
raise HTTPException(response, data)
nextcord.errors.HTTPException: 400 Bad Request (error code: 50035): Invalid Form Body
In data.components.0.components.0: Value of field "type" must be one of (2, 3, 5, 6, 7, 8).

The above exception was the direct cause of the following exception:

nextcord.errors.ApplicationInvokeError: Command raised an exception: HTTPException: 400 Bad Request (error code: 50035): Invalid Form Body
In data.components.0.components.0: Value of field "type" must be one of (2, 3, 5, 6, 7, 8).

✔ Creare un comando per visualizzare le estensioni installate, attive e disattivate

- Spiegare il perche' bisogna fare la verifica con il bot...
- Mostrare piu' dettagli relativi alle estensioni, per esempio quando sono state configurate e da chi...
- ! E' inutile limitare manualmente dove il comando puo' essere usato o da chi..., e' una cosa che esiste gia' all'interno di discord (non in tutti i casi)


- !!! Per il setup delle estensioni utilizzare il comando univoco ma per ogni estensione ritornare all'utente una view o una modal diversa in base al comando triggerato...
- !! Forse sarebbe meglio togliere ephemeral nelle view e negli embed dei setup
e fare un bottone "abort" solo che devo utilizzare view.interaction_check
per controllare chi sta interagendo
✔ !!! Per il setup delle estensioni utilizzare il comando univoco ma per ogni estensione ritornare all'utente una view o una modal diversa in base al comando triggerato...
- ! Rendere il datetime format univoco per tutte le voci del database e modificabile tramite config.json
- !! Aggiungere un timeout alla generazione dei canali per evitare spam di canali vocali temporanei
- Risolvere l'errore che da il database se non e' presente una colonna che dovrebbe essere creata
- !!! Directory refactoring
!!! Directory refactoring
94 changes: 85 additions & 9 deletions src/commands/manager/ExtensionsUi.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,28 @@
button \

from nextcord import \
Forbidden, \
HTTPException, \
TextChannel, \
PermissionOverwrite, \
Permissions, \
ChannelType, \
SelectOption, \
ButtonStyle, \
Interaction, \
Embed, \
Guild, \
Role, \
Colour
from nextcord.abc import GuildChannel

from nextcord.ext import commands

from typing import Callable

from ..verify.VerificationUis import VerificationTypes
from ..verify.VerificationUis import \
VerificationTypes, \
StartVerificationUI

class ExtensionUi(Embed, View):
def __init__(self, bot : commands.Bot, guild : Guild, extension : str, submit_callback : Callable[[Interaction], None], timeout : int = 120):
Expand Down Expand Up @@ -138,36 +147,103 @@ class VerifyUi(ExtensionUi):
def __init__(self, bot : commands.Bot, guild : Guild, extension : str):
ExtensionUi.__init__(self, bot, guild, extension, self.on_submit)
self.description = f'{super().description}, this extension allows you to add a verification level of the account of users who enter within this server'
self.config = { "modes" : [], 'verified_role' : None}
self.config = { "modes" : [], 'verify_channel' : None, 'verify_message' : None, 'verified_role' : None}

self.add_field(
name="1. Verified Role",
value="Choose the role that users who have verified their accounts will receive.",
name="1. Verification Channel",
value="Choose the text channel where verification messages will be sent\n(no choice=create one)",
inline=False
)

self.add_field(
name="2. Allowed verification modes",
value="Select which verification modes you want to make enabled.\n(Each person can choose from one of these modes)",
name="2. Verified Role",
value="Choose the role that will be given to users who verify\n(no choice=create one)",
inline=False
)

@role_select(placeholder="1. Verified Role", min_values=1, row=1)
self.add_field(
name="3. Allowed verification modes",
value="Select which verification modes you want to enable.\n(Each member can choose from one of these modes to verify)",
inline=False
)

@channel_select(placeholder="1. Verification Channel",channel_types=[ChannelType.text], min_values=0, row=1)
async def verify_channel(self, select: ChannelSelect, interaction : Interaction):
self.config['verify_channel'] = (select.values[0].id if len(select.values) > 0 else None)

@role_select(placeholder="2. Verified Role", min_values=0, row=2)
async def verified_role(self, select: RoleSelect, interaction : Interaction):
self.config['verified_role'] = (select.values[0].id if len(select.values) > 0 else None)

@string_select(placeholder="2. Allowed verification modes",min_values=1, max_values=len(modes), options=modes, row=3)
@string_select(placeholder="3. Allowed verification modes",min_values=1, max_values=len(modes), options=modes, row=3)
async def verification_modes(self, select: StringSelect, interaction : Interaction):
self.config['modes'] = select.values

async def setup_verified_role(self, role : Role | None = None):
if role == None:
role = await self.guild.create_role(
name=f"Verified by {self.bot.user.name}",
colour=Colour.green(),
permissions=Permissions(view_channel=True),
reason="GGsBot:Verify"
)
else:
role = await role.edit(permissions=Permissions(view_channel=True), reason="GGsBot:Verify")
return role

async def setup_verify_channel(self, verified_role : Role, verify_channel : TextChannel | None = None):
overwrites = {
self.guild.default_role: PermissionOverwrite(view_channel=True,read_message_history=True),
verified_role: PermissionOverwrite(view_channel=False)
}

if verify_channel == None:
channel = await self.guild.create_text_channel(
name=f"verify",
reason="GGsBot:Verify",
position=0,
overwrites=overwrites
)
else:
channel = await verify_channel.edit(overwrites=overwrites, reason="GGsBot:Verify")
return channel

async def ensure_everyone_permissions(self):
await self.guild.default_role.edit(
reason="GGsBot:Verify",
permissions=Permissions.none()
)

async def send_verification_message(self, channel : TextChannel):
ui = StartVerificationUI(self.bot)
message = await channel.send(embed=ui, view=ui)
self.config['verify_message'] = message.id

async def on_submit(self, interaction : Interaction):
try:
assert self.config.get('verified_role') is not None, "You must choose one verified role!"
assert len(self.config.get('modes')), "You must choose at least one verification mode!"

await self.ensure_everyone_permissions()

verified_role = (self.guild.get_role(verified_role_id) if (verified_role_id:=self.config.get('verified_role')) else None)
verify_channel = (self.guild.get_channel(verify_channel_id) if (verify_channel_id:=self.config.get('verify_channel')) else None)

verified_role = await self.setup_verified_role(verified_role)
verify_channel = await self.setup_verify_channel(verified_role, verify_channel)

self.config['verify_channel'] = verify_channel.id
self.config['verified_role'] = verified_role.id

await self.send_verification_message(verify_channel)
except AssertionError as e:
await interaction.response.send_message(e, ephemeral=True, delete_after=5)
except Forbidden as e:
await interaction.response.send_message(e, ephemeral=True, delete_after=5)
except Exception as e:
print(e)
else:
self.stop()
await interaction.response.send_message(f"Verification channel {verify_channel.jump_url} and the role {verified_role.mention} created successfully!", ephemeral=True)

class StaffUi(ExtensionUi):
def __init__(self, bot : commands.Bot, guild : Guild, extension : str):
Expand Down
75 changes: 75 additions & 0 deletions src/commands/verify/VerificationUis.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
from nextcord.ext import commands
from nextcord import \
WebhookMessage, \
SelectOption, \
Interaction, \
ButtonStyle, \
TextInputStyle, \
Expand All @@ -14,19 +16,24 @@
HTTPException, \
Colour
from nextcord.ui import \
StringSelect, \
Modal, \
View, \
TextInput, \
Button, \
string_select, \
button
from datetime import datetime, timezone
from typing import Callable
from enum import StrEnum
import hashlib
import random

from utils.exceptions import ExtensionException
from utils.commons import Extensions
from utils.terminal import getlogger
from utils.commons import asyncget
from utils.db import Database

logger = getlogger()

Expand All @@ -39,6 +46,72 @@ class VerificationStatus(StrEnum):
NOT_VERIFIED = "NOT_VERIFIED"
VERIFIED = "VERIFIED"

class StartVerificationUI(Embed, View):
modes = [SelectOption(label=type.value.capitalize(), value=type.value) for type in VerificationTypes]
def __init__(self, bot : commands.Bot):
View.__init__(self, timeout=None)
Embed.__init__(self)
self.description = "Select the verification mode you want to use to verify yourself (optional) and then click **Start Verification** to begin."
self.uis : dict[VerificationTypes, VerificationUI] = {
VerificationTypes.BUTTON : ButtonVerificationUi,
VerificationTypes.QUESTION : QuestionVerificationUi
}
self.colour = Colour.green()
self.db = Database()
self.bot = bot

self.mode : VerificationTypes | None = None

self.set_author(name=bot.user.name, icon_url=bot.user.avatar.url)
self.set_footer(text=f"Official verification message sent by {bot.user.name}", icon_url=bot.user.avatar.url)

@string_select(placeholder="Select verification mode",custom_id='GGsBot:Verify::SelectMode', min_values=0, max_values=1, options=modes)
async def select_mode_callback(self, select : StringSelect, interaction : Interaction):
self.mode = select.values[0] if len(select.values) > 0 else None

@button(label="Start Verification", style=ButtonStyle.primary, custom_id='GGsBot:Verify::StartVerification')
async def start_verification(self, button : Button, interaction : Interaction):
message = None
try:
await interaction.response.defer(ephemeral=True)

async with self.db:
config, enabled = await self.db.getExtensionConfig(interaction.guild, Extensions.VERIFY)
assert enabled, "Verification is not enabled for this server"

if not self.mode:
self.mode = random.choice(config['modes'])
else:
assert self.mode in config['modes'], f"This server does not allow verification with this method!"

ui_type = self.uis.get(VerificationTypes(self.mode))

if ui_type is not None:
verified_role_id = config['verified_role']

verified_role = interaction.guild.get_role(verified_role_id)

ui : VerificationUI = ui_type(self.bot, verified_role)
await ui.async_init()

message = await interaction.followup.send(embed=ui, view=ui, wait=True, ephemeral=True)
assert not await ui.wait(), f'The verification process has expired'

except AssertionError as e:
if message: await message.delete()
await interaction.followup.send(e, ephemeral=True)
except ExtensionException as e:
if message: await message.delete()
await interaction.followup.send(embed=e.asEmbed(), ephemeral=True)
else:
if ui.status == VerificationStatus.ALREADY_VERIFIED:
await message.edit('You have already been verified!', view=None, embed=None, delete_after=5)
elif ui.status == VerificationStatus.NOT_VERIFIED:
await message.edit('Verification failed!', view=None, embed=None, delete_after=5)
else:
await message.edit(f'Verification completed successfully!', view=None, embed=None, delete_after=5)


class VerificationUI(Embed, View):
def __init__(self,
bot : commands.Bot,
Expand All @@ -58,6 +131,8 @@ def status(self): return self._status
@status.setter
def status(self, value : VerificationStatus): self._status = value

async def async_init(self): pass

class ButtonVerificationUi(VerificationUI):
def __init__(self,
bot : commands.Bot,
Expand Down
74 changes: 13 additions & 61 deletions src/commands/verify/Verify.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from nextcord.ext import commands
from nextcord.ext.commands import Bot, Cog
from nextcord import \
WebhookMessage, \
slash_command, \
Expand All @@ -14,73 +14,25 @@
from utils.db import Database
from utils.commons import Extensions
from utils.exceptions import ExtensionException
from .VerificationUis import *
from .VerificationUis import StartVerificationUI

permissions = Permissions(
administrator=True
)

class Verify(commands.Cog):
def __init__(self, bot : commands.Bot):
commands.Cog.__init__(self)
class Verify(Cog):
def __init__(self, bot : Bot):
Cog.__init__(self)
self.db = Database()
self.bot = bot
self.persistent_views_added = False

self.modes : dict[VerificationTypes, VerificationUI] = {
VerificationTypes.BUTTON : ButtonVerificationUi,
VerificationTypes.QUESTION : QuestionVerificationUi
}
@Cog.listener()
async def on_ready(self):
if not self.persistent_views_added:
view = StartVerificationUI(self.bot)
self.bot.add_view(view)
self.persistent_views_added = True

@slash_command(name="verify", description="Set of verifications commands", dm_permission=False)
async def verify(self,
interaction : Interaction,
mode : str | None = SlashOption(description="Choose verification mode", choices=VerificationTypes, required=False, default=None)
):
try:
message : WebhookMessage = None
await interaction.response.defer(ephemeral=True)

async with self.db:
config, enabled = await self.db.getExtensionConfig(interaction.guild, Extensions.VERIFY)
assert enabled, "Extension is not enabled"

verified_role = interaction.guild.get_role(config['verified_role'])

if mode:
assert mode in config['modes'], f'Mode {mode} is not a valid verification mode for this server'
else:
mode = random.choice(config['modes'])

ui_type : VerificationUI = self.modes.get(VerificationTypes(mode), None)

ui : VerificationUI = ui_type(
bot=self.bot,
verified=verified_role,
)

if ui_type == QuestionVerificationUi:
await ui.async_init()

message = await interaction.followup.send(embed=ui, view=ui, wait=True)
assert not await ui.wait(), f'The verification process has expired'

except AssertionError as e:
if message:
await message.edit(e, view=None, embed=None)
else:
await interaction.followup.send(e, ephemeral=True)
except ExtensionException as e:
if message:
await message.edit(content=None, embed=e.asEmbed(), view=None)
else:
await interaction.followup.send(embed=e.asEmbed(), ephemeral=True)
else:
if ui.status == VerificationStatus.ALREADY_VERIFIED:
await message.edit('You have already been verified!', view=None, embed=None, delete_after=5)
elif ui.status == VerificationStatus.NOT_VERIFIED:
await message.edit('Verification failed!', view=None, embed=None, delete_after=5)
else:
await message.edit(f'Verification completed successfully!', view=None, embed=None, delete_after=5)

def setup(bot : commands.Bot):
def setup(bot : Bot):
bot.add_cog(Verify(bot))
Loading

0 comments on commit 1b571b1

Please sign in to comment.