Discord.py bot leaving voice channel - python-3.x

I've been making a discord bot which enters a vc plays an audio then leaves, but I can't seem to get the leaving part to work. Here is my code:
# Discord specific import
import discord
from discord.ext import commands
import asyncio
Client = discord.Client()
client = commands.Bot(command_prefix="..")
#client.command(pass_context=True)
async def dan(ctx):
author = ctx.message.author
channel = author.voice_channel
vc = await client.join_voice_channel(channel)
player = vc.create_ffmpeg_player('dan.mp3', after=lambda: print('done'))
player.start()
player.disconnect()
client.run('token')
I'm not getting any errors with this but at the same time the bot is not disconnecting from the vc and I have tried changing 'player' for 'client', 'Client' and 'client.voice'

My problems were that:
I needed to use: await vc.disconnect()
My version of websockets was too high and needed to be below v4.0.0
Hope this helps people with my problem

try vc.disconnect() as stated here in the docs, since Client.join_voice_channel(channel) creates a VoiceClient. Also I suggest not having redundant variables like
author = ctx.message.author
channel = author.voice_channel
When you can have vc = await client.join_voice_channel(ctx.message.author.voice_channel)
Also, another redundant variable is Client = discord.Client() since you don't use it anywhere, you use the commands.Bot instance, so it's best to remove that.

player.disconnect() is a coroutine, you should use the await keyword before it.
await player.disconnect()

Related

Bot not responding discord.py

Here is my code
import discord
from discord.ext import commands
TOKEN = "MY TOKEN"
import random
intent = discord.Intents.default()
intent.members = True
intent.message_content = True
client = discord.Client(intents=intent)
bot = commands.Bot(command_prefix='--', intents=discord.Intents.default())
slap_gif = ['https://media.tenor.com/GBShVmDnx9kAAAAC/anime-slap.gif', 'https://media.tenor.com/CvBTA0GyrogAAAAC/anime-slap.gif', 'https://i.pinimg.com/originals/fe/39/cf/fe39cfc3be04e3cbd7ffdcabb2e1837b.gif', 'https://i.pinimg.com/originals/68/de/67/68de679cc20000570e8a7d9ed9218cd3.gif']
slap_txt = ['Ya, you deserve it', 'Get slapped', 'Ya, get slapped hard']
#client.event
async def on_ready():
print('We have logged in as {0.user}'.format(client))
#bot.command()
async def slap(ctx):
embed = discord.Embed(
color=discord.Color("#ee5253"),
description = f"{ctx.author.mention} {(random.choice(slap_txt))}"
)
embed.set_image(url=(random.choice(slap_gif)))
await ctx.send(embed=embed)
client.run(TOKEN)
I am trying to create a basic gif action bot but it is not working, it was working with on_message but i switched to #bot.command and it is not working now. it runs with no error.
on_message reacts on any text you send.
#bot.command() just reacts to the the command name with the prefix, which would be in your case --slap.
I just can guess, but eventually you didn't send the correct message text.
Because discord.Bot is a subclass of discord.Client you only need exactly one of the two (because you register the command bot, but you run client, the command registered on bot won't work. Also preferably you should keep the discord.Bot instance which is named bot because it as it is a subclass it has more functionality) and you should replace all occurrences of client with that.
Also your bot seems to have the wrong intents. If I change bot = commands.Bot(..., intents=discord.Intents.default()) to bot = commands.Bot(..., intents=intent) it ran the slap function (It has thrown an error for me, but that's not the topic of this question).

Discord.py - Sending to multiple channels

I have a working bot that sends posts from my discord server to another. I'm looking for a way to add additional channels of other servers but can't figure out how to get it to work. I read somewhere that get_channel only works once and that I need to incorporate it into a loop? I'm new to python and discord.py so most likely I just don't understand. Here's my code, Hopefully, someone can help.
import discord
intents = discord.Intents(messages=True, guilds=True)
from discord.ext import commands
test001from=1029028218684055562
test001to=1028777554217291806, 1028777583808098304
bot = commands.Bot(command_prefix = ".");
#bot.event
async def on_ready():
print("Bot Active")
#bot.event
async def on_message(message):
if message.channel.id == test001from:
channeltosend = bot.get_channel(test001to)
await channeltosend.send(message.content)
bot.run("TOKEN")
First, put all the channel ids into a list like so: test001to[1028777554217291806, 1028777583808098304]
Second, use get_channel in the on_ready function and save them as a new list.
Third, use a for loop to iterate through the new list you created for chan in channels and send the message to each channel chan.send(message.content).

Echo a message from another app in discord

I have a bot running in a separate app, but there is a specific variable holding data that I want to also be echo'd on my discord server. The bot itself is huge, but I can pin the specific method here
import discord
import asyncio
import rpChat
global note
class EchoBot(rpChat.ChatClient):
def on_PRI(self, character, message):
super().on_PRI(character, message)
note = character + ": " + message
global note
if message[:1] == "~":
super().PRI("A GameMaster", note)
to try to send this message to discord, I have the following. This is not put in the class above, but just below it, and is not in a class itself:
client = discord.Client()
async def discordEcho():
"""Background task that sends message sent from chat to an appropriate Discord channel
when global messege data is updated"""
await client.wait_until_ready()
channel = client.get_channel(serverroom}
while not client.is_closed():
global note
await channel.send(channel, note)
The data to grab the channel IDs are found in a json
file = open("credentials.json", "r", encoding="utf-8")
info = json.load(file)
file.close()
token = info["discord"]
serverroom = info["serverroom"]
client.loop.create_task(discordEcho())
client.run(token)
When I try this, I obtain:
await client.send_message(channel, message)
AttributeError: 'Client' object has no attribute 'send_message'
And I am unsure why. I have built a bot for both this chat platform, and for discord, but this is the first time I've ever attempted to bridge messages between the two. I am sure what I have offered is clear as mud, but any help would be appreciated, if possible.
Edit:
Edited changes to code. It is working thanks to comment below.
client.send_message is an old, outdated method, it has been replaced with Messageable.send
async def discordEcho():
"""Background task that sends message sent from chat to an appropriate Discord channel
when global messege data is updated"""
await client.wait_until_ready()
channel = client.get_channel(serverroom)
while not client.is_closed():
global note
await channel.send(note)
Side note: you first need to wait_until_ready before getting the channel to wait until the cache is done loading, otherwise channel will be None

discord.py - Join/Leave messages error, doesn't work

Again, my code is not catching up, I have no idea why ...
The console shows no error.
Here is my code:
#bot.event
async def on_member_join(member):
channel = bot.get_channel(792786709350973454)
author = ctx.message.author
ico = author.avatar_url
embed = discord.Embed(
color = discord.Color.red(),
)
embed.set_author(name=(f'• Hello {member} on my server!!'))
embed.add_field(name='Warning,', value='read the regulations!', inline=False)
embed.set_footer(text="dBot created by Diablo#4700", icon_url=ico)
await channel.send(embed=embed)
There are more then one problems in the code snippet. I'll list them all here with fixes.
Firstly the main problem, you are declaring an author variable with ctx.author.name What is ctx here? ctx is passed in commands only. This is an event. It uses member as parameter only you can't use ctx here.
Secondly, the next problem which isn't really playing a part in stopping the command output but is a problem that you are sending member in your embed author message. Again member is an object and you can't use it directly you have to put the attribute after member that you need like, member.name, member.mention, member.avatar_url
Fixed Code:
#bot.event
async def on_member_join(member):
channel = bot.get_channel(792786709350973454)
# author = ctx.message.author # first problem, you don't really need this line
ico = member.avatar_url # since above line is useless you would change this line too
embed = discord.Embed(
color = discord.Color.red(),
)
embed.set_author(name=f'• Hello {member.name} on my server!!') # second problem was here.
embed.add_field(name='Warning,', value='read the regulations!', inline=False)
embed.set_footer(text="dBot created by Diablo#4700", icon_url=ico)
await channel.send(embed=embed)
I have labelled the errors with comments.
(IMPORTANT) Intents:
Just in case you are not aware, You need privileged gateway intents in order to track member events. Make sure to enable both intents from bot section in your application from Developers Portal of Discord and then in your code at the top (where you are initializing bot)...
import discord
from discord.ext import commands
client= commands.Bot(command_prefix="prefix", intents=discord.Intents.all())
...
# rest of the code
References:
on_member_join event
context or ctx
Intents Discord.Py

Add a reaction to a ctx.send message in discord.py

I am making a poll command, the bot will send a ctx message and will say the poll question. I want to make it so when the poll message is sent, the bot adds two reaction, a thumbs up and a thumbs down. I have tried several different ways but non of them work. Here is the code from my latest try (everything is already imported)
reactions = ["👍", "👎"]
#bot.command(pass_context=True)
async def poll(self, ctx, message,*, question):
poll_msg = f"Poll: {question} -{ctx.author}"
reply = await self.bot.say(poll_msg)
for emoji_id in reactions:
emoji = get(ctx.server.emojis, name=emoji_id)
await message.add_reaction(reply, emoji or emoji_id)
The code is all over the place because I tried putting different solutions together to see if it would work but it doesn't work at all.
It looks like you're operating from some old examples. You should read the official documentation to find examples of the modern interfaces.
from discord.ext import commands
from discord.utils import get
bot = commands.Bot("!")
reactions = ["👍", "👎"]
#bot.command()
async def poll(ctx, *, question):
m = await ctx.send(f"Poll: {question} -{ctx.author}")
for name in reactions:
emoji = get(ctx.guild.emojis, name=name)
await m.add_reaction(emoji or name)

Resources