I see error:
(async_telebot.py:529 MainThread) ERROR - TeleBot: "59754269930"
In my code, I handle the callback:
select_item = {}
async def show_items(message, is_update):
with con.cursor() as cursor:
cursor.execute('SELECT * FROM items ORDER BY id ASC')
items = cursor.fetchall()
con.commit()
item = items[select_item[message.from_user.id]]
markup = types.InlineKeyboardMarkup(row_width=8)
btn1 = types.InlineKeyboardButton('one', callback_data='item1')
btn2 = types.InlineKeyboardButton('two', callback_data='item2')
markup.add(btn1, btn2)
msg = 'Test'
if is_update == False:
await bot.send_photo(chat_id=message.chat.id, photo=urllib.request.urlopen(item['image']), caption=msg, reply_markup=markup)
else:
await bot.edit_message_media(chat_id=message.chat.id, message_id=message.id, media=types.InputMedia(type='photo', media=open('start.jpg', 'rb')))
await bot.edit_message_caption(chat_id=message.chat.id, message_id=message.id, caption='edit')
#bot.message_handler()
async def get_user_text(message):
if message.text == 'Items':
if select_item.get('message.from_user.id') is None:
select_item[message.from_user.id] = 0
await show_items(message, False)
#bot.callback_query_handler(func=lambda call: True)
async def callback(call):
if call.message:
if call.data == 'item1':
await show_items(call.message, True)
And I don’t understand what the problem is, I’m a beginner, I need to process for each user the choice of the element that he will now scroll through
Checked data but it's ok
I found a solution:
if call.data == 'item1':
await show_items(call, True)
and
await bot.edit_message_media(chat_id=message.message.chat.id, message_id=message.message.id, media=types.InputMedia(type='photo', media=open('start.jpg', 'rb')))
await bot.edit_message_caption(chat_id=message.message.chat.id, message_id=message.message.id, caption='edit')
I mixed up the object, it referred to the message of the bot and not the user
Related
I'm trying to make the bot wait for a specific message(from a specific author and some specific things) But the bot is just waiting for any message and it makes the command.
Here's the function:
async def check(message):
if type == "netflix":
c.execute("SELECT price FROM netflix")
neprice = c.fetchall()
netprice= neprice[0][0]
netfprice = netprice*amount
nettax = await tax(args=netfprice)
try:
return message.mentions[0].id == 994347081294684240 and message.author.id == 282859044593598464 and int(nettax + netfprice) in message.content
except IndexError:
return False
Here's where I call the function:
await bot.wait_for('message', check=check, timeout=60)
Here's the full command:
#bot.slash_command()
#discord.ext.commands.cooldown(1,60, discord.ext.commands.BucketType.user)
async def buy(message, type: str, amount:Optional[int]):
if amount == None:
amount = 1
if amount < 0:
await message.respond("You cannot buy negative amount of accounts")
member = message.author
con = sqlite3.connect("db.sqlite")
c = con.cursor()
async def check(message):
if type == "netflix":
c.execute("SELECT price FROM netflix")
neprice = c.fetchall()
netprice= neprice[0][0]
netfprice = netprice*amount
nettax = await tax(args=netfprice)
try:
return message.mentions[0].id == 994347081294684240 and message.author.id == 282859044593598464 and int(nettax + netfprice) in message.content
except IndexError:
return False
elif type == "spotify" or "crunchyroll":
c.execute("SELECT price FROM spotify")
spotiprice = c.fetchall()
spotprice = spotiprice[0][0]
newspot = spotprice*amount
spotytax = await tax(args=newspot)
print(spotiprice[0][0])
try:
return message.mentions[0].id == 994347081294684240 and message.author.id == 282859044593598464 and int(newspot + spotytax) in message.content
except IndexError:
return False
if type == "netflix":
c.execute('SELECT *, COUNT(*) AS "count" FROM netflix GROUP BY price')
netamount= c.fetchall()
print(netamount[1])
if netamount[0][3] < amount:
await message.respond(f"We do not have this amount of accounts in the stock")
else:
c.execute("SELECT price FROM netflix ")
netfprice = c.fetchall()
netprice = netfprice[0][0]
newnet = netprice*amount
withtax = await tax(args=newnet)
embed = discord.Embed(title="transfer",description=f"Please transfer :{newnet + withtax}")
embed.add_field(name=f"c <#994347081294684240> {newnet + withtax}",value="**Copy paste the message for no error**")
embed.set_footer(text=f"Sidtho Host. | Requested by - {message.author}")
print("Sent embed, Waiting for receiving the credits")
await message.respond(embed=embed)
await bot.wait_for('message', check=check, timeout=60)
c.execute("SELECT email, password FROM netflix")
netres = c.fetchmany(size=amount)
# print(netres)
embed = discord.Embed(title=f"حساب {type}", description="")
embed.add_field(name="Sidtho Host.",value=" ",inline=False)
for thisamount in netres:
try:
email = thisamount[0]
password= thisamount[1]
embed.add_field(name=f"Email: {email}", value=f"Password: {password}", inline=False)
# print(f"The email is {email} \n The password is {password}
except TypeError as err:
print(f"Gave A TypeError. Where {err} ")
await member.send(embed=embed)
c.execute("DELETE FROM netflix WHERE email=? AND password=?",(email, password))
There is no traceback So no error.
Please note that the check function is a Function, not a command.
and the await bot.wait_for is on a command.
Please note too that type is a value that the user will give to the bot, and its not the python built.
In your code, you wrote await message.respond(...).
There isn't a respond() function in both discord.py and pycord, as far as I know. Try changing it to reply(...) and see if it works.
async def buy(message, type: str, amount:Optional[int]):
#type here the stuff that u want make before the check
def check(m):
return m.mentions[0].id == 994347081294684240 and m.author.id == 282859044593598464 and int(nettax + netfprice) in m.content
try:
response = await client.wait_for('message', check=check, timeout=30.0)
except:
#here u can send a message when the time is done
message.send("timeout")
return
so yeah it should look like this u take the response and run any checks on or save to db.
im trying to code a discord.py bot where you can create embeds through a command, something like the embed creation function in mimu bot. i tried to code it but it dont work, any ways to make it work?
async def embed_create(ctx):
def check(message):
return message.author == ctx.author and message.channel == ctx.channel
await ctx.send('Enter your title.\nPut `none` if you do not want anything in this section.')
await client.wait_for("message", timeout = 300.0, check=check)
if message.content == "none":
title = ""
else:
title = ("message")
await ctx.send('Enter your title.\nPut `none` if you do not want anything in this section.')
await client.wait_for("message", timeout = 300.0, check=check)
if message.content == "none":
desc = ""
else:
desc = ("message")
embed = discord.Embed(title=title.content, description=desc.content, color=0xa9e9e9```
I figured out the problem and fixed it, here:
async def embed_create(ctx):
def check(message):
return message.author == ctx.author and message.channel == ctx.channel
await ctx.send('Enter your title.\nPut `none` if you do not want anything in this section.')
title = await client.wait_for("message", timeout = 300.0, check=check)
title = title.content
if title == "none":
title = "** **" # it will still be empty but not give an empty error message
else:
title = title
await ctx.send('Enter your title.\nPut `none` if you do not want anything in this section.')
desc = await client.wait_for("message", timeout = 300.0, check=check)
desc = desc.content
if desc == "none":
desc = "** **"
else:
desc = desc
embed = discord.Embed(title=title, description=desc, color=0xa9e9e9)
await ctx.send(embed=embed)
So I want my bot to check the database file for a number(0 means off, 1 means on). I have this
#client.event
async def on_message_delete(msg):
db = await asqlite.connect("servers.db")
cursor = await db.cursor()
await cursor.execute(f"SELECT ENABLE_OR_DISABLE_ON_MSG_DELETE FROM Servers WHERE Guild_ID = {msg.guild.id}")
result = await cursor.fetchone()
if result == 0:
return
if result == 1:
myembed = discord.Embed(title= "Deleted Message")
myembed.add_field(name= f'{msg.author} deleted a message(if you want to disable this, just do >disable-del)', value= f'{msg.content}')
await msg.channel.send(embed=myembed)
if msg.author.id == msg.author.bot:
pass
But it doesn't work when I set the value in the db file to 1(whereas it should send a message when someone deletes a message). There's no error either.
you are comparing the row object . this should fix your issue :
result[0] returns first column in the dataset
...
if result["ENABLE_OR_DISABLE_ON_MSG_DELETE"] == 0:
return
if result["ENABLE_OR_DISABLE_ON_MSG_DELETE"] == 1:
myembed = discord.Embed(title= "Deleted Message")
...
I am currently trying to edit an embed with a command. The edited embed has a clear structure. It is supposed to be an evaluation of the suggestion. For this I need the author and his suggestion from the previous command. Is it possible to take the content of the old embed and transfer it to the edited embed if you have two commands? In addition, it would be good to still count and insert the reactions at the message.
Here are my working approaches, except for the missing parts:
##commands.cooldown(1, 100, BucketType.user)
#commands.command(usage="<text>")
async def suggest(self, ctx, *, text: str = None):
"""This is the command for suggestions."""
if text is None:
await ctx.send("**You need to insert a text.**")
return self.suggest.reset_cooldown(ctx)
channel1 = self.bot.get_channel(812284187427864616)
if channel1 == ctx.channel:
channel = self.bot.get_channel(812283430707920906)
e = discord.Embed(color=discord.Colour.green())
e.description = f "**__submitter:__**\n {ctx.author}"
e.add_field(name="__Suggestion:__", value=f"{text}")
e.set_thumbnail(url=ctx.message.author.avatar_url)
e.timestamp = datetime.utcnow()
e.set_footer(text=f "UID: {ctx.author.id}")
feedback = await channel.send(embed=e)
await feedback.add_reaction("✅")
await feedback.add_reaction("❌")
await ctx.message.add_reaction("✅")
The approve command which actually edits the old embed and should insert "Suggestion", "Submitter" and count the reactions.
#commands.command()
async def approve(self, ctx, msg_id: int = None, channel: discord.TextChannel = None):
if not msg_id:
channel = self.bot.get_channel(812283430707920906) # the message's channel
msg_id = 998877665544332211 # the message's id
elif not channel:
channel = ctx.channel
msg = await channel.fetch_message(msg_id)
embed = discord.Embed()
embed.title = "Suggestion accepted"
embed.description = "*Here are all the important information*"
embed.add_field(name="Results", value="✅: MISSING COUNT / ❌: MISSING COUNT")
embed.add_field(name="Suggestion", value=f"MISSING SUGGESTION TEXT")
embed.add_field(name="Submitter:", value=f"MISSING SUBMITTER")
embed.add_field(name="Approved by:", value=f"{ctx.author.mention}")
await msg.edit(embed=embed)
await msg.clear_reactions()
To count the reactions I would use something like:
total_count = 0
for r in message.reactions:
total_count += r.count
EDIT:
This is the embed right now with showing Suggestion two times in different ways.
#commands.command()
async def approve(self, ctx, channel: discord.TextChannel, msgID: int):
try:
msg = await channel.fetch_message(msgID)
embed = msg.embeds[0]
submitter = embed.description[embed.description.find('\n'):]
suggestion = embed.fields[0].value
embed.title = "Suggestion accepted"
embed.description = "*Here are all the important information*"
embed.add_field(name="Results", value="✅: Test/ ❌: Test", inline=False)
embed.add_field(name="Suggestion", value=f"{suggestion}", inline=False)
embed.add_field(name="Submitter", value=f"{submitter}", inline=False)
embed.add_field(name="Approved by", value=f"{ctx.author.mention}", inline=False)
await msg.edit(embed=embed, reference=msgID)
await msg.clear_reactions()
except:
pass
msg = await channel.fetch_message(msg_id)
You can use the fetched message to get details about it.
try:
msg = await channel.fetch_message(msg_id)
embed = msg.embeds[0]
submitter = embed.description[embed.description.find('/n'):] # get submitter name
suggestion = embed.fields[0].value
# other stuff
except:
pass
# possible exceptions message not found, list index out of range(if wrong msg id with no embeds passed as arg)
References:
fetch_message
embeds
message
I have a background loop that will spit out an emoji every X amount of minutes with a reaction attached to it. I want for when someone presses on the reaction of the message, it will delete the message and then send another message saying "messageauthor has grabbed the loot" and then add the amount to the cash json file.
Right now, my code is making the background loop work, but I am not sure how to grab the message.author.id in regards to the background loop so I can reference it in on_reaction_add. The current code is making the bot react once when it spits out the background loop and then again in on_reaction_add. I'm trying to make it wait for a user to react to the background loop message with the same emoji and not the bot.
client = discord.Client()
emoji_msg_grab = {}
try:
with open("cash.json") as fp:
cash = json.load(fp)
except Exception:
cash = {}
def save_cash():
with open("cash.json", "w+") as fp:
json.dump(cash, fp, sort_keys=True, indent=4)
def add_dollars(user: discord.User, dollars: int):
id = user.id
if id not in cash:
cash[id] = {}
cash[id]["dollars"] = cash[id].get("dollars", 0) + dollars
print("{} now has {} dollars".format(user.name, cash[id]["dollars"]))
save_cash()
async def background_loop():
await client.wait_until_ready()
while not client.is_closed:
channel = client.get_channel("479919577279758340")
emojigrab = '💰'
emojimsgid = await client.send_message(channel, emojigrab)
await client.add_reaction(emojimsgid, "💵")
user_id = emojimsgid.author.id
emoji_msg_grab[user_id] = {"emoji_msg_id": emojimsgid.id, "emoji_user_id": user_id}
await asyncio.sleep(600)
#client.event
async def on_reaction_add(reaction, user):
msgid = reaction.message.id
chat = reaction.message.channel
if reaction.emoji == "💵" and msgid == emoji_msg_grab[user.id]["emoji_msg_id"] and user.id == emoji_msg_grab[user.id]["emoji_user_id"]:
emoji_msg_grab[user.id]["emoji_msg_id"] = None
await client.send_message(chat, "{} has grabbed the loot!".format(user.mention))
await client.delete_message(reaction.message)
add_dollars(user, 250)
client.loop.create_task(background_loop())
I would use Client.wait_for_reaction instead of on_reaction_add:
async def background_loop():
await client.wait_until_ready()
channel = client.get_channel("479919577279758340")
while not client.is_closed:
emojigrab = '💰'
emojimsg = await client.send_message(channel, emojigrab)
await client.add_reaction(emojimsg, "💵")
res = await client.wait_for_reaction(emoji="💵", message=emojimsg, timeout=600,
check=lambda reaction, user: user != client.user)
if res: # not None
await client.delete_message(emojimsg)
await client.send_message(channel, "{} has grabbed the loot!".format(res.user.mention))
await asyncio.sleep(1)
add_dollars(res.user, 250)