How to remove bot pagination response in discord.py - python

So I am using disputils and I've made a pagination embed. however, after it gets inactive the reactions get auto removed by the bot. I want to make the bot remove the whole embed but I've tried a lot of things such as using delete_after=(float) and even asyncio but it doesn't seem to be working.
#commands.group(aliases = ['ra'])
async def red(self, ctx):
if ctx.invoked_subcommand is None:
default = discord.Embed(title="`test`",color=discord.Colour.dark_red())
default.set_image(url="foo")
default.set_footer(text="Image by| user")
v1 = discord.Embed(title="example", description='test', color=discord.Colour.dark_red())
v1.set_footer(text="Info taken from| website")
v2 = discord.Embed(title="spam", description="foo" ,color=discord.Colour.dark_red())
v2.set_footer(text="Info taken from| website")
embeds = [
default,
v1,
v2,
]
paginator = BotEmbedPaginator(ctx, embeds)
await paginator.run()
I tried using delete_after(float) inside the paranthesis of await paginator.run() doesn't work. tried using it asycnio format and got an error Instance of 'BotEmbedPaginator' has no 'delete' member. Any help would be appreciated.

Just use DiscordUtils
Here is an example:
#commands.command()
async def paginate(self, ctx):
embed1 = discord.Embed(color=ctx.author.color).add_field(name="Example", value="Page 1")
embed2 = discord.Embed(color=ctx.author.color).add_field(name="Example", value="Page 2")
embed3 = discord.Embed(color=ctx.author.color).add_field(name="Example", value="Page 3")
paginator = DiscordUtils.Pagination.CustomEmbedPaginator(ctx, remove_reactions=True)
paginator.add_reaction('⏮️', "first")
paginator.add_reaction('⏪', "back")
paginator.add_reaction('🔐', "lock")
paginator.add_reaction('⏩', "next")
paginator.add_reaction('⏭️', "last")
embeds = [embed1, embed2, embed3]
await paginator.run(embeds)

Related

discord.py updating a document in mongodb

I'm trying to make a command that allows the user to update a reason on a warn to something else and I don't know how to update documents in mongodb
check = list(warndb.warn_logs.find({"case_id": caseid}))
for w in check:
reason = w.get('reason')
caseid = w.get('case_id')
change = {{"reason": reason}, {"$set": {"reason": update}}}
w.update(change, upsert=False)
embed = discord.Embed(color=embedcolor, title="Successfully updated reason", description=f"Updated reason for case {caseid}")
embed.add_field(name="**Before:**", value=f"{reason}", inline=False)
embed.add_field(name="**Updated To:**", value=f"{update}", inline=False)
embed.timestamp = datetime.datetime.utcnow()
await ctx.send(embed=embed)
return
Here's the main code that I have to update documents but I'm getting a couple of errors and I don't know how to update documents. please help
So please provide full trace back but here is the code for update your mongo also check documention : Mongo doc.
In a cog it could look like this - arg would be the case id eg "!update_warn 123" then the arg would be 123 and also the case id
cluster = MongoClient('Your mongo link')
collection_name = cluster["Database Name"]["Collection Name"]
#commands.command()
async def update_warn(self,ctx,arg):
check = collection_name.find_one({"case_id": arg})
if check is None:
await ctx.reply("No Case was found!")
else:
reason = check['reason']
caseid = check['case_id']
update = "Your Updated Reason"
collection_name.update_one({'case_id':arg},{'$set':{'reason': update}})
embed = discord.Embed(color=embedcolor, title="Successfully updated reason", description=f"Updated reason for case {caseid}")
embed.add_field(name="**Before:**", value=f"{reason}", inline=False)
embed.add_field(name="**Updated To:**", value=f"{update}", inline=False)
embed.timestamp = datetime.datetime.utcnow()
await ctx.send(embed=embed)

How to use link to JPG as media content in message.edit_media method in aoigram, if it requests JSON object

I'm making test bot using aiogram now and i faced a problem.
I want to edit message media, but i only have a link to an image, and when i try to use an 'edit_media' method aiogram tells me that it can't parse JSON object.
(error)
In documentation said that 'media' parameter must be 'A JSON-serialized object for a new media content of the message'.
Here is my code:
code
#dp.callback_query_handler(kb.item_nav_cb.filter(action='next'))
async def item_next_cb_handler(query: types.CallbackQuery, callback_data: dict):
await bot.answer_callback_query(query.id)
logging.info(callback_data)
current_index = int(callback_data['index'])
current_index += 1
link = df_new['link'].iloc[current_index]
item_info = get_item_info.get_item_info(domen+link)
if link in favourites[f'user_{query.from_user.id}']:
item_kb = kb.get_item_fav_kb(index=current_index,
link=link)
else:
item_kb = kb.get_item_notfav_kb(index=current_index,
link=link)
await query.message.edit_caption(caption=f'<b>{item_info[0]}</b>\n{item_info[1]}\n\nЦена: {item_info[2]}',
reply_markup=item_kb)
await query.message.edit_media(media=item_info[3]) # Here is the problem
Found a solution. Needed to use InputMediaPhoto type:
photo = types.input_media.InputMediaPhoto(item_info[3])
await query.message.edit_media(media=photo)
And all together code looks like this:
#dp.callback_query_handler(kb.item_nav_cb.filter(action='next'))
async def item_next_cb_handler(query: types.CallbackQuery, callback_data: dict):
await bot.answer_callback_query(query.id)
logging.info(callback_data)
current_index = int(callback_data['index'])
current_index += 1
link = df_new['link'].iloc[current_index]
item_info = get_item_info.get_item_info(domen+link)
if link in favourites[f'user_{query.from_user.id}']:
item_kb = kb.get_item_fav_kb(index=current_index,
link=link)
else:
item_kb = kb.get_item_notfav_kb(index=current_index,
link=link)
photo = types.input_media.InputMediaPhoto(item_info[3]) # Makes a difference
await query.message.edit_media(media=photo)
await query.message.edit_caption(caption=f'<b>{item_info[0]}</b>\n{item_info[1]}\n\nЦена: {item_info[2]}',
reply_markup=item_kb)

loop attribute cannot be acessed in non-async contexts with discord.py

When I try to run this code
`
import json
import os
import random
from pprint import pprint
import aiohttp
import discord
import requests
from discord.ext import commands
from dotenv import load_dotenv
from mojang import api
# Functions
# Sends a Get request to a given url
def get_info(call):
r = requests.get(call)
return r.json()
# Get the sum of coins in the bazaar
def get_bazaar_buy_order_value(bazaar_data):
sum_coins = 0
price_increase_threshold = 2
buy_order_values = []
# For every product
for item_name, item_data in bazaar_data.get("products", {}).items():
item_sum_coins = 0
# For every buy order
for idx, buy_order in enumerate(item_data.get("buy_summary", [])):
# If its the best price
if(idx == 0):
item_expected_value = buy_order.get("pricePerUnit", 0)
item_sum_coins += buy_order.get("amount", 0) * buy_order.get("pricePerUnit", 0)
# If its not the best price, check for reasonable price
else:
if(buy_order.get("pricePerUnit", 0) < (item_expected_value * price_increase_threshold)):
item_sum_coins += buy_order.get("amount", 0) * buy_order.get("pricePerUnit", 0)
buy_order_values.append((item_name, item_sum_coins))
sum_coins += item_sum_coins
sort_bazaar_buy_orders_by_value(buy_order_values)
return sum_coins
# Sorts and displays a list of buy order items by total value
def sort_bazaar_buy_orders_by_value(buy_order_values):
# Sort items by values
buy_order_values.sort(key = lambda x: -x[1])
# Display items and values
for (item_name, item_sum_coins) in buy_order_values:
print(f"{item_name.ljust(30, ' ')} | {round(item_sum_coins):,}")
return
# Returns Bazaar data
def get_bazaar_data():
return get_info("https://api.hypixel.net/skyblock/bazaar")
# Returns a specific item from the Bazaar
def get_bazaar_item():
return
# Returns auction info from player uuid
def get_auctions_from_player(uuid):
return get_info(f"https://api.hypixel.net/skyblock/auction?key={API_KEY}&player={uuid}")
# Returns current mayor/election data
def get_election_data():
return get_info(f"https://api.hypixel.net/resources/skyblock/election")
# Returns a list of player profiles
def get_profiles_data():
return get_info(f"https://sky.shiiyu.moe/api/v2/profile/{example_uuid}")
# Returns player UUID when prompted with the name
async def get_uuid(name):
return get_info(f"https://sky.shiiyu.moe/api/v2/profile/{name}")
# Discord Functions / Vars
load_dotenv()
TOKEN = os.getenv('DISCORD_TOKEN')
GUILD = os.getenv('DISCORD_GUILD')
client = discord.Client(intents=discord.Intents.default())
intents = discord.Intents.all()
bot = commands.Bot(command_prefix='/',intents=intents)
# Hypixel Vars
Item = "Diamond"
API_FILE = open("API_KEY.json","r")
example_name = "4748"
example_uuid = "147ab344d3e54952b74a8b0fedee5534"
uuid_dashed = "147ab344-d3e5-4952-b74a-8b0fedee5534"
API_KEY = json.loads(API_FILE.read())["API_KEY"]
example_player_uuid = "147ab344d3e54952b74a8b0fedee5534"
auctions_player_url = f"https://api.hypixel.net/skyblock/auction?key={API_KEY}&player={example_player_uuid}"
# Commands
#bot.command(name='bazaar', description = "Gives a detailed readout of a certain item in the bazaar", brief = "Get data of an item in bazaar")
async def bazaar(ctx):
await ctx.send(get_bazaar_data())
await ctx.send(API_KEY)
#bot.command(name="bazaartotal", description = "Show the total amount of coins on the bazaar at any given point", brief = "Shows the amount of coins in the bazaar")
async def baztot(ctx):
await ctx.send(get_bazaar_buy_order_value(get_bazaar_data()))
#bot.command(name = "apikey", description = "Gives 4748's API key, make sure to remove me once publicly availible!", brief = "API Key")
async def key(ctx):
await ctx.send(API_KEY)
#bot.command(name = "profiles", description = 'Get a list of player profiles and data about them', brief = "List player profiles")
async def prof(ctx):
await ctx.send("Username to check?")
message = client.wait_for('message', check=lambda m: m.user == ctx.user)
username = str(message.content)
uuid = get_uuid(username)
pprint(uuid)
await ctx.send(uuid)
bot.run(TOKEN)
I get this error
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: AttributeError: loop attribute cannot be accessed in non-async contexts. Consider using either an asynchronous main function and passing it to asyncio.run or using asynchronous initialisation hooks such as Client.setup_hook
Anyone have a fix for this? The bot runs normally, but once I try to run /profiles it gives me that error. Also, other commands work fine, but when I try to access an api with a
Changed my code multiple times, putting the get_uuid command in async, and googling for a few hours. any help is appreciated!
Your Bot variable is called bot, but you're using client in your wait_for statement.
You've got both a discord.Client ("client") and a commands.Bot ("bot") instance. This doesn't make a whole lot of sense. If you only need Client features then use Client, if you want Bot features then use Bot. You can't use both at the same time.
Also, wait_for is a coroutine, so you should await it.
# Yours:
message = client.wait_for('message', check=lambda m: m.user == ctx.user)
# ^^^^^^^
# Missing await keyword & wrong bot variable
# Correct:
message = await bot.wait_for(...)
# ^^^^^ ^^^
Docs: https://discordpy.readthedocs.io/en/stable/api.html?highlight=wait_for#discord.Client.wait_for
PS requests is blocking and will make your whole bot freeze. Consider looking into an asynchronous http library like aiohttp.
try to do this:
message = await client.wait_for('message', check=lambda m: m.user == ctx.user)
I advise you to remove the 'name' from the slash command argument, it's better to just name the function and add an additional check for the channel 'm.channel == ctx.channel' to wait_for and split the file into several

Facing issues with a discord.py "hug command"

I am currently making a Discord.py bot that responds to commands with a random image that has been specified, here is my code:
hug_gifs = ['https://c.tenor.com/nHkiUCkS04gAAAAC/anime-hug-hearts.gif']
hug_names = ['Hugs you!']
#bot.command()
async def hug(ctx):
embed = discord.Embed [
colour=(discord.Colour.red()).
description = f"{ctx.author.mention} {(random.choice(hug_names))}"
)
embed.set_image(url=(random.choice(hug_gifs)))
await ctx.send(embed = embed)
There are two mistakes when you are trying to create the discord.Embed:
When passing the arguments to the discord.Embed object, you are starting the initializer with a [, which should be changed to (. In Python the [ and ] shall be used only to create a list or to reference any of its positions.
You are using a dot . as separator for the different arguments taken by the constructor of discord.Embed, but that should be a comma , .
Here is your corrected code:
hug_gifs = ['https://c.tenor.com/nHkiUCkS04gAAAAC/anime-hug-hearts.gif']
hug_names = ['Hugs you!']
#bot.command()
async def hug(ctx):
embed = discord.Embed (
colour=(discord.Colour.red()),
description = f"{ctx.author.mention} {(random.choice(hug_names))}"
)
embed.set_image(url=(random.choice(hug_gifs)))
await ctx.send(embed = embed)

Check if image url is valid

Hello i'm making a Discord bot in Python. I'm making a meme command that gets a random submission from a subreddit. Well there is a little problem with it. When the submission is a video or an unavailble format for Discord, embed can't load the content. So i need to check for submissions format and when it's an unavailble format then the function should be recalled or something like that. I couldn't figure out myself so im asking for help. Here is the code:
#client.command()
async def meme(ctx):
if not hasattr(client, 'nextMeme'):
client.nextMeme = await getMeme()
title, url, img_url, upvotes, comments = client.nextMeme
embedVar = discord.Embed(title=title, url=url, color=discord.Color.random())
embedVar.set_image(url=img_url)
embedVar.set_footer(text=f"👍 {upvotes} | 💬 {comments}")
await ctx.send(embed=embedVar)
client.nextMeme = await getMeme()
async def getMeme():
meme_subreddits = ['dankmemes', 'memes', 'jaharia', 'videoyun']
subreddit = await reddit.subreddit(random.choice(meme_subreddits))
all_subs = []
top = subreddit.top(limit = 52)
async for submission in top:
all_subs.append(submission)
random_sub = random.choice(all_subs)
img_url = random_sub.url
title = random_sub.title
url = random_sub.shortlink
upvotes = random_sub.score
comments = random_sub.num_comments
return title, url, img_url, upvotes, comments
You could check if the image url you're getting ends with a supported file extension, with something like this:
if img_url.endswith(('.jpg', '.png', '.gif', '.jpeg')):
If you wanna try until you get a valid one, just put it in a while loop, something like this should work? I cant test it right now, sorry
img_url = ''
while not img_url.endswith(('.jpg', '.png', '.gif', '.jpeg')):
title, url, img_url, upvotes, comments = client.nextMeme
#rest of your code
You can obviously add more file extensions, these were just the ones I could come up with quickly. Hope this helps you at least a little bit

Categories

Resources