import asyncio import os import discord from discord import app_commands intents = discord.Intents.default() bot = discord.Client(intents=intents) manag = app_commands.CommandTree(bot) # manag = management message_delay = 0.5 repeat_task = {} async def repeat_messages(channel, user_id, message, times, interact): task = asyncio.current_task() try: for _ in range(times): await interact.followup.send( message, ephemeral=False ) await asyncio.sleep(message_delay) except asyncio.CancelledError: raise finally: if repeat_task.get(user_id) is task: repeat_task.pop(user_id, None) class RepeatAgainView(discord.ui.View): def __init__(self, user_id, message, times): super().__init__(timeout=300) self.message = message self.times = times @discord.ui.button( label="PRESS TO REPEAT", style=discord.ButtonStyle.primary ) async def repeat_button( self, interact: discord.Interaction, button: discord.ui.Button ): user_id = interact.user.id channel = interact.channel if channel is None: await interact.response.send_message( "unable to find channel", ephemeral=True ) return await interact.response.send_message( "start repeat", ephemeral=True ) task = asyncio.create_task( repeat_messages( channel, user_id, self.message, self.times, interact ) ) repeat_task[user_id] = task # commands @manag.command( name="say", description="make the bot say one message" ) @app_commands.allowed_installs(guilds=True, users=True) @app_commands.allowed_contexts( guilds=True, dms=True, private_channels=True ) async def say_command( interact: discord.Interaction, message: str ): await interact.response.send_message( "...", ephemeral=True ) await interact.followup.send( message, ephemeral=False ) @manag.command( name="discord", description="discordinvite" ) @app_commands.allowed_installs(guilds=True, users=True) @app_commands.allowed_contexts( guilds=True, dms=True, private_channels=True ) async def run_command(interact: discord.Interaction): message = ( "# THE SUN WILL RISE AGAIN\n" "discord.gg/eMzvN3bha" ) await start_repeat(interact, message, 5) @manag.command( name="repeat", description="repeat message" ) @app_commands.allowed_installs(guilds=True, users=True) @app_commands.allowed_contexts( guilds=True, dms=True, private_channels=True ) async def repeat_command( interact: discord.Interaction, message: str ): await start_repeat(interact, message, 5) # end of command async def start_repeat(interact, message, times=5): user_id = interact.user.id channel = interact.channel if channel is None: await interact.response.send_message( "no channel found", ephemeral=True ) return await interact.response.send_message( "start repeat", ephemeral=True, view=RepeatAgainView(user_id, message, times) ) task = asyncio.create_task( repeat_messages( channel, user_id, message, times, interact ) ) repeat_task[user_id] = task @bot.event async def on_ready(): print(f"logged in: {bot.user}") try: synced = await manag.sync() print("commands synced:") for command in synced: print(f"- /{command.name}") except Exception as exc: print(f"command sync failed: {exc}") bot.run(os.environ["token"])