discord.py button on_interaction - discord

from discord.ext import commands
from discord import app_commands
import json
from discord.ui import Button
with open('.\config.json') as f:
data = json.load(f)
class button(discord.ui.View):
def __init__(self):
super().__init__(timeout=None)
#discord.ui.button(label="Button", style=discord.ButtonStyle.success, custom_id="ver")
async def verify(self, interaction: discord.Interaction, button:discord.ui.Button):
user = interaction.user
role = interaction.guild.get_role(data['verify_role'])
await user.add_roles(role)
await interaction.response.send_message(f"success", ephemeral = True)
class verify(commands.Cog):
def __init__(self, bot: commands.Bot) -> None:
self.bot = bot
#commands.Cog.listener()
async def on_interaction(self, interaction: discord.Interaction):
green = await bot.wait_for("button_click", check = lambda k: k.custom_id == "ver")
await green.send(content="Button smashed!", ephemeral=False)
#app_commands.command(name = "ver", description = "ver")
async def verify(self, interaction: discord.Interaction) -> None:
await interaction.response.send_message(view=button())
async def setup(bot: commands.Bot) -> None:
await bot.add_cog(verify(bot))
I made a verify button, but when I reload the bot, I have to command it again. I want to use on_interaction to prevent him, but I don't have enough understanding of it. How do I get the button to work when the bot is reloaded?

You need to add the view when the cog gets loaded for it to be a persistent view
class verify(commands.Cog):
def __init__(self, bot: commands.Bot) -> None:
self.bot = bot
bot.add_view(button())
Read more on bot.add_view(): https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.Bot.add_view
Example of persistent views:
https://github.com/Rapptz/discord.py/blob/master/examples/views/persistent.py

Related

Is Discord User Id too big to send dm too?

I'm making a slash command that can send dms to a specific user id that's been determined by a command argument. It works for specific user ids, but not all of them, including mine my alt account. Is it some permission thing or is the user id out of range?
My code
import discord
from discord.ext import commands
import os
from dotenv import load_dotenv
# importing environmental vars
load_dotenv()
TOKEN = os.getenv("DISCORD_TOKEN")
GUILD = os.getenv("DISCORD_GUILD")
APP_ID = os.getenv("APP_ID")
PUB_KEY = os.getenv("PUBLIC_KEY")
GUILD_ID = os.getenv("GUILD_ID")
GENERAL_CHAN_ID = os.getenv("CHANNEL_GENERAL_ID")
#finished importing .env vars
intents = discord.Intents.all()
activity = discord.Activity(name="being awesome losers", type = discord.ActivityType.streaming)
bot = discord.Bot(intents=intents, activity=activity)
#bot.event
async def on_ready():
print(f"We have logged in as {bot.user}")
#bot.slash_command(description="sends message to someone still testing",guild_ids=[GUILD_ID])
async def send_message(ctx, user_id: str, message: str):
user = bot.get_user(int(user_id))
await user.send(message)
await ctx.respond("Message sent successfully!", ephemeral = True)
#bot.event
async def on_message(message):
channel = bot.get_channel(956302622170701946)
if message.content.startswith("help"):
await message.author.send('👋')
bot.run(TOKEN)
When I input an ID that doesn't work it gives me this traceback
AttributeError: 'NoneType' object has no attribute 'send'
Traceback (most recent call last):
File "C:\Users\Rayan\source\repos\DBot\DiscordBot\lib\site-packages\discord\commands\core.py", line 124, in wrapped
ret = await coro(arg)
File "C:\Users\Rayan\source\repos\DBot\DiscordBot\lib\site-packages\discord\commands\core.py", line 980, in _invoke
await self.callback(ctx, **kwargs)
File "c:\Users\Rayan\source\repos\DBot\main.py", line 56, in send_message
await user.send(message)
AttributeError: 'NoneType' object has no attribute 'send'
Help is greatly appreciated! Thank you!
I do not think the issue is that the ID is out of range. It's simply that the user is not in the cache.
import discord
from discord.ext import commands
import os
from dotenv import load_dotenv
# importing environmental vars
load_dotenv()
TOKEN = os.getenv("DISCORD_TOKEN")
GUILD = os.getenv("DISCORD_GUILD")
APP_ID = os.getenv("APP_ID")
PUB_KEY = os.getenv("PUBLIC_KEY")
GUILD_ID = os.getenv("GUILD_ID")
GENERAL_CHAN_ID = os.getenv("CHANNEL_GENERAL_ID")
#finished importing .env vars
intents = discord.Intents.all()
activity = discord.Activity(name="being awesome losers", type = discord.ActivityType.streaming)
bot = discord.Bot(intents=intents, activity=activity)
#bot.event
async def on_ready():
print(f"We have logged in as {bot.user}")
#bot.slash_command(description="sends message to someone still testing",guild_ids=[GUILD_ID])
async def send_message(ctx, user_id: str, message: str):
user = await bot.fetch_user(int(user_id))
await user.send(message)
await ctx.respond("Message sent successfully!", ephemeral = True)
#bot.event
async def on_message(message):
channel = bot.get_channel(956302622170701946)
if message.content.startswith("help"):
await message.author.send('👋')
bot.run(TOKEN)
This will always fetch the user and therefore will be able to DM everyone, even not in the cache.

Error with discord bot 1.7.3 giving very long error

I was trying to make a discord chat bot but I got this error I am not sure what to do by the way I am using discord 1.7.3 here is the code by the way the DISCORD KEY and OPENAI-KEY are not the problem those are to hide my openai key and discord bot key:
import discord
import asyncio
import openai
import os
openai.api_key = os.environ.get('OPENAI-KEY')
client = discord.Client()
#client.event
async def on_ready():
print('We have logged in as {0.user}'.format(client))
#client.event
async def on_message(message):
if message.author == client.user:
return
if message.content.startswith('$hello'):
await message.channel.send('Hello!')
elif message.content.startswith('$chat'):
response = openai.Completion.create(
engine="davinci",
prompt=message.content[5:],
max_tokens=100,
temperature=0.9,
top_p=1,
n=1,
stream=False,
logprobs=None,
stop=["\n"],
)
await message.channel.send(response['choices'][0]['text'])
client.run(os.environ.get('DISCORD-TOKEN'))
Here is the error I am getting:
import discord
import asyncio
import openai
import os
openai.api_key = os.environ.get('OPENAI-KEY')
client = discord.Client()
#client.event
async def on_ready():
print('We have logged in as {0.user}'.format(client))
#client.event
async def on_message(message):
if message.author == client.user:
return
if message.content.startswith('$hello'):
await message.channel.send('Hello!')
elif message.content.startswith('$chat'):
response = openai.Completion.create(
engine="davinci",
prompt=message.content[5:],
max_tokens=100,
temperature=0.9,
top_p=1,
n=1,
stream=False,
logprobs=None,
stop=["\n"],
)
await message.channel.send(response['choices'][0]['text'])
client.run(os.environ.get('DISCORD-TOKEN'))
Here is the error I am getting
Traceback (most recent call last):
File "c:\Users\Private\OneDrive\Desktop\Pro\GitHub Repo\Discord_chat_bot\Bot.py", line 35, in <module>
client.run(os.environ.get('DISCORD-TOKEN'))
File "C:\Users\Private\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0\LocalCache\local-packages\Python39\site-packages\discord\client.py", line 723, in run
return future.result()
File "C:\Users\Private\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0\LocalCache\local-packages\Python39\site-packages\discord\client.py", line 702, in runner
await self.start(*args, **kwargs)
File "C:\Users\Private\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0\LocalCache\local-packages\Python39\site-packages\discord\client.py", line 665, in start
await self.login(*args, bot=bot)
File "C:\Users\Private\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0\LocalCache\local-packages\Python39\site-packages\discord\client.py", line 511, in login
await self.http.static_login(token.strip(), bot=bot)
AttributeError: 'NoneType' object has no attribute 'strip'
I was expecting for it to work if I try this code in 2.0.0 discord it give a different error
The reason I am using 1.7.3 not 2.0.0 is because I had a different error and to fix it I had to switch to 1.7.3
Error on this line:
client.run(os.environ.get('DISCORD-TOKEN'))
The token you are passing in is None because os.environ.get('DISCORD-TOKEN') returns None.
You could have forgot to set your environment variable or you had it in a .env file. If you have it in a .env file, please load it:
from dotenv import load_dotenv
load_dotenv()

Discord.py Cogs cooldowns?

I have a problem, when I try to build a cooldown "handler" into a discord.py cog, it sends the message etc., but the cooldown message is still sent and the cooldown doesn't work either.
I've tried everything, but I really can't get any further...
Hope someone has a solution!
Thanks in advance
import discord
from discord.ext import commands
import asyncio
import time
import json
import random
import typing
from colorama import Fore, init
from datetime import timedelta
from discord.ext.commands.cooldowns import BucketType
from discord_components import DiscordComponents, Button, ButtonStyle, Select, SelectOption
init()
with open('config.json', 'r') as f:
config = json.load(f)
prefix = config["prefix"]
token = config["token"]
class Fish(commands.Cog):
#commands.Cog.listener()
async def on_command_error(self, ctx, error):
if isinstance(error, commands.CommandOnCooldown):
await ctx.message.delete()
sec = round(error.retry_after)
td = str(timedelta(seconds=sec))
x = td.split(':')
em = discord.Embed(title=f"Yo, chill and wait {x[0]}h, {x[1]}m, {x[2]}s!", color=0xf1c40f)
em.set_author(name=ctx.author, icon_url=ctx.author.avatar_url)
await ctx.send(embed=em, delete_after=30)
#commands.cooldown(1, 60, commands.BucketType.user)
#commands.guild_only()
#commands.command(aliases=["f"], description='Fish some fishes', help="f")
async def fish(self, ctx):
#code
def setup(client):
client.add_cog(Fish(client))```
I know the answer!
In the on_message method there was the
await self.client.process_commands(message)
because of this, the bot sent 2 messages every time!

Nextcord buttons pagination

I'm trying to do a help command with buttons, I'm using nextcord-ext-menus. But, I can't find a way of switching between embeds without editing 2 embeds when one button is pressed.
I want one button to go to the previous page,one to stop the whole help command/embed & one that will go to the next page. (im new to buttons btw)
I can explain in more detail if you don't understand.
My code:
class MyButtonMenu(menus.ButtonMenu):
def __init__(self):
super().__init__(disable_buttons_after=True)
async def send_initial_message(self, ctx, channel):
return await channel.send(f'Hello {ctx.author}', view=self)
#nextcord.ui.button(style=nextcord.ButtonStyle.blurple,emoji="<:left:968157460626047026>")
async def on_thumbs_up(self, button, interaction):
embe = nextcord.Embed(description=f"is it working? /1")
await self.message.edit(embed=embe)
#nextcord.ui.button(emoji="\N{THUMBS DOWN SIGN}")
async def on_thumbs_down(self, button, interaction):
emb = nextcord.Embed(description="WOAH TY !!!")
await self.message.edit(embed=emb)
#nextcord.ui.button(emoji="\N{BLACK SQUARE FOR STOP}\ufe0f")
async def on_stop(self, button, interaction):
self.stop()
#bot.command()
async def pages(ctx):
await MyButtonMenu().start(ctx)

Improving upon discord MassDM bot

import discord
from discord.ext import commands
import platform
import random
import time
bot = commands.Bot(command_prefix='+', case_insensitive=True)
#bot.event
async def on_ready():
print(f'Logged in as {bot.user.name}(ID: +{bot.user.id}) |'
f'Connected to {str(len(bot.guilds))} servers |'
f'Connected to {str(len(set(bot.get_all_members())))} users')
print('--------')
print('CREATED AND HOSTED BY Fataldagod | Fixed Version')
#bot.event
async def on_command_error(ctx, error):
# Ignore these errors:
ignored = (
commands.CommandNotFound, commands.UserInputError, commands.BotMissingPermissions,
commands.MissingPermissions, discord.errors.Forbidden, commands.CommandInvokeError,
commands.MissingRequiredArgument)
if isinstance(error, ignored):
return
#bot.command(pass_context=True)
#commands.has_permissions(kick_members=True)
async def userinfo(ctx, user: discord.Member):
try:
embed = discord.Embed(title="{}'s info".format(user.name),
description="Here's what I could find.",
color=discord.Colour.dark_red())
embed.add_field(name="Name", value=user.name, inline=True)
embed.add_field(name="ID", value=user.id, inline=True)
embed.add_field(name="Status", value=user.status, inline=True)
embed.add_field(name="Highest role", value=user.top_role)
embed.add_field(name="Joined", value=user.joined_at)
embed.set_thumbnail(url=user.avatar_url)
await ctx.send(embed=embed)
except:
await ctx.send("Missing Requrired Args")
#commands.has_permissions(administrator=True)
#bot.command(pass_context=True)
async def send(ctx, *, content: str):
for member in ctx.guild.members:
c = await member.create_dm()
try:
await c.send(content)
await ctx.send("MassDM message sent to: {} ".format(member))
except Exception:
await ctx.send("MassDM message blocked by: {} ".format(member))
Was wondering what I can change to make it so the bot DMs specific roles rather than the entire server?
For example instead of me typing +send (message) I'd like to type +send #role1 #role2 role3 #role4 (message) or something along these lines.
Any help is much appreciated.

Resources