Discord.py - Interactions - Buttons - button

I've been trying to create Buttons for my Discord bot but it seems like I have something wrong, I just can't figure out what it is.
Here's the code I currently have:
#bot.command()
async def test(ctx: interactions.CommandContext):
button = Button(
style=ButtonStyle.PRIMARY,
custom_id="primary",
label="Blue button",
)
await ctx.send("Hello World!", components=button)
I also have the following imports:
import discord
from discord.ext import commands
import random
import time
import interactions
from interactions import Button, ButtonStyle, SelectMenu, SelectOption, ActionRow
What I expect: The bot replying to command !test with the message "Hello World!" and a button with the text 'Blue button' attached to that message.
What it does: Absolutely nothing.
Now I have been staring at this for quite a while, so fair chance I've missed something rather simple, but I'd appreciate the help either way :)

Instal the discord_components Module .
pip install discord_components
Then this code should work for you :
from discord_components import *
bot = ComponentsBot(command_prefix="?")
#bot.command()
async def test(ctx):
button = Button(
style=ButtonStyle.blue,
custom_id="primary",
label="Blue button",
)
await ctx.send("Hello World!", components=[button])

Related

How to reply a massage in Telepot?

I am making a telegram bot with telepot , but I don't know how to do it. I tried many solutions, but I didn't get an answer and the bot only sent simple messages without reply!
My source is supposed to run on the pythoneverywhere site, so I have the limitation of using other libraries like telethon.
here is my code :
import telepot
import urllib3
import random, time
proxy_url = "http://proxy.server:3128"
telepot.api._pools = {
'default': urllib3.ProxyManager(proxy_url=proxy_url, num_pools=3, maxsize=10, retries=False, timeout=30),
}
telepot.api._onetime_pool_spec = (urllib3.ProxyManager, dict(proxy_url=proxy_url, num_pools=1, maxsize=1, retries=False, timeout=30))
bot = telepot.Bot('')
def handle(msg):
content_type, chat_type, chat_id .= telepot.glance(msg)
massage = msg["text"]
bot.sendMessage(chat_id, text="Reply From Bot!" ,reply_to_message_id=massage)
bot.message_loop(handle)
print('RUNNING!')
while 1:
time.sleep(10)
I tried :
bot.sendMessage(chat_id, text="Reply From Bot!" ,reply_to_message_id=massage)
and I expected :
Reply From Bot!
Instead of using massage you can use msg['message_id']
def handle(msg):
content_type, chat_type, chat_id .= telepot.glance(msg)
massage = msg["text"]
bot.sendMessage(chat_id, text="Reply From Bot!" ,reply_to_message_id=msg['message_id'])
And also just mentioning; it seems like telepot is no longer maintained by developers as mentioned in telepot's GitHub repository. It would be better to switch into a library like python-telegram-bot

Telegram Bot Python Inlinekeyboardmarkup does not work for all users in a group

I want to respond when someone sends the /start comand and display a text with a like/dislike button in a group.
Here is my sample code:
from telegram import InlineKeyboardButton, InlineKeyboardMarkup
from telegram.ext import (
Updater,
CommandHandler,
CallbackQueryHandler,
ConversationHandler)
import logging
FIRST, SECOND = range(2)
keyboard = [[InlineKeyboardButton('πŸ‘', callback_data='0'),
InlineKeyboardButton('πŸ‘Ž', callback_data='2')]]
def start(update, context):
reply_markup = InlineKeyboardMarkup(keyboard)
update.message.reply_text(
'Test Message\n',
reply_markup=reply_markup
)
return FIRST
def main():
updater = Updater(
'TOKEN', use_context=True)
dp = updater.dispatcher
conv_handler = ConversationHandler(
entry_points=[CommandHandler('start', start)],
states={
FIRST: [CallbackQueryHandler(a, pattern='^'+str(0)+'$'),
CallbackQueryHandler(b, pattern='^'+str(2)+'$')]
},
fallbacks=[CommandHandler('start', start)]
)
dp.add_handler(conv_handler)
updater.start_polling()
updater.idle()
if __name__ == "__main__":
main()
The callbacks only work for the user who sent the /start command. Other users cannot click the button or there is no callback. if another user sends a /start command, both like/dislike buttons of both posts of the bot work for the two users.
Where is the mistake?
I want every user to be able to press the buttons and it triggers a callback. regardless of whether the user has ever sent the /start command
I am thankful for every help.
The issue here is that by default conversations are per user - please also see this faq entry for details.
For your use case, I doubt that a ConversationHandler gives you any benefit. I would just register the CommandHandler and the CallbackQueryHandler independently.
Disclaimer: I'm currently the maintainer of python-telegram-bot.

Telegram Bot: job_queue.run_repeating cannot properly callback

I have been wrestling with this for a while. I can't seem to get the job_queue.run_repeating to call back a function properly.
My goal is for the user to issue command in the form of /alert to begin running the send_alert function on a fixed interval. I am not sure where I am going wrong despite having looked at at several examples. I can get regular commands to execute just fine, but not JobQueue callbacks.
Currently my code below throws an error on the start_alerts callback, saying NameError: name 'job_queue' is not defined. When I add job_queue accordingly to the function call, such as start_alerts(update, context, job_queue) it no longer updates the "alerts started!" message to my Telegram chat, but it also doesn't throw an error.
from telegram.ext import Updater, CommandHandler, JobQueue
def start_alerts(update, context):
context.bot.send_message(chat_id=update.effective_chat.id, text="alerts started!")
job_queue.run_repeating(send_alert, interval=5.0, first=1.0)
def send_alert(update, context):
message="this is an alert to send"
context.bot.send_message(chat_id=update.effective_chat.id, text=message)
updater = Updater(token=token, use_context=True)
dispatcher = updater.dispatcher
job_queue = updater.job_queue
job_queue.set_dispatcher(dispatcher)
dispatcher.add_handler(CommandHandler('alert', start_alerts))
updater.start_polling()
job_queue.start()
Within the start_alerts function, the variable job_queue is not defined. Use context.job_queue instead as explained in the JobQueue tutorial, the timerbot.py example and the documentation of CallbackContext.

Buttons In Embed (Discord.py)

I have been trying to make a fake nitro command. I made an accept button under the embed that takes the user to a link (probably a troll GIF image or picture).
Currently, this is the code.
import discord
from discord.ext import commands
from discord_components import *
from discord_buttons_plugin import *
def __init__(self, client):
self.client = client
buttons = ButtonsClient(client)
#commands.command(name='nitro')
#commands.has_permissions(ban_members=True)
async def nitro(self,ctx, member: discord.Member = None):
if member == None:
member = ctx.author
embed = discord.Embed(title = "**You've been gifted a subscription!**",
description = f"||**{member.mention}**|| has gifted you Nitro for **1 month!**",
color = 0xc17ce0)
embed.set_image(url = 'https://media.threatpost.com/wp-content/uploads/sites/103/2021/04/19145523/Discord-Nitro-e1618858537976.png' )
await buttons.send(
content = None,
embed = embed,
channel = ctx.channel.id,
components = [
ActionRow([
Button(
style = ButtonType().Link,
label = "Accept",
url = "https://c.tenor.com/Bvb1iMhQQUUAAAAC/gorilla-middle-finger.gif"
)
])
]
)
It’s not showing any error, but the command is not working. How can I do it?
Those are third-party APIs which are similar to discord.py. For using interactions and buttons in discord.py, you can use Discord's master version which can be downloaded by doing:
pip install -U git+https://github.com/Rapptz/discord.py
Support regarding that will be available at their Official Support server.

My Discord bot isn't responding to a command to pull data from timezonedb

So it can actually show the info I want it to in the terminal. But when I prompt it to send it as a discord message it appears to be attempting to send a blank message. It's probably something stupid, but thank you for looking. The language is Python.
import os
import discord
import requests
import json
import pprint
client = discord.Client()
def get_time():
response = requests.get("http://api.timezonedb.com/v2.1/get-time-zone?key=W9BJQ3QMGG69&format=json&by=position&lat=37.9838&lng=23.7275")
return pprint.pprint(response.json())
#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('$petertest'):
clock = get_time()
await message.channel.send(clock)
client.run(os.environ['TOKEN'])
You are using the pprint module to print the data to the console itself. That is the issue there
Changing your code to simply return the data will fix the error.
return response.json()
If you want to send the formatted json data to discord, you can use json.dumps:
if message.content.startswith('test'):
clock = get_time()
clock = json.dumps(clock, indent=4)
await message.channel.send(clock)

Resources