I know how to get the user ID in the usual way:
async def start(message: types.Message):
await bot.send_message(message.from_user.id, f'Here is your id {message.from_user.id}')
But the question is, is it possible to find out the id outside of the async def start(message: types.Message) function?
Related
I made two working bot commands, one that get id's from users connected to a voice channel and the other one move single members to another channel.
How can i automate the process? I need to move every member without typing the username on discord chat
Thanks in advance
#bot.command()
async def move(ctx, channel : discord.VoiceChannel, *members: discord.Member):
for member in members:
await member.move_to(channel)
#bot.command()
async def people(ctx):
channel = bot.get_channel(ID_HERE)
member_ids = list(channel.voice_states.keys())
return member_ids
#*members should get member_ids
You can just create another command from which you call the other two functions:
#bot.command()
async def moveAll(ctx, channel:discord.VoiceChannel):
members_connected = await people(ctx) #Get the people
for member_id in people_connected:
member = await ctx.guild.fetch_member(member_id)
await member.move_to(channel)
I am currently trying to send a message to a user's DM but I only get the following error
user = client.get_user(499642019191324692)
AttributeError: module 'discord.client' has no attribute 'get_user'
This is my code
#bot.command()
async def test(ctx):
user = client.get_user(499642019191324692)
await user.send('Hello')
Thx #Astrogeek for your answer, even if only covering part of the issue. I got a similar issue, and this "bot" instead of client helped me A LOT.
To take the example back :
#bot.command()
async def test(ctx):
user = bot.get_user(499642019191324692)
await user.send('Hello')
Should instead be :
#bot.command()
async def test(ctx):
user = await bot.fetch_user(499642019191324692)
await user.send('Hello')
await fetch_user(user_id)
This function is a coroutine.
Retrieves a User based on their ID. This can only be used by bot accounts. You do not have to share any guilds with the user to get this information, however many operations do require that you do.
(from DiscordPy API Reference)
Since it's a coroutine, you have to "await" it. If you don't, the coroutine hasn't time to get the user from its ID and it results in a "can't send non-None value to a just-started coroutine" with bot.fetch_user(id)
As said in API you can get user from ID that way, but it only guarantees to deliver the message if bot and user are in a same guild or are friends.
you've used bot.command so it'll be bot.get_user instead of client.get_user
#bot.command()
async def test(ctx):
user = bot.get_user(499642019191324692)
await user.send('Hello')
I was trying to create come channels when bot starts. I want them to create in function on_ready. But await guild.create_text_channel("Channel") requires guild by itself. Usually when I want to create it by command I make something like this:
#client.command()
async def create(ctx):
guild = ctx.guild
await guild.create_text_channel(name="test channel")```
But I need ctx to create guild. So the question is: How do I create a channel without ctx?
You simply need to get a discord.Guild instance, you can get that using Bot.get_guild
async def on_ready():
await client.wait_until_ready()
guild = client.get_guild(id_here)
await guild.create_text_channel(name="whatever")
If you want to create a channel in all the guilds the bot is in you can loop through client.guilds
async def on_ready():
await client.wait_until_ready()
for guild in client.guilds:
await guild.create_text_channel(name="whatever")
Reference:
Bot.get_guild
Bot.guilds
Ran into the same problem with disnake, and it took me reading through the api and testing things to figure it out. Since disnake is supposed to be forked off of discord.py try this
#commands.command(name="obvious", description="given")
async def command(ctx: Context):
await ctx.message.guild.create_text_channel("channel_name")
This solved my issue, and now I just need to add the parameters to properly sort channel creation.
I would like my bot to be able to reply to a mention of a specific user (ex.. one person mentions my personal account and the bot responds saying that I'm currently not here)
Is there a way to do this using a format similar to this?
#client.event
async def on_message(message):
if message.author == client.user:
return
if message.content.startswith('#user_id'):
await message.channel.send('Im not here leave a message!')
You would need to use the specific format that discord bots receive mentions. The format is <#!user_id>.
#client.event
async def on_message(message):
if ("<#!put user id here>" in message.content):
await message.channel.send("Im not here leave a message!")
Example for how applied this and it worked for me
#client.event
async def on_message(message):
if ("<#!348256959671173120>" in message.content):
await message.channel.send("Im not here leave a message!")
Discord Member objects have a .mentioned_in(message) method.
WIZARD_ID = 123456 # <- replace with user ID you want
async def on_message(message):
wizard_of_oz = message.guild.get_member(WIZARD_ID)
if wizard_of_oz.mentioned_in(message):
await message.channel.send("Who dares summon the great Wizard of OZ?!")
If you also want to condition on if the user is mentioned by role you need to check the role_mentions in the message, too. So a more complete example is as follows:
def was_mentioned_in(message: discord.Message, member: discord.Member) -> bool:
"""
Whether or not the member (or a role the member has) was mentioned in a message.
"""
if member.mentioned_in(message):
return True
for role in message.role_mentions:
if role in member.roles:
return True
return False
#client.event
async def on_message(message):
wizard_of_oz = message.guild.get_member(WIZARD_ID)
if was_mentioned_in(message, wizard_of_oz):
await message.channel.send("Who dares summon the great Wizard of OZ?!")
I made recently a discord bot for small server with friends. It is designed to answer when mentioned, depending on user asking. But the problem is, when someone mention bot from a phone app, bot is just not responding. What could be the problem?
Code:
import discord
from discord.ext import commands
from discord.ext.commands import Bot
import asyncio
bot = commands.Bot(command_prefix = '=')
reaction = "🤡"
#bot.event
async def on_ready():
print('Bot is ready.')
#bot.listen()
async def on_message(message):
if str(message.author) in ["USER#ID"]:
await message.add_reaction(emoji=reaction)
#bot.listen()
async def on_message(message):
mention = f'<#!{BOT-DEV-ID}>'
if mention in message.content:
if str(message.author) in ["user1#id"]:
await message.channel.send("Answer1")
else:
await message.channel.send("Answer2")
bot.run("TOKEN")
One thing to keep in mind is that if you have multiple functions with the same name, it will only ever call on the last one. In your case, you have two on_message functions. The use of listeners is right, you just need to tell it what to listen for, and call the function something else. As your code is now, it would never add "🤡" since that function is defined first and overwritten when bot reaches the 2nd on_message function.
The message object contains a lot of information that we can use. Link to docs
message.mentions gives a list of all users that have been mentioned in the message.
#bot.listen("on_message") # Call the function something else, but make it listen to "on_message" events
async def function1(message):
reaction = "🤡"
if str(message.author.id) in ["user_id"]:
await message.add_reaction(emoji=reaction)
#bot.listen("on_message")
async def function2(message):
if bot.user in message.mentions: # Checks if bot is in list of mentioned users
if str(message.author.id) in ["user_id"]: # message.author != message.author.id
await message.channel.send("Answer1")
else:
await message.channel.send("Answer2")
If you don't want the bot to react if multiple users are mentioned, you can add this first:
if len(message.mentions)==1:
A good tip during debugging is to use print() So that you can see in the terminal what your bot is actually working with.
if you print(message.author) you will see username#discriminator, not user_id