Untitled
unknown
plain_text
a year ago
16 kB
6
Indexable
import discord from discord.ext import commands from discord.ui import View from jokeapi import Jokes # Import the Jokes class import asyncio from PIL import Image, ImageDraw from io import BytesIO import requests from bot_token import BOT_TOKEN # Function to create a circular image with a specified size def create_circular_image(image_url, size=(60, 60)): # Specify the desired size (width, height) response = requests.get(image_url) img = Image.open(BytesIO(response.content)).convert("RGBA") # Resize the image to the specified size using LANCZOS resampling filter img = img.resize(size, Image.LANCZOS) bigsize = (img.size[0] * 3, img.size[1] * 3) mask = Image.new('L', bigsize, 0) draw = ImageDraw.Draw(mask) draw.ellipse((0, 0) + bigsize, fill=255) mask = mask.resize(img.size, Image.LANCZOS) img.putalpha(mask) output = BytesIO() img.save(output, format="PNG") output.seek(0) return output class MyBot(commands.Bot): def __init__(self, command_prefix, intents): super().__init__(command_prefix=command_prefix, intents=intents) async def on_ready(self): # Function to execute when the bot successfully connects to Discord print(f"{self.user.name} has successfully connected to Discord.") # Sync the bot's commands when it's ready await self.sync_commands() async def on_command_error(self, ctx, error): if isinstance(error, commands.CommandNotFound): await ctx.send("That command does not exist.", ephemeral=True) else: # Handle other types of errors gracefully error_message = f"An error occurred: {type(error).__name__}: {error}" print(error_message) await ctx.send(error_message, ephemeral=True) @staticmethod def get_server_prefix(bot, message): # Static method to get the server prefix (e.g., "/") return "/" async def sync_commands(self): # Method to sync the bot's commands with Discord await self.tree.sync() print("Commands synced successfully") # Create an instance of MyBot with custom command prefix and intents bot = MyBot(command_prefix=MyBot.get_server_prefix, intents=discord.Intents.all()) class AnnouncementView(discord.ui.View): def __init__(self, bot, sender: discord.User, sender_id: int, target_channel_id: int): super().__init__() self.bot = bot # Store the bot instance self.sender = sender # Store the sender self.sender_id = sender_id self.target_channel_id = target_channel_id # Store the target channel ID self.embed = discord.Embed(color=discord.Color.blue()) # Initialize the embed with a specified color self.embed.add_field(name="Title", value="Not provided", inline=False) self.embed.add_field(name="Description", value="Not provided", inline=False) self.embed.add_field(name="Date", value="Not provided", inline=False) self.embed.title = "Announcement! 📢" self.add_item(self.title_button) self.add_item(self.description_button) self.add_item(self.date_button) self.add_item(ConfirmButton(self)) # Add the ConfirmButton def add_items(self): title_button = title_button description_button = description_button date_button = date_button confirm_button = ConfirmButton(self) self.add_item(title_button) self.add_item(description_button) self.add_item(date_button) self.add_item(confirm_button) def set_thumbnail(self, image_url): # Set the thumbnail for the embed using the sender's circular avatar circular_image = create_circular_image(image_url) self.file = discord.File(circular_image, filename="circular_avatar.png") self.embed.set_thumbnail(url="attachment://circular_avatar.png") # Function to update the embed with new title, description, and date def update_embed(self, title=None, description=None, date=None): if title: self.embed.set_field_at(0, name="Title", value=title, inline=False) if description: self.embed.set_field_at(1, name="Description", value=description, inline=False) if date: self.embed.set_field_at(2, name="Date", value=date, inline=False) async def interaction_check(self, interaction: discord.Interaction) -> bool: if interaction.user.id != self.sender_id: await interaction.response.send_message("You are not allowed to interact with this embed.", ephemeral=True) return False return True # Define a button for confirming the announcement class ConfirmButton(discord.ui.Button): def __init__(self, parent_view): super().__init__(label="Confirm", style=discord.ButtonStyle.success) self.parent_view = parent_view # Callback function to handle button click async def callback(self, interaction: discord.Interaction): # Get the target channel to send the announcement target_channel = self.parent_view.bot.get_channel(self.parent_view.target_channel_id) if target_channel is None: # Notify if the channel is invalid await interaction.response.send_message("Invalid channel ID", ephemeral=True) return # Set the thumbnail before sending the embed self.parent_view.set_thumbnail(self.parent_view.sender.avatar.url) # Send the embed to the target channel await target_channel.send(embed=self.parent_view.embed, file=self.parent_view.file) await interaction.response.send_message("Announcement sent for review!", ephemeral=True) # Define a command for creating an announcement @bot.tree.command(name="announcement", description="📌 • Create an Announcement!") async def announcement_command(interaction: discord.Interaction): try: await interaction.response.defer(ephemeral=True) # Defer the initial response to allow interaction # Initialize an empty embed embed = discord.Embed(color=discord.Color.blue()) embed.title = "Announcement! 📢" embed.add_field(name="Title", value="Not provided", inline=False) embed.add_field(name="Description", value="Not provided", inline=False) embed.add_field(name="Date", value="Not provided", inline=False) embed.set_footer(text=f"Sent by: @{interaction.user.name}") # Send the message with the initial embed and user's circular profile picture as thumbnail circular_image = create_circular_image(interaction.user.avatar.url) file = discord.File(circular_image, filename="circular_avatar.png") embed.set_thumbnail(url="attachment://circular_avatar.png") prompt_message = await interaction.followup.send(embed=embed, file=file, ephemeral=True) # Add buttons for title, description, date, and confirm title_button = discord.ui.Button(label="Enter Title", style=discord.ButtonStyle.secondary, custom_id="title_button") description_button = discord.ui.Button(label="Enter Description", style=discord.ButtonStyle.secondary, custom_id="description_button") date_button = discord.ui.Button(label="Enter Date", style=discord.ButtonStyle.secondary, custom_id="date_button") confirm_button = discord.ui.Button(label="Confirm", style=discord.ButtonStyle.success, custom_id="confirm_button") view = discord.ui.View() view.add_item(title_button) view.add_item(description_button) view.add_item(date_button) view.add_item(confirm_button) # Update the message with the view containing buttons await prompt_message.edit(view=view) while True: try: interaction = await bot.wait_for("button_click", timeout=60, check=lambda i: i.user == interaction.user) except asyncio.TimeoutError: await prompt_message.edit(content="Timed out. Please try again.", view=None) return # Handle button clicks to update the embed if interaction.component.custom_id == "title_button": title = await input_value(interaction, "Title") if title: embed.set_field_at(0, name="Title", value=title, inline=False) elif interaction.component.custom_id == "description_button": description = await input_value(interaction, "Description") if description: embed.set_field_at(1, name="Description", value=description, inline=False) elif interaction.component.custom_id == "date_button": date = await input_value(interaction, "Date (e.g., 05/19/2024)") if date: embed.set_field_at(2, name="Date", value=date, inline=False) elif interaction.component.custom_id == "confirm_button": break # Break the loop when the user confirms the announcement await interaction.response.edit_message(embed=embed, view=view) # Send the final announcement to the target channel target_channel_id = 1243960674015772772 # Specify the target channel ID message = await bot.get_channel(target_channel_id).send(embed=embed) # Add approve and decline buttons as components to the sent message approve_button = discord.ui.Button(label="Approve", style=discord.ButtonStyle.success, custom_id="approve_button") decline_button = discord.ui.Button(label="Decline", style=discord.ButtonStyle.danger, custom_id="decline_button") approve_view = discord.ui.View() approve_view.add_item(approve_button) approve_view.add_item(decline_button) await message.edit(view=approve_view) except Exception as e: error_message = f"An error occurred while creating the announcement: {e}" print(error_message) await interaction.response.send_message(error_message, ephemeral=True) async def input_value(interaction, prompt): """Prompt the user to input a value.""" await interaction.respond( content=f"Please enter the {prompt}:", ephemeral=True ) try: response = await bot.wait_for("message", timeout=60, check=lambda m: m.author == interaction.user) return response.content except asyncio.TimeoutError: await interaction.followup.send("Timed out. Please try again.", ephemeral=True) return None class ButtonView(View): def __init__(self, parent_view, embed): super().__init__() self.parent_view = parent_view self.embed = embed @discord.ui.button(label="Title", style=discord.ButtonStyle.secondary) async def title_button(self, interaction: discord.Interaction, button: discord.ui.Button): await interaction.response.send_message(TitleModal()) @discord.ui.button(label="Description", style=discord.ButtonStyle.secondary) async def description_button(self, interaction: discord.Interaction, button: discord.ui.Button): await interaction.response.send_message(DescriptionModal()) @discord.ui.button(label="Date", style=discord.ButtonStyle.secondary) async def date_button(self, interaction: discord.Interaction, button: discord.ui.Button): await interaction.response.send_message(DateModal()) @discord.ui.button(label="Confirm", style=discord.ButtonStyle.success) async def confirm_button(self, interaction: discord.Interaction): await interaction.response.send_message("Confirmed!", ephemeral=True) class TitleModal(discord.ui.Modal): def __init__(self, parent_view): self.parent_view = parent_view super().__init__(title="Enter a Title") self.title_input = discord.ui.TextInput(label="Title", placeholder="Enter title here...", required=True, max_length=50) self.add_item(self.title_input) async def on_submit(self, interaction: discord.Interaction): title = self.title_input.value self.parent_view.update_embed(title=title) await interaction.response.edit_message(embed=self.parent_view.embed, view=self.parent_view) class DescriptionModal(discord.ui.Modal): def __init__(self, parent_view): self.parent_view = parent_view super().__init__(description="Enter a Description") self.description_input = discord.ui.TextInput(label="Description", placeholder="Enter description here...", required=True, max_length=500) self.add_item(self.description_input) async def on_submit(self, interaction: discord.Interaction): description = self.description_input.value self.parent_view.update_embed(description=description) await interaction.response.edit_message(embed=self.parent_view.embed, view=self.parent_view) class DateModal(discord.ui.Modal): def __init__(self, parent_view): self.parent_view = parent_view super().__init__(date="Enter a Date") self.date_input = discord.ui.TextInput(label="Date", placeholder="Enter date here...", required=True, max_length=8) self.add_item(self.date_input) async def on_submit(self, interaction: discord.Interaction): date = self.date_input.value self.parent_view.update_embed(date=date) await interaction.response.edit_message(embed=self.parent_view.embed, view=self.parent_view) # Define a button for approving the announcement class ApproveButton(discord.ui.Button): async def callback(self, interaction: discord.Interaction): await interaction.response.send_message("Announcement approved!", ephemeral=True) # Define a button for declining the announcement class DeclineButton(discord.ui.Button): async def callback(self, interaction: discord.Interaction): await interaction.response.send_message("Announcement declined!", ephemeral=True) # Define a command for fetching a joke @bot.tree.command(name="joke", description="📌 • Use this command to brighten your day with a random joke.") async def slash_command(interaction: discord.Interaction): try: j = await Jokes() # Initialise the class joke = await j.get_joke(blacklist=['nsfw', 'racist']) # Retrieve a random joke if joke["type"] == "single": await interaction.response.send_message(joke["joke"]) else: await interaction.response.send_message(f"{joke['setup']}\n{joke['delivery']}") except Exception as e: error_message = f"An error occurred while fetching the joke: {e}" print(error_message) await interaction.response.send_message(error_message) # Define a command for checking bot latency @commands.command() async def ping(ctx): try: # Get the bot's latency in milliseconds bot_latency = round(bot.latency * 1000) # Send the bot latency in the server's channel await ctx.send(f"Pong! {bot_latency}ms") except Exception as e: error_message = f"An error occurred while checking bot latency: {e}" print(error_message) await ctx.send(error_message) # Run the bot bot.run(BOT_TOKEN)
Editor is loading...
Leave a Comment