|
| 1 | +import discord |
| 2 | +import httpx |
| 3 | +from discord import app_commands |
| 4 | +from discord.ext import commands |
| 5 | +from loguru import logger |
| 6 | + |
| 7 | +from tux.utils.constants import Constants as CONST |
| 8 | + |
| 9 | + |
| 10 | +class Mail(commands.Cog): |
| 11 | + def __init__(self, bot: commands.Bot): |
| 12 | + self.bot = bot |
| 13 | + self.api_url = CONST.MAILCOW_API_URL |
| 14 | + self.headers = { |
| 15 | + "Content-Type": "application/json", |
| 16 | + "Accept": "application/json", |
| 17 | + "X-API-Key": CONST.MAILCOW_API_KEY, |
| 18 | + "Authorization": f"Bearer {CONST.MAILCOW_API_KEY}", |
| 19 | + } |
| 20 | + self.default_options = { |
| 21 | + "active": "1", |
| 22 | + "domain": "atl.tools", |
| 23 | + "password": "changeme1234!", |
| 24 | + "password2": "changeme1234!", |
| 25 | + "quota": "3072", |
| 26 | + "force_pw_update": "1", |
| 27 | + "tls_enforce_in": "0", |
| 28 | + "tls_enforce_out": "0", |
| 29 | + "tags": ["discord_member"], |
| 30 | + } |
| 31 | + |
| 32 | + mail = app_commands.Group(name="mail", description="Mail commands.") |
| 33 | + |
| 34 | + @mail.command(name="register", description="Registers a user for mail.") |
| 35 | + @app_commands.checks.has_any_role("Root", "Admin", "Mod") |
| 36 | + async def register( |
| 37 | + self, interaction: discord.Interaction, member: discord.Member, username: str |
| 38 | + ) -> None: |
| 39 | + if interaction.guild: |
| 40 | + mailbox_data = self.default_options.copy() |
| 41 | + mailbox_data["local_part"] = username |
| 42 | + mailbox_data["name"] = username |
| 43 | + # Ensure tags are copied correctly and member ID is added |
| 44 | + tags = ( |
| 45 | + self.default_options["tags"] |
| 46 | + if isinstance(self.default_options["tags"], list) |
| 47 | + else [] |
| 48 | + ) |
| 49 | + tags = tags.copy() # Ensure it's a fresh copy of the list |
| 50 | + tags.append(str(member.id)) |
| 51 | + mailbox_data["tags"] = tags |
| 52 | + |
| 53 | + api_path = "/add/mailbox" |
| 54 | + api_endpoint = self.api_url + api_path |
| 55 | + |
| 56 | + async with httpx.AsyncClient(timeout=10.0) as client: |
| 57 | + try: |
| 58 | + response = await client.post( |
| 59 | + api_endpoint, headers=self.headers, json=mailbox_data |
| 60 | + ) |
| 61 | + if response.status_code == 200: |
| 62 | + result = response.json() |
| 63 | + logger.info(f"Response JSON: {result}") |
| 64 | + |
| 65 | + # Initialize the mailbox_info as 'Unknown' |
| 66 | + mailbox_info = "Unknown" |
| 67 | + |
| 68 | + # Check the response for success or failure messages |
| 69 | + for item in result: |
| 70 | + if "msg" in item: |
| 71 | + if "mailbox_added" in item["msg"]: |
| 72 | + mailbox_info = item["msg"][1] |
| 73 | + break |
| 74 | + if "mailbox_quota_left_exceeded" in item["msg"]: |
| 75 | + await interaction.response.send_message( |
| 76 | + "Failed to register the mailbox. Quota limit exceeded.", |
| 77 | + ephemeral=True, |
| 78 | + ) |
| 79 | + return |
| 80 | + |
| 81 | + await interaction.response.send_message( |
| 82 | + f"Successfully registered {mailbox_info} for mail.", ephemeral=True |
| 83 | + ) |
| 84 | + |
| 85 | + dm_message = f""" |
| 86 | +**Your mailbox has been successfully registered!** |
| 87 | +
|
| 88 | +**Email Address**: `{mailbox_info}` |
| 89 | +**Access Mailbox**: [mail.atl.tools](https://mail.atl.tools) |
| 90 | +**Default Password**: `changeme1234!` |
| 91 | +
|
| 92 | +**Please change your password after logging in for the first time.** |
| 93 | +
|
| 94 | +After changing, you can also set up your mailbox on your mobile device or email client following the instructions provided on the mail server. Alternatively, feel free to use our webmail interface available at [mail.atl.tools/SOGo](https://mail.atl.tools/SOGo/). |
| 95 | +
|
| 96 | +If you have any questions or need assistance, please feel free to reach out to the server staff. Enjoy your new mailbox! 📬 |
| 97 | + """ |
| 98 | + |
| 99 | + try: |
| 100 | + await member.send( |
| 101 | + f"Hello {member.mention},\n{dm_message.strip()}", |
| 102 | + suppress_embeds=True, |
| 103 | + ) |
| 104 | + except discord.Forbidden: |
| 105 | + await interaction.response.send_message( |
| 106 | + f"Failed to send a DM to {member.mention}. Please enable DMs from server members.", |
| 107 | + ephemeral=True, |
| 108 | + ) |
| 109 | + |
| 110 | + elif response.status_code == 401: |
| 111 | + await interaction.response.send_message( |
| 112 | + "Unauthorized. Check your API credentials.", ephemeral=True |
| 113 | + ) |
| 114 | + else: |
| 115 | + await interaction.response.send_message( |
| 116 | + f"Failed to register {username} for mail. Status code: {response.status_code}.", |
| 117 | + ephemeral=True, |
| 118 | + ) |
| 119 | + except httpx.RequestError as exc: |
| 120 | + await interaction.response.send_message( |
| 121 | + f"An error occurred while requesting {exc.request.url!r}.", ephemeral=True |
| 122 | + ) |
| 123 | + logger.error(f"An error occurred while requesting, {exc}") |
| 124 | + else: |
| 125 | + await interaction.response.send_message( |
| 126 | + "This command can only be used in a guild (server).", ephemeral=True |
| 127 | + ) |
| 128 | + |
| 129 | + |
| 130 | +async def setup(bot: commands.Bot): |
| 131 | + await bot.add_cog(Mail(bot)) |
0 commit comments