I am making a bot in discord.py but when I run the userinfo command, it shows that the person is offline even though they are online or on dnd. Here is the code
#client.command()
async def userinfo(ctx, user: discord.Member=None):
"""Displays user information."""
if not user: # this command took forever to redo for the no user lol
embed = discord.Embed(title="Your info.", color=0x176cd5)
embed.add_field(name="Username", value=ctx.message.author.name + "#" + ctx.message.author.discriminator, inline=True)
embed.add_field(name="ID", value=ctx.message.author.id, inline=True)
embed.add_field(name="Status", value=ctx.message.author.status, inline=True)
embed.add_field(name="Highest role", value=ctx.message.author.top_role)
embed.add_field(name="Roles", value=len(ctx.message.author.roles))
embed.add_field(name="Joined", value=ctx.message.author.joined_at)
embed.add_field(name="Created", value=ctx.message.author.created_at)
embed.add_field(name="Bot?", value=ctx.message.author.bot)
embed.set_thumbnail(url=ctx.message.author.avatar_url)
embed.set_author(name=ctx.message.author, icon_url=ctx.message.author.avatar_url)
await ctx.send(embed=embed)
else:
embed = discord.Embed(title="{}'s info".format(user), color=0x176cd5)
embed.add_field(name="Username", value=user.name + "#" + user.discriminator, inline=True)
embed.add_field(name="ID", value=user.id, inline=True)
embed.add_field(name="Status", value=user.status, inline=True)
embed.add_field(name="Highest role", value=user.top_role)
embed.add_field(name="Roles", value=len(user.roles))
#embed.add_field(name="Game", value=user.game)
embed.add_field(name="Joined", value=user.joined_at)
embed.add_field(name="Created", value=user.created_at)
embed.add_field(name="Bot?", value=user.bot)
embed.set_thumbnail(url=user.avatar_url)
embed.set_author(name=ctx.message.author, icon_url=ctx.message.author.avatar_url)
await ctx.send(embed=embed)
```
you would need the presence intent for this
you can get the intents with this
bot = commands.Bot(("prefix"), intents=discord.Intents.all())
there is also a better way of defaulting the user to ctx.author if no user is inputted
#bot.command()
async def userinfo(ctx, user: discord.Member=None):
"""Displays user information."""
if user == None: ##if no user is inputted
user = ctx.author ##defines user as the author of the message
embed = discord.Embed(title="{}'s info".format(user), color=0x176cd5)
embed.add_field(name="Username", value=user.name + "#" + user.discriminator, inline=True)
embed.add_field(name="ID", value=user.id, inline=True)
embed.add_field(name="Status", value=user.status, inline=True)
embed.add_field(name="Highest role", value=user.top_role)
embed.add_field(name="Roles", value=len(user.roles))
embed.add_field(name="Game", value=user.game)
embed.add_field(name="Joined", value=user.joined_at)
embed.add_field(name="Created", value=user.created_at)
embed.add_field(name="Bot?", value=user.bot)
embed.set_thumbnail(url=user.avatar_url)
embed.set_author(name=ctx.message.author, icon_url=ctx.message.author.avatar_url)
await ctx.send(embed=embed)
with this, I hope I helped shorten your code and fix your problem, have a nice day
I hope you didn't forget about intents. To get the status you would need the precence intent.
Related
Trying to use discord.py and learning the beginnings of bot developement, but when I try to send an embed, it gives me the error.
I tried:
import discord
intents = discord.Intents.default()
intents.message_content = True
client = discord.Client(intents=intents)
#client.event
async def on_ready():
print(f'Logged in as {client.user}')
#client.event
async def on_message(message):
if message.content.startswith('!test'):
embed=discord.Embed(title="title", color=0x13fa07)
embed.add_field(name="name1", value="value1", inline=True)
embed.add_field(name="name2", value="value2", inline=True)
embed.set_footer(text="bot test 0.1")
await message.send(embed=embed)
client.run('token here')
(token ofc censored)
but then it returns
AttributeError: 'Message' object has no attribute 'send'
Welcome to discord.py, just as the error says 'Message' object has no attribute 'send' but it does have the attribute channel which has the method send that you are looking for docs
...
await message.channel.send(embed=embed)
Here is the welcome message code:
#bot.event
async def on_member_join(member):
print(f"{member} has just joined")
channel = bot.get_channel(ID)
role = ID
embed = EmbedBuilder (
title = f"Welcome {member.mention} to the server!",
description = "",
color = 0xf1c40f
).build()
await channel.send(embed=embed)
role = get(member.guild.roles, id=role)
await member.add_roles(role)
This will return the result:
Welcome <#MyUserId> to the server!
for other people, such as my alt account, but will successfully return
Welcome #Mentioned to the server!
for the persons own account to see. I have no idea why it only displays and pings successfully for the member who has joined, but wont display correctly for other people. Any help?
Hello I need help with my warning command. I don't know how to make it say the stuff in chat, if you do show me how to fix this, I would preferably want this in an embed.
#bot.command(pass_context = True)
#has_permissions(manage_roles=True, ban_members=True)
async def warn(ctx,user:discord.User,*reason:str):
if not reason:
await ctx.send("Please provide a reason")
return
reason = ' '.join(reason)
for current_user in report['users']:
if current_user['name'] == user.name:
current_user['reasons'].append(reason)
break
else:
report['users'].append({
'name':user.name,
'reasons': [reason,]
})
with open('reports.json','w+') as f:
json.dump(report,f)
#bot.command(pass_context = True)
async def warnings(ctx,user:discord.User):
for current_user in report['users']:
if user.name == current_user['name']:
await ctx.send(f"```{user.name} has been reported {len(current_user['reasons'])} times : {','.join(current_user['reasons'])}```")
break
else:
await ctx.send(f"```{user.name} has never been reported```")
#warn.error
async def kick_error(error, ctx):
if isinstance(error, MissingPermissions):
text = "Sorry {}, you do not have permissions to do that!".format(ctx.message.author)
await bot.send_message(ctx.message.channel, text)
for and embed put in code. e.g:
embed = discord.Embed(title=f'{member}\'s Warning!',color=0x1d9521)
embed.add_field(name='why he is warned',value=reason, inline=False)
embed.add_field(name="Moderator that warned", value={ctx.author.mention}, inline=False)
i am not sure if this would work but then to send it do
await ctx.send(embed=embed)
another way to send is
await ctx.reply(embed=embed)
to put this out of the embed you could do
await ctx.send("Why they are warned `{reason}`/nThe Responsible Moderator {ctx.author.mention}")
i am not sure if this would work but you can try
I'm trying to get my bot to respond to a message sent after a trigger word, but all it does is send me the following error: AttributeError: 'generator' object has no attribute 'content'. Here is my code:
#client.event
async def on_message(message):
if message.content == "report":
await message.author.send("Type your report below")
def check(m):
return m.guild == None and m.author == message.author
try:
response = client.wait_for("message", check=check)
except asyncio.TimeoutError:
await message.author.send("Uh-oh, the request timed out! Try again.")
else:
content = response.content
Thanks in advance!
client.wait_for is a coroutine function. That means, in order to use it, you have to await it.
You just have to do:
response = await client.wait_for("message", check=check)
import discord
from discord.ext import commands
import platform
import random
import time
bot = commands.Bot(command_prefix='+', case_insensitive=True)
#bot.event
async def on_ready():
print(f'Logged in as {bot.user.name}(ID: +{bot.user.id}) |'
f'Connected to {str(len(bot.guilds))} servers |'
f'Connected to {str(len(set(bot.get_all_members())))} users')
print('--------')
print('CREATED AND HOSTED BY Fataldagod | Fixed Version')
#bot.event
async def on_command_error(ctx, error):
# Ignore these errors:
ignored = (
commands.CommandNotFound, commands.UserInputError, commands.BotMissingPermissions,
commands.MissingPermissions, discord.errors.Forbidden, commands.CommandInvokeError,
commands.MissingRequiredArgument)
if isinstance(error, ignored):
return
#bot.command(pass_context=True)
#commands.has_permissions(kick_members=True)
async def userinfo(ctx, user: discord.Member):
try:
embed = discord.Embed(title="{}'s info".format(user.name),
description="Here's what I could find.",
color=discord.Colour.dark_red())
embed.add_field(name="Name", value=user.name, inline=True)
embed.add_field(name="ID", value=user.id, inline=True)
embed.add_field(name="Status", value=user.status, inline=True)
embed.add_field(name="Highest role", value=user.top_role)
embed.add_field(name="Joined", value=user.joined_at)
embed.set_thumbnail(url=user.avatar_url)
await ctx.send(embed=embed)
except:
await ctx.send("Missing Requrired Args")
#commands.has_permissions(administrator=True)
#bot.command(pass_context=True)
async def send(ctx, *, content: str):
for member in ctx.guild.members:
c = await member.create_dm()
try:
await c.send(content)
await ctx.send("MassDM message sent to: {} ".format(member))
except Exception:
await ctx.send("MassDM message blocked by: {} ".format(member))
Was wondering what I can change to make it so the bot DMs specific roles rather than the entire server?
For example instead of me typing +send (message) I'd like to type +send #role1 #role2 role3 #role4 (message) or something along these lines.
Any help is much appreciated.