Search code examples
pythondiscorddiscord.pypython-asyncio

Discord.py slash-command ctx.send()


everyone having a small issue with the Slash commands. The idea is that I fetch an Array of Assetdata convert each into an embedded and then send the embedded. If there is an image it will show an image and if a .mp4 is linked to the asset it will convert the mp4 to gif and then attache the file locally with file = discord.File(). This all worked just fine bevor moving to Slash commands. For some reason, the slash command wants to send a response bevor receiving all the data. This is an issue because the gif processing takes time or if a large sum of data is requested the request takes longer. The function works fine if have a single asset to display and an Image.

So my question is how do I get ctx.send() to wait??

Thanks in Advance everyone!

client = commands.Bot(command_prefix = "!")
slash = SlashCommand(client, sync_commands=True)


@slash.slash(
    name="assetsearch",
    description="Sends a Message",
    guild_ids=[XXXXXXXXXXXXXXXX], #Hidden for StackOverflow
    options = [
        create_option(
            name = "searchtype",
            description = "Please choose how you would like to search for an Asset.",
            required = True,
            option_type = 3,
            choices = [
                create_choice(
                    name = "Search by Asset Id",
                    value = "id"
                ),
                create_choice(
                    name = "Search by Collection",
                    value = "colec"
                ),
                create_choice(
                    name = "Search by Accountname",
                    value = "acc"
                ),
                create_choice(
                    name = "Search by Asset Name",
                    value = 'match'
                )
            ]
        ),
        create_option(
            name = "searchterm",
            description = "Please enter an Asset Id, an Account name, the name of an Asset or the Collection name.",
            required = True,
            option_type = 3
            ),

        create_option(
            name = "amount",
            description = "Please enter how many Assets you would like to display.",
            required = True,
            option_type = 3
            ),
    ],
)

async def _assetsearch(ctx:SlashContext, searchtype: str, searchterm: str, amount: str):
    response = await getAssetData(searchtype, searchterm, amount) #Fetches an Array of AssetData, async function
    for asset in response:
        nftEmbed, nftFile = await __formatMessage(asset) #formats the message, converts mp4 from website to gif, returns the gif and ebeded
        print(nftEmbed,nftFile)
        await ctx.send(embed=nftEmbed, file=nftFile) #send the embeded and gif, ISSUE!!!
        if os.path.isfile('Nft.gif'): os.remove("Nft.gif")
    response = ""

Working Function bevor using slash-command

    if msg.startswith('$search'):
        try:
            searchType = msg.split(",")[1]
        except:
            searchType = 'match'
        try:
            searchTerm = msg.split(",")[2]
        except:
            searchTerm = 'abcd'
        try:
            searchLimit = msg.split(",")[3]
        except:
            searchLimit = '1'
        response = getAssetData(searchType,searchTerm,searchLimit)
        for asset in response:
            nftEmbed, file = __formatMessage(asset)
            await message.channel.send(embed=nftEmbed, file=file)
            if os.path.isfile('Nft.gif'): os.remove("Nft.gif")
        response = ""

Solution

  • I figured it out. The Slashcomands are expecting a response within 3s if you are working with an API in the background and then precessing data this could become a criterium you cant meet consistently. This is why you would have the Bot itself respond directly upon request. Once you are done with processing your data you can respond normaly

    async def _slashcomandfunction(ctx:SlashContext, str:otherparameters,):
        message = await ctx.send('Sometext') #Direct respond
        await ctx.channel.send(embed=embed, file=file) #Actual message
    

    If you don't want the Bots message

    message = await ctx.send('Sometext',delete_after=1)
    

    ...or edit the message the Bot sent.

    message = await ctx.send('Sometext')
    await message.edit(content="newcontent")