no jif
no jif

Reputation: 3

Is there a way to convert a string to a discord.Member type in discord.py?

I've been trying to add a tic-tac-toe minigame to my discord bot. I originally wrote the code inside a @client.command() because I thought you could use client.wait_for() inside it but unfortunately, you can't. Anyway, I had to convert my code to work on the on_message() function and now I am stumbling the problem of taking a discord.Member variable type from the initial command so like ~tictactoe @user#1234. So for example, I tried writing this in the on_message() function to no success.

if message.content.startswith("~tictactoe") or message.content.startwith("~ttt"):
    member = str(message).split(" ")
    member = discord.Member(member[1])
    channel = message.channel

Here is my full code:

if message.content.startswith("~tictactoe") or message.content.startwith("~ttt"):
    member = str(message).split(" ")
    member = discord.Member(member[1])
    channel = message.channel
    if member.bot: channel.send("You can't play against a bot!")
    else:
        while True:
            x = 0
            player = [message.author if (x % 2 == 0) else member]
            x += 1
            symbol = [':x:' if player == message.author else ':o:']
            def check(m):
                possibilities = ['a1','a2','a3','b1','b2','b3','c1','c2','c3']
                return (m.content.lower() in possibilities or m.content.lower() == 'end') and m.author == player and m.channel == channel
            if x != 1:
                channel.send("TicTacToe\n{message.author.name} vs. {member.name}")
                for i in range(3):
                    channel.send(f"{board[i][0]}{board[i][1]}{board[i][2]}\n")
            channel.send(f"{player.mention}, where do you want to place your marker?\na1\ta2\ta3\nb1\tb2\tb3\nc1\tc2\tc3\n or `end` to end game")
            try:
                cell = await client.wait_for('message', timeout=20.0, check=check)
            except:
                channel.send("Input invalid or you took too long to respond.")
            else:
                cell = cell.lower()
                if cell == 'end':
                    break
                possibilities = [['a1','a2','a3'], ['b1','b2','b3'], ['c1','c2','c3']]
                board = [[':black_large_square:',':black_large_square:',':black_large_square:'], [':black_large_square:',':black_large_square:',':black_large_square:'], [':black_large_square:',':black_large_square:',':black_large_square:']]
                for i in range(3):
                    for j in range(3):
                        if cell == str(possibilities[i][j]): board[i][j] == symbol
                won = False
                for i in range(3):
                    if board[i][0] == board[i][1] == board[i][2] and won == False:
                        channel.send(f"{player} won the game!")
                        won == True
                    if board[0][i] == board[1][i] == board[2][i] and won == False:
                        channel.send(f"{player} won the game!")
                        won = True
                if board[0][0] == board[1][1] == board[2][2] and won == False:
                    channel.send(f"{player} won the game!")
                    won = True
                if board[0][2] == board[1][1] == board[2][0] and won == False:
                    channel.send(f"{player} won the game!")
                    won = True

Any help apperciated :)

Upvotes: 0

Views: 2264

Answers (1)

MrSpaar
MrSpaar

Reputation: 3994

Using message.mentions


message.mentions returns a list of discord.Member that were mentioned (or discord.User if the message in sent in private messages).

# Safe method
if message.mentions:
    member = message.mentions[0]
else:
    return  # There was no mentions

# Riskier but simpler method
# Having no mentions or more than one would raise an error
member, = message.mentions

Quick note: a reply is considered as a mention, message.mentions will contain the members mentionned in your message and the member you replied to.

Parsing the message


A mention is equivalent to <@!id>, so you can parse your message to get the member's id:

command, member = message.split()
member_id = int(member.strip('<@!>'))

Then, to get the discord.Member object out of it:

# Regardless of cache, but sends an API call
member = await bot.fetch_member(member_id)

# Depends on the bot's cache
# Doesn't make any API calls and isn't asynchronous
member = message.guild.get_member(member_id)

Upvotes: 2

Related Questions