Is it possible to use .random.choice for urls (specifically gifs)? - python

I'm trying to create a bot that will send a random gif (from the few options I've chosen) upon command.
However, it always comes back as errors, saying that the command wasn't found, even tho I typed in ?hug & attribute errors:
Ignoring exception in command None:
discord.ext.commands.errors.CommandNotFound: Command "hug" is not found
Ignoring exception in command hug:
Ignoring exception in command hug:
Traceback (most recent call last):
File "C:\Users\lemaia\Pictures\Discord\lib\site-packages\discord\ext\commands\core.py", line 83, in wrapped
ret = await coro(*args, **kwargs)
File "C:\Users\lemaia\Documents\DiscordBot\!givebot\v4.0.0.py", line 16, in hug
embed.random.choice(['https://media.discordapp.net/attachments/414964961953972235/570600544226508821/Server_Welcome.gif ', 'https://media.giphy.com/media/l4FGpP4lxGGgK5CBW/giphy.gif', 'https://media.giphy.com/media/fvN5KrNcKKUyX7hNIA/giphy.gif', 'https://tenor.com/view/milk-and-mocha-cuddling-hug-cute-kawaii-gif-12535135'])
AttributeError: 'Embed' object has no attribute 'random'"
embed.random.choice(['https://media.discordapp.net/attachments/414964961953972235/570600544226508821/Server_Welcome.gif ', 'https://media.giphy.com/media/l4FGpP4lxGGgK5CBW/giphy.gif', 'https://media.giphy.com/media/fvN5KrNcKKUyX7hNIA/giphy.gif', 'https://tenor.com/view/milk-and-mocha-cuddling-hug-cute-kawaii-gif-12535135'])
AttributeError: 'Embed' object has no attribute 'random'"
import discord
from discord.ext import commands
import random
client = commands.Bot(command_prefix='?')
#client.event
async def on_ready():
print("Bot is ready for use <3")
print(client.user.name)
print('------------------------')
#client.command()
async def hug(ctx):
embed = discord.Embed(title = 'A hug has been sent!', description = 'warm, fuzzy and comforting <3', color = 0x83B5E3)
embed.random.choice(['https://media.discordapp.net/attachments/414964961953972235/570600544226508821/Server_Welcome.gif ', 'https://media.giphy.com/media/l4FGpP4lxGGgK5CBW/giphy.gif', 'https://media.giphy.com/media/fvN5KrNcKKUyX7hNIA/giphy.gif', 'https://tenor.com/view/milk-and-mocha-cuddling-hug-cute-kawaii-gif-12535135'])
await ctx.channel.send(embed=embed)
client.run('TOKEN')

You trying to use attribute random of Embed object, not call random.choice.
To set image in embed you need to use discord.Embed.set_image:
import discord
from discord.ext import commands
import random
client = commands.Bot(command_prefix='?')
#client.event
async def on_ready():
print("Bot is ready for use <3")
print(client.user.name)
print('------------------------')
#client.command()
async def hug(ctx):
image = random.choice(['https://media.discordapp.net/attachments/414964961953972235/570600544226508821/Server_Welcome.gif', 'https://media.giphy.com/media/l4FGpP4lxGGgK5CBW/giphy.gif', 'https://media.giphy.com/media/fvN5KrNcKKUyX7hNIA/giphy.gif', 'https://tenor.com/view/milk-and-mocha-cuddling-hug-cute-kawaii-gif-12535135']
embed = discord.Embed(title = 'A hug has been sent!', description = 'warm, fuzzy and comforting <3', color = 0x83B5E3)
embed.set_image(url=image))
await ctx.send(embed=embed)
client.run('TOKEN')
Context objects has an send attribute, which is basically alias to Context.channel.send

Related

Trying to send a message to a specific channel from a different file , discord.py

i splitted some code into another file and i get "'NoneType' object has no attribute 'send'"
as i read , its should be a error like "the channel dont exist" "the bot dont have permission"
but tahts wrong , i can send messages just fine from the main.py in the specific channel just not from the loging.py . here my code .
#bot.py
import discord
import asyncio
from discord.ext import commands
import os
from dotenv import load_dotenv
from datetime import datetime, timedelta, date, time, timezone
import time
import loging
load_dotenv()
TOKEN = os.getenv("DISCORD_TOKEN")
bot = commands.Bot(command_prefix=commands.when_mentioned_or("$"), help_command=None)
#bot.command(name='test', help='this command will test')
async def test(ctx):
await loging.comlog(ctx)
bot.run(TOKEN)
#loging.py
import discord
import asyncio
from discord.ext import commands
import os
from datetime import datetime, timedelta, date, time, timezone
import time
bot = commands.Bot(command_prefix=commands.when_mentioned_or("$"), help_command=None)
timestamp = datetime.now()
timenow = str(timestamp.strftime(r"%x, %X"))
async def comlog(ctx):
channel = ctx.channel
channelid = ctx.channel.id
username = ctx.author
usernameid = ctx.author.id
logingchan = await bot.fetch_channel(983811124929630239)
em = discord.Embed(title=f'${ctx.command}', description=f'{timenow}', color=0x00FF00)
em.set_thumbnail(url=username.avatar_url)
em.add_field(name="Channel:", value=f'{ctx.channel.mention} \n{channelid}', inline=True)
em.add_field(name="User:", value=f'{username}\n{usernameid}', inline=True)
print(f'{timenow}: $help: in "{channel}" by "{username}"')
await logingchan.send(embed=em)
await ctx.message.delete()
for testing i replaced the cahnnel with "ctx" and this works just fine
Ignoring exception in command test:
Traceback (most recent call last):
File "C:\Users\Asuka\AppData\Local\Programs\Python\Python310\lib\site-packages\discord\ext\commands\core.py", line 85, in wrapped
ret = await coro(*args, **kwargs)
File "C:\Users\Asuka\Desktop\PROJECT\Discord_Bot\bot.py", line 149, in test
await loging.comlog(ctx)
File "C:\Users\Asuka\Desktop\PROJECT\Discord_Bot\loging.py", line 23, in comlog
await logingchan.send(embed=em)
AttributeError: 'NoneType' object has no attribute 'send'
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "C:\Users\Asuka\AppData\Local\Programs\Python\Python310\lib\site-packages\discord\ext\commands\bot.py", line 939, in invoke
await ctx.command.invoke(ctx)
File "C:\Users\Asuka\AppData\Local\Programs\Python\Python310\lib\site-packages\discord\ext\commands\core.py", line 863, in invoke
await injected(*ctx.args, **ctx.kwargs)
File "C:\Users\Asuka\AppData\Local\Programs\Python\Python310\lib\site-packages\discord\ext\commands\core.py", line 94, in wrapped
raise CommandInvokeError(exc) from exc
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: AttributeError: 'NoneType' object has no attribute 'send'
yea i know ppl say now , the cahnnel dont exist , the bot dont have premmision . false , why can i send in the exact same channel with my main.py but not with the loging.py . also , if i dont send in a specific channel , and send the embed in channel where the command got used , and i use the channel with the id , my bot can reply in the exact same channel.
You have two separate bots in your two modules.
In the bot.py, you make a bot that you later run with the run method. This bot is fine, and it's connected to discord and can do a bunch of things.
However, you made a second bot in logging.py. This bot isn't actually doing anything and it was never started, so any attempts to get or fetch anything from discord will fail. What you need to do is to give the bot instance to the other module.
You can do this by either putting it into a class, or passing the bot as an argument, which I will show here:
async def comlog(bot, ctx):
channel = ctx.channel
channelid = ctx.channel.id
username = ctx.author
usernameid = ctx.author.id
logingchan = await bot.fetch_channel(983811124929630239)
em = discord.Embed(title=f'${ctx.command}', description=f'{timenow}', color=0x00FF00)
em.set_thumbnail(url=username.avatar_url)
em.add_field(name="Channel:", value=f'{ctx.channel.mention} \n{channelid}', inline=True)
em.add_field(name="User:", value=f'{username}\n{usernameid}', inline=True)
print(f'{timenow}: $help: in "{channel}" by "{username}"')
await logingchan.send(embed=em)
await ctx.message.delete()
# Then pass in the bot when you call the function
#bot.command(name='test', help='this command will test')
async def test(ctx):
await loging.comlog(bot, ctx)
Then you can just delete your second bot definition in logging.py.
If you want permission failure messages you need to use try/except:
try:
await logingchan.send(embed=em)
except discord.errors.Forbidden:
# don't have permissions, do something here
There isn't a bot variable in loging.py
If you want to split bot commands you should make cogs instead
Cogs are like command groups
This is how you do it:
# main.py
from discord.ext import commands
from loging import my_commands_cog
bot = commands.Bot(command_prefix = "idk!")
bot.add_cog(my_commands_cog)
# loging.py
from discord.ext import commands
class my_commands_cog(commands.Cog)
#commands.command(name = "idk")
async def idk(ctx, * , arg):
# stuff
print("idk")
Check it out here: Cogs

What's wrong with my discordpy get() method?

So I want to write a funny little discord bot that's in a russian theme. I want to make it play the USSR Anthem no matter what song is requested, in the channel that's written after "&channel" in the command on discord.
This is the console feed I get, when I type "vadim play something &channel Just Chatting blyat:
Privet
Just Chatting
Ignoring exception in on_menter code hereessage
Traceback (most recent call last):
File "C:\Users\maria\AppData\Local\Programs\Python\Python39\lib\site-packages\discord\client.py", line 343, in _run_event
await coro(*args, **kwargs)
File "C:\Users\maria\Desktop\Coding\Projekte\Python\SovjetBot\Code\bot.py", line 33, in on_message
voicechannel = channel.connect()
AttributeError: 'NoneType' object has no attribute 'connect'
Here's my code:
import discord
from discord.utils import get
import time
class MyClient(discord.Client):
#Triggered on login
async def on_ready(self):
print("Privet")
#Triggered on messages
async def on_message(self, message):
if message.author == client.user:
return
if message.content.lower().startswith("vadim") and message.content.lower().endswith("blyat"):
messagearray = message.content.split(" ")
messagearray.pop()
messagearray.remove("vadim")
if messagearray[0].lower() == "play" and ((len(messagearray)) != 1 or messagearray.contains('&channel')):
where = ""
for i in range(messagearray.index("&channel") + 1, len(messagearray)):
where = where + ' ' + messagearray[i]
where = where[0:]
time.sleep(0.25)
print(where)
channel = get(message.guild.channels, name=where)
time.sleep(0.25)
voicechannel = channel.connect()
time.sleep(0.25)
voicechannel.play(discord.FFmpegPCMAudio('National Anthem of USSR.mp3'))
client = MyClient()
client.run(The bots client id)
TLDR
Change
channel = get(message.guild.channels, name=where)
To
channel = await get(message.guild.channels, name=where)
Explanation
There error indicates you have an issue on the line voicechannel = channel.connect() because channel is NoneType. You define channel on the line above with channel = get(message.guild.channels, name=where). However, according to the documentation the get() function you're using is a coroutine so you need to await it.
Side Note
After you create channel, you should check that it's not None before you try to use it with voicechannel = channel.connect().

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()

AttributeError: 'list' object has no attribute 'channel' discord.py

I am trying to create a function that would clear the chat on discord using https://www.youtube.com/watch?v=ZBVaH6nToyM , however I think that I've declared channel (channel = ctx.message.channel) however entering .clear would result in an error
Ignoring exception in command clear
Traceback (most recent call last):
File "C:\Users\mark\AppData\Local\Programs\Python\Python36-
32\lib\site-packages\discord\ext\commands\core.py", line 50, in
wrapped
ret = yield from coro(*args, **kwargs)
File "C:/Users/mark/Desktop/purge.py", line 17, in clear
await client.delete_message(messages)
File "C:\Users\mark\AppData\Local\Programs\Python\Python36-
32\lib\site-packages\discord\client.py", line 1261, in delete_message
channel = message.channel
AttributeError: 'list' object has no attribute 'channel
import discord
from discord.ext import commands
from discord.ext.commands import Bot
TOKEN = "token here"
client = commands.Bot(command_prefix = '.')
#client.event
async def on_ready():
print("Bot is online")
#client.command(pass_context = True)
async def clear(ctx, amount=100):
channel = ctx.message.channel
messages = []
async for message in client.logs_from(channel,limit=int(amount)):
messages.append(messages)
await client.delete_message(messages)
await client.say('message has been deleted')
client.run(TOKEN)
You are basically appending a list itself over and over again
my_list=[]
my_list.append(my_list)
print(my_list)
Which results in something like this
>>[[[...]]
The command should be something like this
#bot.command(pass_context=True)
async def clear(msg,amt:int=20): #can be converted into int via :type
messages=[]
async for i in bot.logs_from(msg.message.channel,limit=amt):
messages.append(i)
await bot.delete_messages(messages)
Also a heads up note, you can't bulk delete messages that are older than 14 days I think meaning that you can't use the delete_messages and only delete it individually

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