Skip to content

Commit

Permalink
Merge pull request #116 from Freelancers-Union/a3_npe
Browse files Browse the repository at this point in the history
A3 NPE
  • Loading branch information
Karlish-git committed Mar 22, 2024
2 parents 90eabb9 + 3b2009f commit 9b9ef7f
Show file tree
Hide file tree
Showing 5 changed files with 252 additions and 9 deletions.
2 changes: 1 addition & 1 deletion src/commands/squad_markup.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ class Ps2SquadMarkup(commands.Cog):
Class cog for ps2 squad markup help message.
"""

@commands.slash_command(dm_permission=True)
@commands.slash_command(dm_permission=True, help="Print the markup for colourful squad names.")
async def squad(self, inter):
pass

Expand Down
2 changes: 2 additions & 0 deletions src/database/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import os
from typing import Type
from beanie import init_beanie, Document
import beanie
from motor.motor_asyncio import AsyncIOMotorClient


Expand Down Expand Up @@ -40,6 +41,7 @@ async def init_database(mongo_uri: str, db_name: str):
db_name:
The name of the database to connect to.
"""

db_list = get_all_documents()
client = AsyncIOMotorClient(str(mongo_uri))
await init_beanie(
Expand Down
2 changes: 2 additions & 0 deletions src/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ async def on_connect():
# everything below here will only run on the first connect

try:

logging.info("Connected to Discord. Initializing Database.")
await init_database(get_mongo_uri(), "FUBot")
except Exception as e:
Expand All @@ -72,6 +73,7 @@ async def on_connect():
# bot.load_extension("loggers.arma_server_logger")
bot.load_extension("send_intro")
bot.load_extension("helpers.sync_commands")
bot.load_extension("services.a3_onboarding")


@bot.event
Expand Down
15 changes: 7 additions & 8 deletions src/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
requests==2.27.1
auraxium==0.2.2
requests==2.31.0
auraxium==0.2.4
asyncio==3.4.3
disnake==2.7.*
emoji==1.7.0
disnake==2.9.1
emoji==2.10.1
aiocron==1.8
pymongo==4.2.0
SteamQuery==1.0.2
beanie==1.19.1
pydantic==1.10.9
beanie==1.25.0
pydantic==1.10.14
aiofiles==23.2.1
asyncssh==2.14.0
asyncssh==2.14.2
240 changes: 240 additions & 0 deletions src/services/a3_onboarding.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,240 @@
import logging
from datetime import datetime

import disnake
import helpers.discord_checks as dc
from disnake.ext import commands


class OnboardA3Member(commands.Cog):
def __init__(self, bot: commands.Bot):
self.bot = bot
self.a3_role = "Arma 3"
self.a3_officer_role = "Arma Division Officer"
self.notification_channel = "arma-on-board"
self.onboarding_category = "📜-ArmA-onboarding"
self.onbarding_id = "a3onb-"
self.assign_id = "assign"
self.accepted_id = "accepted"
self.rejected_id = "rejected"

async def cog_load(self):
try:
# create the onboarding category if it doesn't exist
logging.info("Creating onboarding category and notification channel")
for guild in self.bot.guilds:
arma_officer_role = disnake.utils.get(
guild.roles, name=self.a3_officer_role
)
if not arma_officer_role:
logging.warning(
f"Role {self.a3_officer_role} not found in {guild.name}"
)
continue
if not disnake.utils.get(
guild.categories, name=self.onboarding_category
):
overwrites = {
arma_officer_role: disnake.PermissionOverwrite(
view_channel=True,
send_messages=True,
manage_channels=True,
manage_messages=True,
read_message_history=True,
),
guild.default_role: disnake.PermissionOverwrite(
view_channel=False
),
}
await guild.create_category(
self.onboarding_category,
overwrites=overwrites, # pyright: ignore
)
if not disnake.utils.get(
guild.channels, name=self.notification_channel
):
category = disnake.utils.get(
guild.categories, name=self.onboarding_category
)
await guild.create_text_channel(
name=self.notification_channel, category=category
)
except Exception as e:
logging.exception(
"Error creating onboarding category and notification channel", e
)

@commands.Cog.listener(name="on_member_update")
async def notify_officers(self, old: disnake.Member, new: disnake.Member):
"""
Send message to officers that new member has selected a3 role
"""
if not (
disnake.utils.get(new.roles, name=self.a3_role)
and not disnake.utils.get(old.roles, name=self.a3_role)
):
return

try:
member_request = disnake.Embed(
title=f"New ArmA Player - {new.name}",
description=f"Contact newly enlisted {new.mention} to get them on battle field! :military_helmet:",
colour=disnake.Colour(14812691),
)

channel = disnake.utils.get(
new.guild.channels, name=self.notification_channel
)
if channel is not None and channel.type == disnake.ChannelType.text:
await channel.send(
embed=member_request,
components=[
disnake.ui.Button(
label="Assign to me",
style=disnake.ButtonStyle.success,
custom_id=self.onbarding_id
+ self.assign_id
+ "-"
+ str(new.id),
)
],
)
except Exception as e:
logging.exception("Error notifying officers", e)

@commands.Cog.listener("on_button_click")
async def onboard_listener(self, inter: disnake.MessageInteraction):
"""
Onboarding listener
Handles the onboarding task message in Officer chat.
Args:
inter (disnake.MessageInteraction): The interaction
Returns:
None
"""
a3_onbarding_id = "a3onb-"
try:
if not (inter.component.custom_id and inter.guild):
return
if not inter.component.custom_id.startswith(a3_onbarding_id):
logging.info(
f"New member assigned to officer: {inter.component.custom_id}"
)
logging.info(f"Interacted with {inter.component.custom_id}")

split = inter.component.custom_id.split("-")
action = split[1]
member_id = int(split[2])

member_id = int(inter.component.custom_id.split("-")[-1])
member = inter.guild.get_member(member_id)
if member is None:
embed = inter.message.embeds[0]
embed.description = (
"Member not found"
if not embed.description
else embed.description + "\nMember not found"
)
await inter.response.edit_message(embed=embed)
return

onbaoarding_channel_name = f"onboarding-{str(member.name).lower()}"

# Create a private channel for the new member and the officer
if action == self.assign_id:
overwrites = {
inter.guild.default_role: disnake.PermissionOverwrite(
view_channel=False
),
member: disnake.PermissionOverwrite(
view_channel=True, send_messages=True, read_message_history=True
),
}

# Create the channel
category = disnake.utils.get(
inter.guild.categories, name=self.onboarding_category
)
onboarding_channel = await inter.guild.create_text_channel(
name=onbaoarding_channel_name,
overwrites=overwrites,
category=category,
)
for user in [member, inter.author]:
await onboarding_channel.set_permissions(
target=user,
view_channel=True,
send_messages=True,
read_message_history=True,
)

# Update the embed to show the new member has been assigned to an officer
embed = inter.message.embeds[0]
embed.add_field(
name="Assigned To:", value=f"{inter.author.mention}", inline=False
).set_footer(text=f"Communication initiated: {datetime.utcnow()} UTC")
embed.add_field(
name="Onboarding Channel",
value=f"{onboarding_channel.mention}",
inline=False,
)
embed.colour = disnake.Colour(12757760)
await inter.response.edit_message(
embed=embed,
components=[
disnake.ui.Button(
label="Accepted",
style=disnake.ButtonStyle.green,
custom_id=self.onbarding_id
+ self.accepted_id
+ "-"
+ str(member.id),
),
disnake.ui.Button(
label="Rejected",
style=disnake.ButtonStyle.red,
custom_id=self.onbarding_id
+ self.rejected_id
+ "-"
+ str(member.id),
),
],
)

else:
embed = inter.message.embeds[0]
if action == self.accepted_id:
embed.description = f"{member.mention} has been onbarded"
elif action == self.rejected_id:
embed.description = f"{member.mention} has Failed onboarding"
# Update the embed to show the new member has accepted and add the member role
embed.colour = disnake.Colour(1150720)
embed.add_field(
name="Closed at:", value=f"{datetime.utcnow()} UTC", inline=False
)

onboarding_channel = await dc.get_channel(
inter, channel_name=onbaoarding_channel_name
)
if not onboarding_channel:
embed.add_field(
name="Error",
value="Onboarding channel not found. I can't delete it",
inline=False,
)
else:
await onboarding_channel.delete()

await inter.response.edit_message(embed=embed, components=None)

except Exception as e:
logging.exception(e)
await inter.send(
content=f"Something went wrong, you should check the user's roles. and give Botanists this timestamp: {datetime.now()}",
)


def setup(bot: commands.Bot):
bot.add_cog(OnboardA3Member(bot))

0 comments on commit 9b9ef7f

Please sign in to comment.