Python discord bot send message in a channel - python

I'm trying to run a very simple program: it should check for a string in a link, and in case of a true or false result it should send a different message to a discord channel. The part that verifies the link works, the problem is the part that sends the message, I tried to do it again in different ways but I can't get it to work, this is the code:
#client.command()
async def check_if_live():
global live
contents = requests.get('https://www.twitch.tv/im_marcotv').content.decode('utf-8')
channel = client.get_channel(1005529902528860222)
if 'isLiveBroadcast' in contents:
print('live')
live = True
await channel.send('live')
else:
print('not live')
live = False
await channel.send('not live')
In other parts of the code where I send a message in response to a command using await message.channel.send("message")everything works as expected.
I have done a lot of research but can't find anything useful.
*edit:
With the code above the error is 'NoneType' object has no attribute 'send' on the line await channel.send('not live'), if i try to do as suggested by Artie Vandelay inserting await client.fetch_channel(1005529902528860222) before channel = client.get_channel(1005529902528860222) on the inserted line I have an error 'NoneType' object has no attribute 'request'.
Since I think that at this point it may have a certain value, I also insert the code sections about the client variable.
client = discord.Client()
load_dotenv()
TOKEN = os.getenv('TOKEN')
#all bot code
client.run(TOKEN)
I also tried this:
bot = commands.Bot(command_prefix='!')
load_dotenv()
TOKEN = os.getenv('TOKEN')
#bot.command()
#all bot code
bot.run(TOKEN)
Both methods return errors

Double check if your channel id is correct.
Also try using
.text
instead of
.content.decode('utf-8')
if it still does not work, please send your error message, so we can see what is wrong.

I answer my question because I found a solution, instead of using #bot.command I used #bot.event async def on_ready(), and now it works, I hope this answer can be useful to someone else who has this same problem.

Related

What is and How to fix this error in discord.py?

I was using replit (maybe because replit doesnt work?) tryoing to make some code for a Discord bot when I saw this:
Type error: __init__ missing 1 required keyword-only argument: "intents"
Im not really sure what is means
Heres my code (BTW i used pip install discord in shell)
`
import discord
token = "mytoken (not revealing it i guess)"# but even with right token it doesnt work
client = discord.Client()
name = "MIIB.BOT_v1.0"
#client.event
async def on_ready():
print("Bot logged in as ", name, "!")
client.run(token)
on_ready()
#i did *****pip install discord****** in shell btw
`
I tried some variations but not much. I expected:
Bot logged in as botname#6969
Replace
client = discord.Client()
with
client = discord.Client(intents=discord.Intents.default())
As per recently(-ish), you need to specify the intents your bot uses when login to the API, so you should populate the Client argument with an intent object.
Calling the default intents, if you don't plan on doing anything with any other that you might need to enable, would look like this
bot_intents = discord.Intents.default()
client = discord.Client(intents=bot_intents)

How to program a discord.py bot to dm me when a command is used by another person?

I want to create a command that people can use to send suggestions to me. They'd use the command "!suggest", followed by their input, and the bot privately dms that whole message to me. However I am struggling with making the bot dm me instead of the author of the command.
if message.content.startswith('!suggest'):
await message.author.send(message.content)
The problem here lies with the author part in the code- instead of dming me every time, it will dm the person who typed the command, which is useless to me. How can I replace 'author' with my discord ID, to make it dm me and only me with the message? I've asked this before and all answers have not worked for me. These are the solution's I've gotten that did not work:
message.author.dm_channel.send("message"), but that is the same problem, it does not get rid of the author issue.
me = await client.get_user_info('MY_SNOWFLAKE_ID')
await client.send_message(me, "Hello!")
This code also did not work for me. The user that it is dming is the same each time, so I have no need to run the get_user_info in the first place. And whenever the second line runs, I get an error code because the MyClient cannot use the send_message attribute.
Your code is from the old discord version. It has been changed in the discord.py rewrite. I also recommend you to use discord.ext.commands instead of using on_message to read commands manually.
As for the dm, simply use
your_id = 123456789012345678
me = client.get_user(your_id)
await me.send("Hello")
Note that it requires members intents enabled. Use await fetch_user(your_id) if you don't have it enabled. Also, note that there might be also rate-limiting consequences if multiple users use commands simultaneously.
Docs:
get_user
fetch_user
User.send
#client.command()
async def suggest(ctx, message = None):
if message == None:
await ctx.send("Provide a suggestion")
else:
await ctx.{your_id}.send("message")
Please don't mind the indent
You can dm a user by doing this:
user = client.get_user(your_id_here)
await user.send('work!')
FAQ : https://discordpy.readthedocs.io/en/stable/faq.html#how-do-i-send-a-dm
if you want the full code here it is:
#client.command()
async def suggest(ctx, *, suggest_text):
user_suggestor = ctx.author
user = client.get_user(user_id) # replace the user_id to your user id
if suggest_text == None:
await ctx.send("Enter your suggestion! example : !suggest {your suggest here}")
else:
await user.send(f"{user_suggestor.name} sent an suggestion! \nSuggestion : {suggest_text}") # the \n thing is to space
thank me later :D

How to make a discord.py bot send a message through the console to a specific channel

discord.py - Send messages though console - This question is outdated so I'm going to try and re-ask as the solutions provided there do not work.
I want my discord bot to send a message to a specific channel through input in the console. My code is as follows:
channel_entry = 614001879831150605
msg_entry = 'test'
#client.event
async def send2():
channel = client.get_channel(channel_entry.get)
await channel.send(msg_entry)
I get the following error:
AttributeError: 'NoneType' object has no attribute 'send'
Any help is appreciated.
You don't need to register this as a client.event as you are not reacting to something that happens in Discord, that means the decorator is not needed.
I have to say I am quite confused why you are using get on an integer in channel_entry.get. Just use the integer by itself. This is probably the source of your error. Because you are not passing an integer to client.get_channel it returns a None object, because no channel has been found. documentation
Working example:
channel_entry = 614001879831150605
msg_entry = 'test'
async def send_channel_entry():
channel = client.get_channel(channel_entry)
await channel.send(msg_entry)
Also make sure you have the latest version of discord.py installed.

(discord.py) How do I get my bot to read DM's that are sent to it and either print them or send them to a specific channel

So I recently created a discord bot with various meme commands and moderating commands. I am relatively new to python but I understand the gist of it. I have already created a command that lets me(only me) DM a user through the bot. I now want to try and make the bot be able to read the messages that are sent back to it and send them to me, whether its printed in shell or sent to a specific channel/me I don't care, I just want to be able to see what is sent to it.
I did some reading around and found this, and from that I collected this:
#bot.event
async def on_message(message):
channel = bot.get_channel('channel ID')
if message.server is None and message.author != bot.user:
await bot.send_message(channel, message.content)
await bot.process_commands(message)
This alone has not worked for me, I get an error saying that "AttributeError: 'Message' object has no attribute 'server'" when I DM'ed the bot. I was told that discord.py rewrite does not use 'server', but rather 'guild'. So I changed it to say message.guild. From there it gave me the error "AttributeError: 'Bot' object has no attribute 'send_message'", and that's about as far as I got there. I've tinkered with it and changed things here and there and made some slight progress...I think. My new code is:
#bot.event
async def on_message(ctx, message):
channel = bot.get_channel('channel ID')
if message.guild is None and message.author != bot.user:
await ctx.send(channel, message.content)
await bot.process_commands(message)
This gives me the error "TypeError: on_message() missing 1 required positional argument: 'message'".
That is as far as I've gotten now. Any help would be appreciated, as I said, I'm still somewhat new to python, I've only started using it about 2 months ago.
You're using the ctx parameter, which is unique to commands.
'ctx' is commands.Context, which provides information about commands that are executed.
Since this isn't a command, but rather an event, you shouldn't provide it.
Untested, but this should do the trick:
(I made it so it ignores messages from ALL bots, to avoid spam)
for printing messages to console
#bot.event
async def on_message(message: discord.Message):
if message.guild is None and not message.author.bot:
print(message.content)
await bot.process_commands(message)
for dumping message contents to a channel
msg_dump_channel = 1234
#bot.event
async def on_message(message: discord.Message):
channel = bot.get_channel(msg_dump_channel)
if message.guild is None and not message.author.bot:
# if the channel is public at all, make sure to sanitize this first
await channel.send(message.content)
await bot.process_commands(message)
Your first code is using ancient, outdated and unsupported dpy version.
You mostly updated it correctly in the second code except for few mistakes like the on_message event.
It is not working because it only takes one argument message, there is no ctx in that event.
So the event is passing one argument but your function takes 2 thus the error. The correct code would be:
async def on_message(message):
But now you'll be confused what to do with this line you wrote:
await ctx.send(channel, message.content)
Even if ctx existed this wouldn't work because send doesn't take destination anymore, instead you call send on destination destination.send("Hello") so translated to your code if the channel is where you want to send it would be await channel.send(message.content)
Also one final note I noticed that you used string here:
bot.get_channel('channel ID') this could be you just giving example but just remember that IDs are ints, if you pass string it will never find that channel.
For example this is invalid:
bot.get_channel('123456789111315178')
And this would be valid: bot.get_channel(123456789111315178)
Based on that error, I'd say you're likely calling on_message() at some point and not giving the message parameter. Look through your code and see if that's maybe the case.
Alternatively, if it's some other code you haven't written that's calling your function, then it might only be calling on_message() with one argument, in which case the ctx argument might be incompatible with that function.

Why is my discord bot spamming?

I have previously posted on this same bot and got it working thanks to the people who responded. But, while it finally came to life and turned on, it started spamming messages for no apparent reason. I've looked over the code for typos and can't find any.
Here's the code:
import discord
from discord.ext.commands import bot
from discord.ext import commands
import asyncio
import time
Client = discord.Client()
client = commands.Bot (command_prefix = discord)
#client.event
async def on_ready() :
print("Bepis machine fixed")
#client.event
async def on_message(message) :
if message.content == "bepis" :
await client.send_message (message.channel, "bepis")
client.run("Censored Bot Token")
after #client.event is where i need help. also the bottom line if fine this time! turns out i had hit the space bar before the parenthesis and it didn't like that. Help is very appreciated so i can continue adding on to this awesome bot.
It looks like you are sending a message "bepis" in response to the first, then every, message "bepis" - presumably your first response will appear as an entry on the incoming feed which will trigger a second, etc.
Turns out I was not using proper formatting for my bot.
Whenever you say "bepis" in the discord server, the bot will see it and then say "bepis" back, as its intended to do, but, because of my improper formatting, the bot saw itself say "bepis" and responded as if someone else was saying "bepis".
Old lines:
if message.content == "bepis" :
await client.send_message(message.channel, "bepis")
New lines:
if message.content.startswith('bepis'):
await client.send_message(message.channel, "bepis")
So make sure you're using the right format if you're making a bot!
You seemed to already know what the problem is, from this answer you posted. But your solution is far from being able to solve the problem.
on_message is called whenever a new message is sent to anywhere accessible by the bot; therefore, when you type in "bepis" in discord, the bot replies with "bepis", then the message sent by the bot goes into on_message, which the bot re-replies "bepis", and so on...
The simple solution is to check if the message's author is any bot account, or if you want, if the message's author is your bot.
from discord.ext import commands
client = commands.Bot(command_prefix=None)
#client.event
async def on_ready():
print("Bepis machine fixed")
#client.event
async def on_message(message):
# or `if message.author.bot:` # which checks for any bot account
if message.author == client.user:
return
if message.content == "bepis":
await client.send_message(message.channel, "bepis")
client.run("Token")
Note: I also fixed many of your other problems, such as multiple unused imports, another Client, and indentation.
And FYI, command_prefix is only used when command is being processed by a functional command. When you use on_message it has no use, which means you can set it to None.

Categories