Wavelink - How do i send message when track has started? - python

I am currently making a music bot and I don't know how to send a message when track has started. I have tried this, but doesn't work.
async def on_wavelink_track_start(player: wavelink.Player, track: wavelink.Track):
Ctx = player.ctx
AttributeError: 'Player' object has no attribute 'ctx'.
I don't know what to do because the documentation doesn't say anything about this.
Version of llibraries I am using: Wavelink(1.3.5) and Discord.py(2.0).

Player only has guild as an attribute, which isn't enough to send a message.
You can grab a channel object using its id and use that to send your message. The below assumes that your bot client is named client in your code.
async def on_wavelink_track_start(player: wavelink.Player, track: wavelink.Track):
channel = client.get_channel(123456789) # replace with correct channel id
await channel.send('Message to send')
This is only if you want to use the on_wavelink_tract_start event. You could always just send the message from the command that starts the process using ctx like normal.

Related

Python discord bot send message in a channel

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.

How to send a message to a specific channel as part of a slash command

When I receive a slash command with my bot, I send a modal to a user asking for information.
All this works, however, as part of that, I would also like to send a message to a specific channel on a specific server (guild) to say that a request has been made.
I am having trouble with that second part.
import discord
bot = discord.Bot()
client = discord.Client()
#bot.slash_command(name = "create-trial-request", description = "Create a new trial request from a bbcode template.")
async def trial_request(ctx):
modal = my_modal(title="Fill this in please")
await ctx.send_modal(modal)
class my_modal(discord.ui.Modal):
def __init__(self, *args, **kwargs) -> None:
super().__init__(*args, **kwargs)
self.add_item(discord.ui.InputText(label="Some Label Name"))
async def callback(self, interaction: discord.Interaction):
request_number = request_number_generator()
# here is where I want to send my message to a specific channel.
# I know the ID of that channel, I just don't know how to send the message there.
code_snippet = format_to_code(bbcode)
request_response = "Created request #" + str(request_number)
await interaction.response.send_message(request_response, ephemeral=True)
I have tried the following (placed where my comments are in the code above):
channel = client.get_channel(6648250855168XXXXX)
await channel.send("Created trial request #" + str(request_number))
...but I get: AttributeError: 'NoneType' object has no attribute 'send'
Obviously the bot has access to the channel, and if I write to it as part of the response to the slash command, it successfully writes there, but I can't seem to make it work on its own.
Is there any way to do what I am trying to?
Thanks for any help.
To do so, 1. import commands aka from discord.ext import commands
Then remove your bot = discord.Bot and edit client do it is client = commands.Bot()
thats what i do
Thanks to #3nws, I now know the answer to this question.
The issue in my case was that I was using both client and bot and should have only been using one of the two (in this instance, bot, since I am using slash commands.
There is a usable bot.getchannel command that does what I wanted.
I hope this helps anyone else with the same issue.
First of all: Don't create 2 bot/client instances. Just use commands.Bot once. That's the reason you made a mistake. You used client instead of bot. Replace it and it should work.
Otherwise, if it would be still None, here are some possible reasons why:
• Not subscribed to the relevant intent.
• Wrong key
 ◦ Remember, IDs are ints, not strings
 ◦ If you're trying to copy an emoji ID, right-clicking the emoji in a message will copy message ID
• Bot not logged in, and trying to grab objects from cache
 ◦ Subvairant, using two client objects.
• Bot cannot "see" the object.
 ◦ It has to be on the server, share a server with the member, etc
 ◦ If you're sharded on separate processes, each process will only have objects for that shard.
• Objects retuned by fetch_x will not have a populated cache.
It doesn't make a huge difference if you do bot.get_channel() or bot.get_guild().get_channel(). You can use both.

In Discord.py, how can I use a message ID to store the message as a variable?

I'm trying to make something in discord.py that locates a message from a given message ID and then stores that message as a variable. I can't find anything else so far that can do this. My desired effect is to type in a message ID, store the message as a variable, change the text slightly, and then make the bot say the result.
Please go easy on me, I've only recently started with discord.py.
You can get a message from a message id by using ctx.fetch_message
Note that this method is a coroutine, meaning that it needs to be awaited.
Example
#bot.command()
async def getmsg(ctx, msgID: int):
try:
msg = await ctx.fetch_message(msgID)
except discord.errors.NotFound:
# means that the messageID is invalid
This returns a discord.Message object
To get the message content you just need to access the content attribute of the object
msg_content = msg.content
This example uses the current text channel as the place to find the message
If you want to find a message in a whole server, it's a bit trickier since the fetch_message method is only callable from an abc.Messegeable object, which includes:
• TextChannel
• DMChannel
• GroupChannel
• User
• Member
• Context
So, to get a message from a whole guild,you should probably loop over the channels in a guild, and call the fetch_message on that channel.
Maybe something like this:
#bot.command()
async def getmsg(ctx, msgID: int):
msg = None
for channel in ctx.guild.text_channels:
try:
msg = await channel.fetch_message(msgID)
except discord.errors.NotFound:
continue
if not msg:
# means that the given messageId is invalid
After all this there is just one thing I want to add.
I strongly recommend that you use one of discord.py's forks since discord.py isn't maintained anymore.

How do I send a message to a specific discord channel while in a task loop?

import discord
from discord.ext import commands, tasks
from discord_webhook import DiscordWebhook
client = discord.Client()
bot = commands.Bot(command_prefix="$")
#tasks.loop(seconds=15.0)
async def getAlert():
#do work here
channel = bot.get_channel(channel_id_as_int)
await channel.send("TESTING")
getAlert.start()
bot.run(token)
When I print "channel", I am getting "None" and the program crashes saying "AttributeError: 'NoneType' object has no attribute 'send' ".
My guess is that I am getting the channel before it is available, but I am unsure. Anybody know how I can get this to send a message to a specific channel?
Your bot cannot get the channel straight away, especially if it's not in the bot's cache. Instead, I would recommend to get the server id, make the bot get the server from the id, then get the channel from that server. Do view the revised code below.
#tasks.loop(seconds=15.0)
async def getAlert():
#do work here
guild = bot.get_guild(server_id_as_int)
channel = guild.get_channel(channel_id_as_int)
await channel.send("TESTING")
(Edit: Including answer from comments so others may refer to this)
You should also ensure that your getAlert.start() is in an on_ready() event, as the bot needs to start and enter discord before it would be able to access any guilds or channels.
#bot.event
async def on_ready():
getAlert.start()
print("Ready!")
Helpful links:
discord.ext.tasks.loop - discord.py docs
on_ready event - discord.py docs
bot.get_guild(id) - discord.py docs
guild.get_channel(id) - discord.py docs
"I can't get certain guild with discord.py" - Stackoverflow

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.

Categories