How to send an embed on client ready - python

I am creating a bot with discord.py.
I would like to send an embed to a specific discord channel when the bot is ready. To do that, here is my code:
import discord
client = discord.Client()
logchannel = client.fetch_channel(692934456612487199)
#client.event
async def on_ready():
print(f'Ticket Tool active as {client.user}')
embed = discord.Embed(title="**Jokz' Ticket Tool**", color=0xff0000, description="Started Successfully!")
embed.set_footer(text="JokzTickets | #jokztools",icon_url="https://pbs.twimg.com/profile_images/1243255945913872384/jOxyDffX_400x400.jpg")
embed.set_thumbnail(url="https://gifimage.net/wp-content/uploads/2017/10/check-mark-animated-gif-12.gif")
await logchannel.send(embed=embed)
client.run(key)
When I run this, I get the following error:
PS C:\Users\jokzc\Desktop\jokzticketspy> py index.py
Ticket Tool active as Jokz' Tools#5577
Ignoring exception in on_ready
Traceback (most recent call last):
File "C:\Users\jokzc\AppData\Local\Programs\Python\Python38\lib\site-packages\discord\client.py", line 312, in _run_event
await coro(*args, **kwargs)
File "index.py", line 15, in on_ready
await logchannel.send(embed=embed)
TypeError: send() takes no keyword arguments
What would the correct way to format this be?

So I ended up figuring out that it worked if I changed the function from client.fetch_channel to client.get_channel and I needed to put this in the actual on_ready function! The reason for this is because the client cannot get or fetch the channel until the client is actually ready.
The corrected code looks like this:
#client.event
async def on_ready():
logchannel = client.get_channel(692934456612487199)
print(f'Ticket Tool active as {client.user}')
embed = discord.Embed(title="**Jokz' Ticket Tool**", color=0x00ff00, description="Started Successfully!")
embed.set_footer(text="JokzTickets | #jokztools",icon_url="https://pbs.twimg.com/profile_images/1243255945913872384/jOxyDffX_400x400.jpg")
embed.set_thumbnail(url="https://gifimage.net/wp-content/uploads/2017/10/check-mark-animated-gif-12.gif")
await logchannel.send(embed=embed)

#client.event
async def on_ready():
channelid = client.get_channel(id)
botname = client.user.name
print('message ' + botname)
embed = discord.Embed(title=f"Text", description="Text", color=discord.Color.red())
embed.set_footer(text="Your text", icon_url="URL of icon")
embed.set_thumbnail(url="Url")
await channelid.send(embed=embed)

Related

How to use discord.spotify class in discord.py

The discord.py documentation has a spotify class (https://discordpy.readthedocs.io/en/stable/api.html#spotify)
And I'm wondering how to set this activity to a profile. There are no examples in the documentation.
I tried using this activity in on_ready event
#client.event
async def on_ready():
print("Bot was connected to the server")
await bot.change_presence(activity=discord.Spotify(title = "Test"))
And my output is wrong.
Bot was connected to the server
Ignoring exception in on_ready
Traceback (most recent call last):
File "/home/runner/Russian-field-of-experiments-on-the-island-of-Python/venv/lib/python3.8/site-packages/discord/client.py", line 343, in _run_event
await coro(*args, **kwargs)
File "main.py", line 13, in on_ready
await bot.change_presence(activity=discord.Spotify(title = "Test"))
File "/home/runner/Russian-field-of-experiments-on-the-island-of-Python/venv/lib/python3.8/site-packages/discord/activity.py", line 527, in __init__
self._sync_id = data.pop('sync_id')
KeyError: 'sync_id'
full source code:
import discord
from discord.ext import commands
bot = commands.Bot(command_prefix="!")
#bot.event
async def on_ready():
print("Bot was connected to the server")
await bot.change_presence(activity=discord.Spotify(title = "Test"))
bot.run("token")
How to use the Spotify class in discord.py?
To change the bot's status to "listening to Spotify" you can do this:
await bot.change_presence(activity=discord.Activity(type=discord.ActivityType.listening, name="Spotify"))
If you want to set it to what a specific user is listening to you can do this:
from discord import Spotify
#bot.event
async def on_ready():
user = bot.get_user(user_id) # Make sure to change this to the users ID.
while True:
for activity in user.activities:
if isinstance(activity, Spotify):
await bot.change_presence(activity=discord.Activity(type=discord.ActivityType.listening, name=f"{activity.title} by {activity.artist}"))
else:
await bot.change_presence(activity=discord.Activity(type=discord.ActivityType.listening, name=f"Nothing")) # User isn't listening to Spotify
For the above to work, the user you define must be listening to Spotify. If they're not listening to Spotify, the status will change to Nothing.

Discord.py ctx commands not recognised

im fairly new to coding in general and recently started trying to code my own bot. Almost all of the tutorials i have seen use the ctx command however, whenever i use it i get this error:
"NameError: name 'ctx' is not defined"
Here is part of my code that uses the ctx command. The aim is to get it to delete the last 3 messages sent.
#client.event
async def purge(ctx):
"""clear 3 messages from current channel"""
channel = ctx.message.channel
await ctx.message.delete()
await channel.purge(limit=3, check=None, before=None)
return True
#client.event
async def on_message(message):
if message.content.startswith("purge"):
await purge(ctx)
client.run(os.environ['TOKEN'])
Full error:
Ignoring exception in on_message
Traceback (most recent call last):
File "/opt/virtualenvs/python3/lib/python3.8/site-packages/discord/client.py", line 343, in _run_event
await coro(*args, **kwargs)
File "main.py", line 31, in on_message
await purge(ctx)
NameError: name 'ctx' is not defined
I'm hosting the server on repl.it if that makes any difference and as i said, im pretty new to coding so it's possible i have missed something very obvious, any help is appreciated. ^_^
A fix to that is:
async def purge(message):
await message.delete()
channel = message.channel
await channel.purge(limit=3)
#client.event
async def on_message(message):
if message.content.startswith("purge"):
await purge(message)
The problem is the on_message function uses message and not ctx. Replacing message with ctx wont work because im pretty sure the on_message cant use ctx

How to get your Discord bot to say something specific, then delete the previous message

Im new to working with discord.py, basically im simply trying to make my discord bot say something then delete the previous text, so for example I want to type "/say hello" then I want the bot to grab that, remove the prefix and just print "hello", Ive already googled and searched and found another guide but there was no follow up answers and when I tried the solutions they errored, below is the code im using
import discord
from discord.ext import commands
bot = discord.Client()
prefix = "/"
#bot.event
async def on_ready():
print("Online")
#bot.event
async def on_message(message):
args = message.content.split(" ")[1:]
if message.content.startswith(prefix + "say"):
await bot.delete_message(message)
await bot.send_message(message.channel, " ".join(args))
bot.run("token")
and this is the error the console prints out
C:\Users\unknownuser\anaconda3\envs\discordbot\pythonw.exe C:/Users/unknownuser/PycharmProjects/discordbot/bot.py
Online
Ignoring exception in on_message
Traceback (most recent call last):
File "C:\Users\unknownuser\anaconda3\envs\discordbot\lib\site-packages\discord\client.py", line 313, in _run_event
await coro(*args, **kwargs)
File "C:/Users/unknownuser/PycharmProjects/discordbot/bot.py", line 15, in on_message
await bot.delete_message(message)
AttributeError: 'Client' object has no attribute 'delete_message'
As I start learning the documentation and logic behind it I should start figuring it out for myself but this one has me stumped, Help would be appreciated
Looks like you're using a tutorial for an old version of discord.py.
There are some major changes in the most recent - rewrite - version.
Example for your code
# using the command decorator
#bot.command()
async def say(ctx, *, sentence):
await ctx.message.delete()
await ctx.send(sentence)
#############################################
# using the on_message event
#bot.event
async def on_message(message):
args = message.content.split(" ")[1:]
if message.content.startswith(prefix + "say"):
await message.delete()
await message.channel.send(" ".join(args))
else:
await bot.process_commands(message) # allows decorated commands to work
References:
Message.delete()
Bot.process_commands()
Messageable.send()

welcome/goodbye using discord.py

I'm trying to create a bot that greets a user that joins a server. But make it so that the person is greeted in the server itself rather than as a DM (which most tutorials I've found teach you how to do).
This is what I've come up with so far.
#bot.event
async def on_member_join(member):
channel = bot.get_channel("channel id")
await bot.send_message(channel,"welcome")
but, it doesn't work and instead throws up this error.
Ignoring exception in on_member_join
Traceback (most recent call last):
File "C:\Users\Lenovo\AppData\Local\Programs\Python\Python36\lib\site-
packages\discord\client.py", line 307, in _run_event
yield from getattr(self, event)(*args, **kwargs)
File "C:\Users\Lenovo\Documents\first bot\bot.py", line 26, in
on_member_join
await bot.send_message(channel,"welcome")
File "C:\Users\Lenovo\AppData\Local\Programs\Python\Python36\lib\site-
packages\discord\client.py", line 1145, in send_message
channel_id, guild_id = yield from self._resolve_destination(destination)
File "C:\Users\Lenovo\AppData\Local\Programs\Python\Python36\lib\site-
packages\discord\client.py", line 289, in _resolve_destination
raise InvalidArgument(fmt.format(destination))
discord.errors.InvalidArgument: Destination must be Channel, PrivateChannel,
User, or Object. Received NoneType
You aren't passing the correct id to get_channel, so it's returning None. A quick way to get it would be to call the command
from discord.ext import commands
bot = commands.Bot(command_prefix='!')
#bot.command(pass_context=True)
async def get_id(ctx):
await bot.say("Channel id: {}".format(ctx.message.channel.id))
bot.run("TOKEN")
You could also modify your command to always post in a channel with a particular name on the server that the Member joined
from discord.utils import get
#bot.event
async def on_member_join(member):
channel = get(member.server.channels, name="general")
await bot.send_message(channel,"welcome")
The answer by Patrick Haugh is probably your best bet, but here are a few things to keep in mind.
The Member object contains the guild (server), and the text channels the server contains.
By using member.guild.text_channels you can ensure the channel will exist, even if the server does not have a 'general' chat.
#bot.event
async def on_member_join(member):
channel = member.guild.text_channels[0]
await channel.send('Welcome!')
Try this:
#bot.event
async def on_member_join(member):
channel = discord.utils.get(member.guild.channels, name='the name of the channel')
await channel.send(f'Enjoy your stay {member.mention}!')

Discord.py Module Python 3.6.4 kick feature

I was making a discord bot using the discord module in python... I am having a lot of trouble trying to make the kick command work. I tried using bot.kick, client.kick and ctx.kick but they all give the same error which says,
Ignoring exception in command kick:
Traceback (most recent call last):
File "C:\Users\user\AppData\Roaming\Python\Python36\site-packages\discord\ext\commands\core.py", line 62, in wrapped
ret = yield from coro(*args, **kwargs)
File "C:\Users\user\Desktop\Code\bot.py", line 44, in kick
await client.kick(user)
AttributeError: 'Client' object has no attribute 'kick'
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "C:\Users\user\AppData\Roaming\Python\Python36\site-packages\discord\ext\commands\bot.py", line 886, in invoke
yield from ctx.command.invoke(ctx)
File "C:\Users\user\AppData\Roaming\Python\Python36\site-packages\discord\ext\commands\core.py", line 493, in invoke
yield from injected(*ctx.args, **ctx.kwargs)
File "C:\Users\user\AppData\Roaming\Python\Python36\site-packages\discord\ext\commands\core.py", line 71, in wrapped
raise CommandInvokeError(e) from e
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: AttributeError: 'Client' object has no attribute 'kick'
I tried searching various different youtube videos and posts related to the problem I am having but nobody seems to be having a solution. I have written the code below. If you spot any errors which I missed please let me know.
import time
import random
import discord
import asyncio
from discord.ext import commands
#Initialize
client = discord.Client()#Creates Client
bot = commands.Bot(command_prefix='!')#Sets prefix for commands(!Command)
#bot.event
async def on_ready():
print('Name:', end=' ')
print(bot.user.name)
print('ID: ')
print(bot.user.id)
#bot.command(pass_context=True)
async def user_info(ctx, user: discord.Member):
await ctx.send(f'The username of the user is {user.name}')
await ctx.send(f'The ID of the user is {user.id}')
await ctx.send(f'The status of the user is {user.status}')
await ctx.send(f'The role of the user is {user.top_role}')
await ctx.send(f'The user joined at {user.joined_at}')
#bot.command(pass_context=True)
async def kick(ctx, user: discord.Member):
await ctx.send(f'The Kicking Hammer Has Awoken! {user.name} Has Been Banished')
await client.kick(user)
bot.run('SECRET')
client.run('SECRET')
You appear to be using the newer discord.py 1.0, also called the rewrite branch. You should read this, which is the documentation of the many breaking changes that were made in that switch. You should also refer solely to that documentation, as most documentation for the older 0.16 version is not compatible.
Many things were moved out of Client and into places that made a little more sense. Specifically, kick is now a method of Guilds.
import asyncio
from discord.ext import commands
bot = commands.Bot(command_prefix='!')
#bot.event
async def on_ready():
print('Name:', end=' ')
print(bot.user.name)
print('ID: ')
print(bot.user.id)
#bot.command(pass_context=True)
async def user_info(ctx, user: discord.Member):
await ctx.send(f'The username of the user is {user.name}')
await ctx.send(f'The ID of the user is {user.id}')
await ctx.send(f'The status of the user is {user.status}')
await ctx.send(f'The role of the user is {user.top_role}')
await ctx.send(f'The user joined at {user.joined_at}')
#bot.command(pass_context=True)
async def kick(ctx, user: discord.Member):
await ctx.send(f'The Kicking Hammer Has Awoken! {user.name} Has Been Banished')
await ctx.guild.kick(user)
bot.run('secret')
Note that I've also removed all references to client in the above. Bot is a subclass of Client, so you can access all the Client methods through Bot.

Categories