How to display an image immediately in the aiogram chat? - python

#dp.message_handler(lambda message: message.text == "Python")
async def python(message: types.Message):
keyboard: InlineKeyboardMarkup = InlineKeyboardMarkup(resize_keyboard=True)
url_button_1: InlineKeyboardButton = InlineKeyboardButton(text=f"Road", url='https://***')
url_button_2: InlineKeyboardButton = InlineKeyboardButton(text=f"Tasks", url='https://***')
url_button_3: InlineKeyboardButton = InlineKeyboardButton(text=f"Books", url='https://***')
url_button_4: InlineKeyboardButton = InlineKeyboardButton(text=f"Text", url='https://***')
keyboard.add(url_button_1)
keyboard.add(url_button_2)
keyboard.add(url_button_3)
keyboard.add(url_button_4)
await message.answer(text=f"Select the necessary sources", reply_markup=keyboard)
How do I make sure that by clicking on any of these buttons, a picture is immediately displayed to the user in the chat?
With this option, you still need to click on the link, which works longer:
url_button_2: InlineKeyboardButton = InlineKeyboardButton(text=f"Tasks", url='https://***')

Related

Clicking on button in discord channel does not execute the code in on_button_click

The purpose of this code is to
create the channel if it doesnt exist (this works) and write a welcome message in it (this works)
when you type in !open_ticket it should create a button and display it along with a message (this works)
click the button and it will create a new channel with the users name as part of it (this does not work)
the print does not display in the terminal so it tells me the code is never even executed.
Why?
import discord
from discord.ext import commands
from helperfunctions import create_default_message
token = 'my token'
my_guild = 'guild name'
channel_name = 'support-tx'
intents = discord.Intents.all()
intents.members = True
intents.message_content = True
bot = commands.Bot(command_prefix='!', intents=intents.all())
#bot.event
async def on_ready():
for guild in bot.guilds:
if guild.name == my_guild:
break
for channel in guild.channels:
if channel.name == channel_name:
print("support tickets channel already created")
bCF = True #channel found
break
else:
bCF = False
#create support tickets channel if it doesnt exist
if not bCF:
await guild.create_text_channel(channel_name)
#await sync_channel_permissions(guild,channel_name) #this isnt working
#create the initial message if it doesnt exist
await create_default_message(bot,channel_name)
print(
f"{bot.user} is connected to the following guild:\n"
f"{guild.name}(id: {guild.id})"
)
#bot.event
async def on_message(message):
if message.author == bot.user: #make sure bot doesnt read its own messages
return
#message_content = message.content.lower()
await bot.process_commands(message)
#bot.command()
#using !open_ticket in the discord chat, this should create a button and type a message
async def open_ticket(ctx):
print("hello function executed")
view = discord.ui.View()
button = discord.ui.Button(label="Open Ticket", custom_id="openTicket")
view.add_item(button)
view.timeout = None # set the view timeout to None
bot.add_view(view) # register the view with the bot
await ctx.send("Click the button to open a new support ticket.",view=view)
#bot.event
#clicking on the above button should run this code but it does not, the print line doesn't show in the console
async def on_button_click(interaction: discord.Interaction):
print(f"Button clicked by {interaction.user}")
if interaction.component.custom_id == "openTicket":
print("Button clicked") # Add this line to check if the function is being executed
user = interaction.user
guild = interaction.guild
channel_name = f"{user.name}'s Ticket"
overwrites = {
guild.default_role: discord.PermissionOverwrite(read_messages=False),
user: discord.PermissionOverwrite(read_messages=True)
}
new_channel = await guild.create_text_channel(channel_name, overwrites=overwrites)
await interaction.respond(content=f"Hello {user.mention}! Your ticket has been created in {new_channel.mention}.")
bot.run(token)
There's no event called on_button_click - that function is never getting called. We need to give the button a callback function for it actually to run when the button is pressed.
There's a couple of ways we could do this. I've modified a section of your code so that we're setting the button's callback function equal to the on_button_click function you've defined. Can see the docs for that here. I removed the checking of the button pressed as well as that's not necessary when we're setting it to the callback of the button directly.
async def on_button_click(interaction: discord.Interaction):
print(f"Button clicked by {interaction.user}")
print("Button clicked") # Add this line to check if the function is being executed
user = interaction.user
guild = interaction.guild
channel_name = f"{user.name}'s Ticket"
overwrites = {
guild.default_role: discord.PermissionOverwrite(read_messages=False),
user: discord.PermissionOverwrite(read_messages=True)
}
new_channel = await guild.create_text_channel(channel_name, overwrites=overwrites)
await interaction.respond(content=f"Hello {user.mention}! Your ticket has been created in {new_channel.mention}.")
#bot.command()
async def open_ticket(ctx):
print("hello function executed")
view = discord.ui.View()
button = discord.ui.Button(label="Open Ticket", custom_id="openTicket")
button.callback = on_button_click
view.add_item(button)
view.timeout = None # set the view timeout to None
bot.add_view(view) # register the view with the bot
await ctx.send("Click the button to open a new support ticket.",view=view)

Adding a cooldown to a button (Pycord 2.0.0b4)

I'm working on a Discord bot using Pycord 2.0.0b4 and am trying to implement buttons with a 3 second cooldown per user.
I want the bot to send a cooldown message if someone tries clicking the button during the cooldown (e.g. try again in x seconds), or respond with the embed embed1 otherwise.
Here's what I'm working with:
class yeetView(discord.ui.View):
#discord.ui.button(label='Yeet Again', style=discord.ButtonStyle.primary, emoji='🚀')
async def button_callback(self, button, interaction):
embed1 = await reYeetAlgo(interaction, interaction.user.id)
await interaction.response.send_message(embed=embed1, view=yeetView())
# Button click awaits some other async function reYeetAlgo, which returns Embed object embed1, which is then sent on Discord as an embed along with another button to run the function again if the user so chooses.
I have cooldowns on other commands with a similar cooldown time using #commands.cooldown(1, 3, commands.BucketType.user), but the decorator only works because they are commands. So I'm looking for something that applies the same thing but to buttons/interactions. Thanks
It is pretty easy
class yeetView(discord.ui.View):
def __init__(self) -> None:
super().__init__(timeout = None)
self.cooldown = commands.CooldownMapping.from_cooldown(1, 60,
commands.BucketType.member)
#discord.ui.button(label='Yeet Again', style=discord.ButtonStyle.primary, emoji='🚀')
async def button_callback(self, button, interaction):
bucket = self.cooldown.get_bucket(interaction.message)
retry = bucket.update_rate_limit()
if retry:
return await interaction.response.send_message(f"Slow down! Try
again in {round(retry, 1)} seconds.", ephemeral = True)
embed1 = await reYeetAlgo(interaction, interaction.user.id)
await interaction.response.send_message(embed=embed1, view=yeetView())

Discord.py Button Interaction Failed at user click

I'm trying to create a verification function for Discord Bot using buttons. I have tried creating it, but not sure if it works (testing purpose) .
I need it to give a role to verify a user like a role called Verified, would also like a suggestion on how I can make it not a command and just make it a embed in a single channel where new members can just simply click on it and get the role to be verified.
I'm not getting any errors in the console of development, it's just saying when I click the button in the UI (Discord App) I get an message saying "Interaction failed".
#client.command()
async def verify(ctx):
member = ctx.message.author
role = get(member.guild.roles, name="Sexy EGirl")
await ctx.send(
embed = discord.Embed(description="Click below to verify", color=getcolor(client.user.avatar_url)),
components = [
Button(style=ButtonStyle.blue, label = 'Verify')
]
)
interaction = await client.wait_for("button_click", check=lambda i: i.component.label.startswith("Verify"))
await interaction.respond(member.add_roles(role))
You get "Interaction failed", if you don't send a respond message.
#client.event
async def on_button_click(interaction):
message = interaction.message
button_id = interaction.component.id
if button_id == "verify_button":
member = message.guild.get_member(interaction.user.id)
role = message.guild.get_role(859852728260231198) # replace role_id with your roleID
await member.add_roles(role)
response = await interaction.respond(embed=discord.Embed(title="Verified"))
#client.command()
#commands.has_permissions(administrator=True) # you need to import command from discord.ext if you want to use this -> from discord.ext import commands
async def verify(ctx):
await ctx.send(
embed=discord.Embed(title="Embed - Title", description="Click below to verify"),
components=[
Button(style=ButtonStyle.blue, label='Verify', custom_id="verify_button")
])
With this code you are able to send an embed with a verify button in a channel. (if you have administrator permissions) Then the user can press on the button and the on_button_click event will be triggered.
To handle the Interaction failed, you are sending a respond message.

Python Telepot bot inline keybard

I am building a bot in Python using Telepot. I am able to have it respond to commands but when i implement an inline keyboard i do not know how to call on them. I know it must be callbackquery but i cannot find how to implement it.
Any help would be appreciated.
import sys
import time
import telepot
from telepot.namedtuple import ReplyKeyboardMarkup, KeyboardButton, InlineKeyboardMarkup, InlineKeyboardButton
def on_chat_message(msg):
content_type, chat_type, chat_id = telepot.glance(msg)
print('Chat Message:', content_type, chat_type, chat_id)
if content_type == 'text':
if msg['text'] == '/start':
bot.sendMessage(chat_id, 'Welcome to #UK_Cali Teleshop\n Created by JonSnow 2021',reply_markup = InlineKeyboardMarkup(inline_keyboard=[
[InlineKeyboardButton(text="Feedback",callback_data='a'), InlineKeyboardButton(text="You",callback_data='b'),InlineKeyboardButton(text="PGP",callback_data='c'), InlineKeyboardButton(text="Cunt",callback_data='d')],
[InlineKeyboardButton(text="Products",callback_data='e')]
]
))
bot.answerCallbackQuery(callback_query_id)
bot = telepot.Bot('1646167995:AAGsOwfjcryYYkoah69QJ6XGA7koUywmuRk')
print('Listening ...')
bot.message_loop({'chat': on_chat_message}, run_forever=True)
bot = telepot.Bot('TOKEN')
import time
import telepot
from telepot.loop import MessageLoop
from telepot.namedtuple import InlineKeyboardMarkup, InlineKeyboardButton
TOKEN = "super secret bot token"
def on_chat_message(msg):
#here you handel messages and create the iniline keyboard
content_type, chat_type, chat_id = telepot.glance(msg)
keyboard = InlineKeyboardMarkup(inline_keyboard=[
[InlineKeyboardButton(text='button text', callback_data='callback query data for reconizing it')],
])
def on_callback_query(msg):
#here you handels callback querys,
#the event that are fired when user clickan inline keyboard'sbutton
query_id, from_id, query_data = telepot.glance(msg, flavor='callback_query')
#do something based on the callback query,
#to recognize the button pressed check query_data,
#that corresponds to he callback_data setted when creating the button
bot = telepot.Bot(TOKEN)
MessageLoop(bot, {'chat': on_chat_message,
'callback_query': on_callback_query}).run_as_thread()
while True:
time.sleep(10)

How do you make the python bot click on the button in the telegram bot

I want to make a bot click for Telegram. The problem is I'm confused about how I clicked it using my code, I tried it but it still failed and the bot didn't click, what data should be posted so that the bot clicks on the telegram bot. I need your help. This is my source code :
from telethon import TelegramClient, events, sync
from telethon.tl.functions.messages import GetHistoryRequest, GetBotCallbackAnswerRequest
api_id = 974119
api_hash = 'a483ea002564cdaa0499a08126abe4a3'
client = TelegramClient('session_name', api_id, api_hash)
client.start()
channel_username = 'GOOGLE'
channel_entity = client.get_entity(channel_username)
posts = client(GetHistoryRequest(
peer=channel_entity,
limit=1,
offset_date=None,
offset_id=0,
max_id=0,
min_id=0,
add_offset=0,
hash=0))
messageId = posts.messages[0].id
client(GetBotCallbackAnswerRequest(
channel_username,
messageId,
data=posts.messages[0].reply_markup.rows[0].buttons[0]))
client.disconnect()
The button that must be clicked is KeyboardButtonUrl or 🔎 Go to website :
reply_markup=ReplyInlineMarkup(
rows=[
KeyboardButtonRow(
buttons=[
KeyboardButtonUrl(
text='🔎 Go to website',
url='https://www.google.com'
),
]
),
KeyboardButtonRow(
buttons=[
KeyboardButtonCallback(
text='🛑 Report',
data=b'{"name":"ReportClick","id":"120326622"}'
),
KeyboardButtonCallback(
text='⏩ Skip',
data=b'{"name":"SkipClick","id":"120326622"}'
),
]
),
]
),
You should not use client.get_entity() in this case, it's not necessary.
You should use client.get_messages(), not GetHistoryRequest.
You should use message.click(), not GetBotCallbackAnswerRequest.
So your code would be:
from telethon import TelegramClient, sync
api_id = ...
api_hash = ...
client = TelegramClient('session_name', api_id, api_hash)
messages = client.get_messages('GOOGLE')
messages[0].click()
This should be enough to click the first button of the last message in the channel.
sender = await event.get_sender()
messages = await client.get_messages(sender.username)
await messages[0].click(0)
This will click the first button in the message. You could also click(row, column), using some text such as click(text='👍') or even the data directly click(data=b'payload').

Categories

Resources