I need to send a private message to the user with help Discord bot.
Using Django + Python.
file path > discordbot(django app)/management/commands/trades.py
i.e I run python manage.py trades
class Command(BaseCommand):
def handle(self, *args, **options):
client = Bot(description="LivePage", command_prefix="-", pm_help = False)
async def send_order():
await client.wait_until_ready()
counter = 0
while not client.is_closed:
user = discord.Object(id = '415618634120167424') # i get my id with using command in the discord client - \# + nickname
await client.send_message(user, 'milkiii')
await asyncio.sleep(5) # task runs every 60 seconds
#client.event
async def on_ready():
print('Use this link to invite {}:'.format(client.user.name))
client.loop.create_task(send_order())
client.run()
But when a script will running I have next message:
Task exception was never retrieved
future: <Task finished coro=<Command.handle.<locals>.send_order() done, defined at /home/worksection/worksection/botdiscord/management/commands/trades.py:24> exception=NotFound('NOT FOUND (status code: 404): Unknown Channel',)>
Traceback (most recent call last):
File "/home/worksection/worksection/botdiscord/management/commands/trades.py", line 41, in send_order
await client.send_message(user, 'milkiii')
File "/home/worksection/env/lib/python3.6/site-packages/discord/client.py", line 1152, in send_message
data = yield from self.http.send_message(channel_id, content, guild_id=guild_id, tts=tts, embed=embed)
File "/home/worksection/env/lib/python3.6/site-packages/discord/http.py", line 198, in request
raise NotFound(r, data)
discord.errors.NotFound: NOT FOUND (status code: 404): Unknown Channel
If I change await client.send_message(user, 'milkiii') to > await client.send_message(415618634120167424, 'milkiii')
I will see next error :
Task exception was never retrieved
future: <Task finished coro=<Command.handle.<locals>.send_order() done, defined at /home/worksec
/worksection/botdiscord/management/commands/trades.py:24> exception=InvalidArgument('Destination
t be Channel, PrivateChannel, User, or Object. Received int',)>
Traceback (most recent call last):
File "/home/worksection/worksection/botdiscord/management/commands/trades.py", line 41, in sen
der
await client.send_message(415618634120167424, 'milkiii')
File "/home/worksection/env/lib/python3.6/site-packages/discord/client.py", line 1145, in send
sage
channel_id, guild_id = yield from self._resolve_destination(destination)
File "/home/worksection/env/lib/python3.6/site-packages/discord/client.py", line 289, in _reso
destination
raise InvalidArgument(fmt.format(destination))
discord.errors.InvalidArgument: Destination must be Channel, PrivateChannel, User, or Object. Re
ed int
Can you help me? :<
Related
Goals
Running multiple bot in the same time with same command
What I've tried
I've coded and searching through internet I found this. I know it's the answer but if I created client1 and client2. Here in my code I just make 1 client (client1)
token1 = getenv("TOKEN1")
token2 = getenv("TOKEN2")
intents = discord.Intents().all()
client1 = commands.Bot(command_prefix = '.', intents = intents)
slash = SlashCommand(client1, sync_commands=True)
client1.remove_command('help')
#client1.event
async def on_ready():
await client1.change_presence(activity=discord.Game(name='Bot Ready'))
print("logged in")
for filename in listdir('cogs'):
if filename.endswith('.py'):
client1.load_extension(f'cogs.{filename[:-3]}')
def meFunction(ctx):
return ctx.author.id == 385053392059236353
loop = asyncio.get_event_loop()
loop.create_task(client1.start(token1))
loop.create_task(client1.start(token2))
loop.run_forever()
And then this warning message appear in my command prompt
client_session: <aiohttp.client.ClientSession object at 0x00000247DB381BE0>
Unclosed connector
connections: ['[(<aiohttp.client_proto.ResponseHandler object at 0x00000247DB370D60>, 2262.609)]']
connector: <aiohttp.connector.TCPConnector object at 0x00000247DB38E280>
Task exception was never retrieved
future: <Task finished name='Task-5' coro=<Client.start() done, defined at C:\Users\chris\AppData\Local\Programs\Python\Python39\lib\site-packages\discord\client.py:649> exception=RuntimeError('Concurrent call to receive() is not allowed')>
Traceback (most recent call last):
File "C:\Users\chris\AppData\Local\Programs\Python\Python39\lib\site-packages\discord\client.py", line 666, in start
await self.connect(reconnect=reconnect)
File "C:\Users\chris\AppData\Local\Programs\Python\Python39\lib\site-packages\discord\client.py", line 566, in connect
await self.ws.poll_event()
File "C:\Users\chris\AppData\Local\Programs\Python\Python39\lib\site-packages\discord\gateway.py", line 555, in poll_event
msg = await self.socket.receive(timeout=self._max_heartbeat_timeout)
File "C:\Users\chris\AppData\Local\Programs\Python\Python39\lib\site-packages\aiohttp\client_ws.py", line 216, in receive
raise RuntimeError("Concurrent call to receive() is not allowed")
RuntimeError: Concurrent call to receive() is not allowed
Last solution what I know is making client2 which is copy of client1
so the idea for the bot is to send an embed to a channel, then resend it with all the embed's attributes but with a new footer.
but the problem i'm running into right now is the new embed has to have the same attributes or less than the old embed to not raise an exception. e.g. author, image, url.
this is the code i'm testing with:
import discord
import os
from discord.ext import commands
intents = discord.Intents.default()
intents.members = True
bot = commands.Bot(command_prefix=',', intents=intents)
#bot.event
async def on_ready():
global test_channel, bot_command_channel, cu_free_games_channel
test_channel = bot.get_channel(868816978293452841)
bot_command_channel = bot.get_channel(808734570283139162)
cu_free_games_channel = bot.get_channel(873018877020373043)
print('bot is ready')
#bot.event
async def on_message(message):
if message.content.startswith('!test'):
embed_old = discord.Embed(
title= '''this is the title''',
description= '''this is the description''',
color= discord.Color.red(),
# url= '''https://www.google.com/'''
)
embed_old.set_footer(text='old footer')
await bot_command_channel.send(embed=embed_old)
if message.channel == bot_command_channel:
if not len(message.embeds):
return
else:
embed_content_in_dict = message.embeds[0].to_dict()
print(embed_content_in_dict) #prints out the embed's content
for embed in embed_content_in_dict:
embed_new = discord.Embed(
title= embed_content_in_dict["title"],
type= embed_content_in_dict["type"],
description= embed_content_in_dict["description"],
url = embed_content_in_dict["url"], # if the URL in embed_old is commented out, it throws an exception
)
embed_new.set_footer(text='new footer')
await test_channel.send(embed=embed_new)
return
bot.run(os.getenv('TOKEN'))
this is what prints in the console:
bot is ready
{'footer': {'text': 'old footer'}, 'color': 15158332, 'type': 'rich', 'description': 'this is the description', 'title': 'this is the title'}
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 47, in on_message
url = embed_content_in_dict["url"], # if the URL in embed_old is commented out, it throws an exception
KeyError: 'url'
someone suggested that i use embed_content_in_dict.get('url') but this still raises an exception (given it's not a real one and only triggers in discord.py 1.7 and not 1.6)
this is the error i get if i use .get('url') :
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 50, in on_message
await test_channel.send(embed=embed_new)
File "/opt/virtualenvs/python3/lib/python3.8/site-packages/discord/abc.py", line 1065, in send
data = await state.http.send_message(channel.id, content, tts=tts, embed=embed,
File "/opt/virtualenvs/python3/lib/python3.8/site-packages/discord/http.py", line 254, in request
raise HTTPException(r, data)
discord.errors.HTTPException: 400 Bad Request (error code: 50035): Invalid Form Body
In embed.url: Scheme "none" is not supported. Scheme must be one of ('http', 'https').
so my question is how can i make the bot resends the original embed with all it's attributes without raising an exception on the latest version?
You can resend an embed and change it's footer (and/or any other attribute) with just three lines:
for embed in message.embeds:
embed.set_footer(text="whatever")
await message.channel.send(embed=embed)
I have a bot that sends dm pings to a user whos Id is given as a parameter in a command.
This is the command:.spam ID #_OF_PINGS
I run into the following error:
Ignoring exception in command spam:
Traceback (most recent call last):
File "/app/.heroku/python/lib/python3.6/site-packages/discord/ext/commands/core.py", line 85, in wrapped
ret = await coro(*args, **kwargs)
File "bot.py", line 16, in spam
await ctx.send(f'Started pinging {user.name} {num} times.')
AttributeError: 'NoneType' object has no attribute 'name'
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/app/.heroku/python/lib/python3.6/site-packages/discord/ext/commands/bot.py", line 903, in invoke
await ctx.command.invoke(ctx)
File "/app/.heroku/python/lib/python3.6/site-packages/discord/ext/commands/core.py", line 859, in invoke
await injected(*ctx.args, **ctx.kwargs)
File "/app/.heroku/python/lib/python3.6/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 'name'
Here is my code:
from discord.ext import commands
token = 'MyBotTokenHere'
prefix = '.'
client = commands.Bot(command_prefix=prefix)
client.remove_command("help")
#client.event
async def on_ready():
print('Ready')
#client.command()
async def spam(ctx, id1: int, num: int):
user = client.get_user(id1)
await ctx.send(f'Started pinging {user.name} {num} times.')
for i in range(num):
await user.send(f'<#{str(id1)}>')
await ctx.send(f'Finished {num} pings for {user.name}')
client.run(token)
It was working fine yesterday, but today, it broke down for some reason.
How do I fix it?
P.S. I hosted it on Heroku
You can use a converter for this:
#client.command()
async def spam(ctx, user: discord.User, num: int):
await ctx.send(f'Started pinging {user.name} {num} times.')
for i in range(num):
await user.send(f'<#{str(id1)}>')
await ctx.send(f'Finished {num} pings for {user.name}')
This way, Discord will automatically try to get the discord.User instance that corresponds to the id that you pass as an argument, and you can also #mention someone if you want to & it'll still work.
Also, starting from Discord 1.5.0, you now need to pass in intents when initializing a bot, which you clearly aren't doing yet. Update your Discord, and use the following to initialize your bot:
intents = discord.Intents.default()
intents.members = True
client = commands.Bot(command_prefix=prefix, intents=intents)
More info on the how's and why's of intents in the relevant API documentation. You'll also want to enable members on your bot's Privileged Intents page, which is explained in the linked API docs as well.
I'm trying to build a discord bot for reaction roles. To do this, I'm trying to use the on_reaction_add combined with fetch_message to check if the reaction added was to the message that the bot sent but I keep getting various error with fetch_message. Here is the code:
#bot.command()
async def createteams(ctx):
msg = await ctx.send("React to get into your teams")
await msg.add_reaction("1️⃣")
await msg.add_reaction("2️⃣")
await msg.add_reaction("3️⃣")
await msg.add_reaction("4️⃣")
await msg.add_reaction("5️⃣")
await msg.add_reaction("6️⃣")
await msg.add_reaction("7️⃣")
await msg.add_reaction("8️⃣")
#bot.event
async def on_reaction_add(reaction, user):
id = reaction.message.id
if await reaction.message.author.fetch_message(reaction.message.id) == "React to get into your teams":
print("Success")
This gives me the error
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/discord/client.py", line 312, in _run_event
await coro(*args, **kwargs)
File "hypixel.py", line 60, in on_reaction_add
fetch = await reaction.message.author.fetch_message(id)
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/discord/abc.py", line 955, in fetch_message
channel = await self._get_channel()
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/discord/member.py", line 243, in _get_channel
ch = await self.create_dm()
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/discord/member.py", line 109, in general
return getattr(self._user, x)(*args, **kwargs)
AttributeError: 'ClientUser' object has no attribute 'create_dm'
But when I go and copy the ID of the message I reacted to, its the same as the printed variable id but it still says Message Not Found
Thanks
I figured out the issue, you can't use fetch_message with user it needs to be channel so I changed my code to
await reaction.message.channel.fetch_message(id)
and it worked :)
I'm trying to get the bot to send a message every few seconds from a set of predefined messages.
import discord
import asyncio
import random
client = discord.Client()
async def background_loop():
await client.wait_until_ready()
while not client.is_closed:
channel = client.get_channel("channel id here")
messages = ["Hello!", "How are you doing?", "Howdy!"]
await client.send_message(channel, random.choice(messages))
await asyncio.sleep(120)
client.loop.create_task(background_loop())
client.run("discord token here")
But when i try too run it, i get this error in the console and no messages are sent into the chat.
/usr/bin/python3.5 /root/PycharmProjects/untitled/Loop.py
Task exception was never retrieved
future: <Task finished coro=<background_loop() done, defined at /root/PycharmProjects/untitled/Loop.py:8> exception=InvalidArgument('Destination must be Channel, PrivateChannel, User, or Object. Received NoneType',)>
Traceback (most recent call last):
File "/usr/lib/python3.5/asyncio/tasks.py", line 239, in _step
result = coro.send(None)
File "/root/PycharmProjects/untitled/Loop.py", line 13, in background_loop
await client.send_message(channel, random.choice(messages))
File "/usr/local/lib/python3.5/dist-packages/discord/client.py", line 1145, in send_message
channel_id, guild_id = yield from self._resolve_destination(destination)
File "/usr/local/lib/python3.5/dist-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
I fixed this by writing a helper function to get the Channel object from the client
def get_channel(channels, channel_name):
for channel in client.get_all_channels():
print(channel)
if channel.name == channel_name:
return channel
return None
client = discord.Client()
general_channel = get_channel(client.get_all_channels(), 'general')
await client.send_message(general_channel, 'test msg')