Minylugin
Minylugin

Reputation: 19

check if a specific message is still in the channel? - Discord.py

I've been working on creating a connect 4 game for my discord bot, the game itself works fine, but if someone removes the message that contains the Board and the reactions which are used by users to play the game, the game will start to break and won't work as it should until someone restarts the bot:

turn = 0 #switches between 0 and 1 during the game

game_over = False
while not game_over:
    try:

        reaction, user = await client.wait_for("reaction_add", check = check)
        if turn == 0:
            #do stuff depending on what the emoji reaction is
            if winning move():
                game_over = True
        else:
            #do stuff depending on what the emoji reaction is
            if winning_move():
                game_over = True
        #more things that aren't necessary to show

Is there a way for me to change the game_over to True after someone removes the message and/or check if the message has been deleted and change the variable to True through that? for e.g:

#If the board's not in the channel:
  await message.channel.send("Board was not found")
  game_over = True

any help would be highly appreciated!

Upvotes: 1

Views: 831

Answers (2)

Ratery
Ratery

Reputation: 2917

You can use asyncio.wait() function. See an example below where I have implemented simple mini-game logic.

@client.command()
async def mini_game(ctx):
    message = await ctx.send("test message")  # send first message
    done, pending = await asyncio.wait(
        [
            asyncio.create_task(client.wait_for("reaction_add", check=your_check)),  # specify `your_check` function
            asyncio.create_task(client.wait_for("message_delete", check=lambda m: m == message))
        ],
        return_when=asyncio.FIRST_COMPLETED,
        timeout=30  # you can specify timeout here
    )
    if done == set():
        pass  # if time limit exceeded
    else:
        coro = done.pop().result()
        try:
            reaction, member = coro  # if user `member` has added `reaction`
        except TypeError:
            pass  # if message has been deleted

You can adapt this code to suit your needs.

Upvotes: 1

LoahL
LoahL

Reputation: 2613

You can check if a message has been deleted by simple trying to fetch the message with the id it had before being deleted. If this returns a NotFound error, the message has been deleted:

def is_message_deleted(ctx, message_id):
    try:
        await ctx.fetch_message(message_id) #try to fetch the message
        return False
    except discord.error.NotFound: #if a NotFound error appears, the message is either not in this channel or deleted
        return True

You can then include this function in your code:

if is_message_deleted(ctx, board_message.id):
    await message.channel.send("Board was not found")
    game_over = True

References:

Upvotes: 0

Related Questions