I want to create a button that when I click on it will send the file to me in the telegram.
from config import TOKEN
from telegram import MessageEntity, ReplyKeyboardMarkup, Update
from telegram import InlineKeyboardButton, InlineKeyboardMarkup
from telegram.ext import Updater
from telegram.ext import CallbackContext
from telegram.ext import CommandHandler
from telegram.ext import MessageHandler, Filters
from telegram.ext import CallbackQueryHandler
import logging
import urllib.request , json
updater = Updater(token= TOKEN, use_context= True)
dispathcer = updater.dispatcher
logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
level=logging.INFO)
download_url_link = 'https://saavn.me/songs?link='
home_page = 'https://saavn.me/home'
def readjson(url):
req = urllib.request.urlopen(url)
return json.loads(req.read().decode())
def start(update: Update, context: CallbackContext):
text= "Welcome #{username}".format(username = update.effective_user.username)
update.message.reply_text(text)
def download(update: Update, context: CallbackContext):
x = update.message.parse_entities(types = MessageEntity.URL)
msg = update.message.reply_text("Working on it...")
for i in x:
try:
rjson = read_json(end_point_link + x[i])
name = rjson["results"]['name']
download_link = rjson["results"]["downloadUrl"][4]["link"]
quality = rjson["results"]["downloadUrl"][4]["quality"]
msg.delete()
dl = update.message.reply_document(download_link, caption="Here is {} and quality is {}".format(name, quality))
keyboard = [
[
InlineKeyboardButton('128KB', callback_data=dl),
InlineKeyboardButton('320kb', callback_data=dl),
]
]
reply_markup = InlineKeyboardMarkup(keyboard)
update.message.reply_text("Please choose:",
reply_markup=reply_markup)
except:
continue
if 'error' in rjson:
continue
return
msg.edit_text("I can't fetch from that url. try again!")
dont work inlinekeyboard and just send for me link download and dont show my buttons
start_handler = CommandHandler('start', start)
download_hundler = MessageHandler(Filters.entity(MessageEntity.URL), download)
button_handler = CallbackQueryHandler(button)
dispathcer.add_handler(start_handler)
dispathcer.add_handler(download_hundler)
dispathcer.add_handler(button_handler)
updater.start_polling()
I run the program and the file is sent to me but it does not ask me 128 or 320 and it automatically sends the file why?
In the keyboard section, you should have a unique callback data for each button. for example:
keyboard = [
[
InlineKeyboardButton('128KB', callback_data='dl-128'),
InlineKeyboardButton('320kb', callback_data='dl-320'),
]
]
Then you should create a function to handle callback query:
def button(update: Update, context: CallbackContext):
data = update.callback_query.data
quality = int(data.split('-')[1])
if quality == 128:
# send 128kb file
elif quality == 320:
# send 320kb file
after that, you should create a callback handler with your preferred pattern. For this example it would be:
button_handler = CallbackQueryHandler(button, pattern='dl-')
dispathcer.add_handler(button_handler)
Related
i am searching for a solution. I hava a bot which post by /start command some stuff i need. But id like that the bot do this in a defined time, maybe every 6h.
Hope someone could help me.
import telegram
from telegram.ext import Updater
from telegram.ext import CommandHandler
from tracker import get_prices
telegram_bot_token = "xxx-xxx"
updater = Updater(token=telegram_bot_token, use_context=True)
dispatcher = updater.dispatcher
def start(update, context):
chat_id = update.effective_chat.id
message = ""
crypto_data = get_prices()
for i in crypto_data:
coin = crypto_data[i]["coin"]
price = crypto_data[i]["price"]
change_day = crypto_data[i]["change_day"]
change_hour = crypto_data[i]["change_hour"]
message += f"Coin: {coin}\nPrice: ${price:,.2f}\nHour Change: {change_hour:.3f}%\nDay Change: {change_day:.3f}%\n\n"
context.bot.send_message(chat_id=chat_id, text=message)
dispatcher.add_handler(CommandHandler("start", start))
updater.start_polling()
I was testing something an could add an timer, but is there a way to loop the programm with while True: ?
import telegram
from telegram.ext import Updater
from telegram.ext import CommandHandler
from tracker import get_prices
import threading
import time
telegram_bot_token = "xxx:xxx"
updater = Updater(token=telegram_bot_token, use_context=True)
dispatcher = updater.dispatcher
def message_timer(update, context):
time.sleep(10)
chat_id = update.effective_chat.id
message = ""
crypto_data = get_prices()
for i in crypto_data:
coin = crypto_data[i]["coin"]
price = crypto_data[i]["price"]
change_day = crypto_data[i]["change_day"]
change_hour = crypto_data[i]["change_hour"]
message += f"Coin: {coin}\nPrice: ${price:,.2f}\nHour Change: {change_hour:.3f}%\nDay Change: {change_day:.3f}%\n\n"
context.bot.send_message(chat_id=chat_id, text=message)
dispatcher.add_handler(CommandHandler("start", message_timer))
updater.start_polling()
Currently, I have created a Python bot with buttons that can be pressed to add orders to a list of orders, as shown below:
Sample of the Telebot's Buttons and the List
My bot is in separate chat groups, Chat 1 and Chat 2. When I press a button to add the order in Chat 1, the order is also added in Chat 2.
How do I separate the instances of the bot such that adding orders in Chat 1 does not affect the order list of Chat 2?
Code for the data:
def button(update: Update, _: CallbackContext) -> None:
query = update.callback_query
query.answer()
result = ""
keyboard = []
if str(query.data) == 'macs':
keyboard = [
[InlineKeyboardButton("Filet o Fish", callback_data='fof')],
[InlineKeyboardButton("Big Mac", callback_data='bm')],
[InlineKeyboardButton("Back", callback_data='back')]
]
elif str(query.data) in ('ameens', 'Maggi Pattaya', 'Garlic Naan'):
keyboard = [
[InlineKeyboardButton("Maggi Pattaya", callback_data='Maggi Pattaya')],
[InlineKeyboardButton("Garlic Naan", callback_data='Garlic Naan')],
[InlineKeyboardButton("Back", callback_data='back')]
]
if str(query.data) in ('Maggi Pattaya', 'Garlic Naan'):
order_list.append(str(query.data))
for order in order_list:
result += '\n' + order
elif str(query.data) == 'back':
keyboard = [
[InlineKeyboardButton("Ameen's", callback_data='ameens')],
[InlineKeyboardButton("Macs", callback_data='macs')]
]
if len(order_list) != 0:
for order in order_list:
result += '\n' + order
else:
order_list.append(str(query.data))
for order in order_list:
result += order
reply_markup = InlineKeyboardMarkup(keyboard)
if str(query.data) == 'back':
query.edit_message_text(text="Where would you like to order from?", reply_markup = reply_markup)
else:
#query.edit_message_text(text=f"Menu from {query.data}", reply_markup = reply_markup)
query.edit_message_text(text=f"Orders: {result}", reply_markup = reply_markup)
The general problem is that you store things in order_list which appears to be some kind of global variable. Vad Sims answer already gives the important hint that you should store data on a per chat basis to distinguish between data stored for chat 1 and data stored for chat 2. As you're using the python-telegram-bot library, I suggest to use the built-in feature context.chat_data. Please have a look at this wiki page for more details.
Disclaimer: I'm currently the maintainer of python-telgeram-bot.
You can use this code:
#!/usr/bin/env python
# pylint: disable=C0116
# This program is dedicated to the public domain under the CC0 license.
"""
Basic example for a bot that uses inline keyboards. For an in-depth explanation, check out
https://git.io/JOmFw.
"""
import logging
from telegram import InlineKeyboardButton, InlineKeyboardMarkup, Update
from telegram.ext import Updater, CommandHandler, CallbackQueryHandler, CallbackContext
logging.basicConfig(
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', level=logging.INFO
)
logger = logging.getLogger(__name__)
chats = {}
def start(update: Update, _: CallbackContext) -> None:
if update.message.chat.id not in chats:
chats[update.message.chat.id] = []
keyboard = [
[
InlineKeyboardButton("Option 1", callback_data='1'),
InlineKeyboardButton("Option 2", callback_data='2'),
],
[InlineKeyboardButton("Option 3", callback_data='3')],
]
reply_markup = InlineKeyboardMarkup(keyboard)
txt = ''.join(chats[update.message.chat.id])
update.message.reply_text(txt, reply_markup=reply_markup)
def button(update: Update, _: CallbackContext) -> None:
query = update.callback_query
# CallbackQueries need to be answered, even if no notification to the user is needed
# Some clients may have trouble otherwise. See https://core.telegram.org/bots/api#callbackquery
query.answer()
if query.from_user.id not in chats:
chats[query.from_user.id] = []
chats[query.chat.id].append(query.data)
query.edit_message_text(text=f"Selected option: {query.data}")
def help_command(update: Update, _: CallbackContext) -> None:
update.message.reply_text("Use /start to test this bot.")
def main() -> None:
# Create the Updater and pass it your bot's token.
updater = Updater("TOKEN")
updater.dispatcher.add_handler(CommandHandler('start', start))
updater.dispatcher.add_handler(CallbackQueryHandler(button))
updater.dispatcher.add_handler(CommandHandler('help', help_command))
# Start the Bot
updater.start_polling()
# Run the bot until the user presses Ctrl-C or the process receives SIGINT,
# SIGTERM or SIGABRT
updater.idle()
if __name__ == '__main__':
main()
I'm just starting to discover how to build a bot with python.
I'm trying to send a message at certain time. Seems that the callback_minute function won't accept more than one arguments.I read a lot of example, I read the documentation regarding run_repeating function but I can't fix this issue...
my target is to get the chat_id dinamically. Someone can help me?
import logging
import sys
import requests
import random
import datetime
import telegram.ext
from telegram import InlineKeyboardButton, InlineKeyboardMarkup, KeyboardButton, ReplyKeyboardMarkup, ReplyKeyboardRemove, Update
from telegram.ext import Updater, Filters, CommandHandler, MessageHandler, CallbackQueryHandler, ConversationHandler, CallbackContext
from lib import utils
class MonoBot:
def __init__(self):
logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', level=logging.DEBUG)
# define a command callback function
def start(self, update, context):
#a = utils.search(self, update.message.from_user)
#context.bot.send_message(chat_id=update.message.chat_id, text=update.message.text + a)
update.message.reply_text("write /lista top know what u can do...")
def echo(self, update, context):
context.bot.send_message(chat_id=update.message.chat_id, text=update.message.text + " stuff")
def option(self, update, context):
button = [
[InlineKeyboardButton("text 1", callback_data="1")],
[InlineKeyboardButton("text 2", callback_data="2")],
[InlineKeyboardButton("text 3", callback_data="3")],
]
reply_markup = InlineKeyboardMarkup(button)
context.bot.send_message(chat_id=update.message.chat_id, text="scegli..", reply_markup=reply_markup)
def button(self, update, context):
query = update.callback_query
# context.bot.send_message(chat_id=query.message.chat_id, text="vitto " + query.data)
# use this below in order to hide option
context.bot.edit_message_text(chat_id=query.message.chat_id, text="vitto " + query.data,
message_id=query.message.message_id)
def get_location(self, update, context):
button = [[KeyboardButton("share location", request_location=True)]]
reply_markup = ReplyKeyboardMarkup(button)
context.bot.send_message(chat_id=update.message.chat_id, text="share location?", reply_markup=reply_markup)
def location(self, update, context):
lat = update.message.location.latitude
lon = update.message.location.longitude
context.bot.send_message(chat_id=update.message.chat_id, text="lat:" + str(lat) + " lon:" + str(lon),
reply_markup=ReplyKeyboardRemove())
#conversazione
def cancel(self, update: Update, context: CallbackContext) -> int:
print(update.message.from_user)
update.message.reply_text("by by :)", reply_markup=ReplyKeyboardRemove())
return ConversationHandler.END
def cerca(self, update: Update, context: CallbackContext) -> int:
print("-"*40)
print(update.message.text)
word = update.message.text.split(" ")[1]
print("-"*40)
update.message.reply_text('https://www.google.com/search?q='+ word)
#return ConversationHandler.END
def lista(self, update: Update, context: CallbackContext) -> int:
update.message.reply_text("qua metto l\'elenco dei comandi che espongo...tipo\n- /cercaGOOGLE\n- /altrocomando")
print("-" * 40)
print(update.message)
print("-" * 40)
return CERCA
def reply(self, update: Update, context: CallbackContext) -> int:
user_input = update.message.text
update.message.reply_text(utils.search(self, user_input))
#return ConversationHandler.END
# i'm trying to send a message at certain time...
def callback_minute(self, update, context):
#-1001198785547
context.bot.send_message(chat_id=update.effective_chat.id, text="tempoooooo")
if __name__ == "__main__":
bot = MonoBot()
# first of all take token in order to authenticate
# check new messages --> polling
updater = Updater(token=sys.argv[1])
# allows to register handler --> command, text, video, audio, ...
dispatcher = updater.dispatcher
# CORE <<-----------
# create a command headler and command heandler to dispatcher ###ORDER LIST IS IMPORTANT!!
updater.dispatcher.add_handler(CommandHandler('start', bot.start))
updater.dispatcher.add_handler(CommandHandler('option', bot.option))
updater.dispatcher.add_handler(CommandHandler('location', bot.get_location))
updater.dispatcher.add_handler(MessageHandler(Filters.location, bot.location))
updater.dispatcher.add_handler(CallbackQueryHandler(bot.button))
#updater.dispatcher.add_handler(MessageHandler(Filters.text, bot.reply))
# Add conversation handler with the states GENDER, PHOTO, LOCATION and BIO
word, cmd, LOCATION, CERCA = range(4)
conv_handler = ConversationHandler(
entry_points=[CommandHandler('lista', bot.lista)],
states={
CERCA: [MessageHandler(filters=Filters.text, callback=bot.reply)],
},
fallbacks=[CommandHandler('exit', bot.cancel)],
)
dispatcher.add_handler(conv_handler)
# from here time issue..
j = updater.job_queue
j.run_repeating(bot.callback_minute, interval=60, first=10)
#t = datetime.time(6, 15, 00, 000000)
#j.run_daily(bot.timer, t, days=(0, 1, 2, 3, 4, 5, 6), context=None, name=None)
#updater.dispatcher.add_handler(MessageHandler(Filters.text, bot.echo))
# start polling
updater.start_polling()
#updater.idle() # ???
I get below error:
2021-02-15 22:21:04,527 - telegram.ext.dispatcher - DEBUG - Setting singleton dispatcher as <telegram.ext.dispatcher.Dispatcher object at 0x7f8719922040>
Traceback (most recent call last):
File "/home/vitto/PycharmProjects/monopattino/mono_bot.py", line 118, in <module>
j.run_repeating(bot.callback_minute, interval=60, first=10)
File "/home/vitto/PycharmProjects/monopattino/mono_env/lib/python3.8/site-packages/telegram/ext/jobqueue.py", line 291, in run_repeating
j = self.scheduler.add_job(
File "/home/vitto/PycharmProjects/monopattino/mono_env/lib/python3.8/site-packages/apscheduler/schedulers/base.py", line 434, in add_job
job = Job(self, **job_kwargs)
File "/home/vitto/PycharmProjects/monopattino/mono_env/lib/python3.8/site-packages/apscheduler/job.py", line 49, in __init__
self._modify(id=id or uuid4().hex, **kwargs)
File "/home/vitto/PycharmProjects/monopattino/mono_env/lib/python3.8/site-packages/apscheduler/job.py", line 180, in _modify
check_callable_args(func, args, kwargs)
File "/home/vitto/PycharmProjects/monopattino/mono_env/lib/python3.8/site-packages/apscheduler/util.py", line 401, in check_callable_args
raise ValueError('The following arguments have not been supplied: %s' %
ValueError: The following arguments have not been supplied: context
Try to remove update from callback_minute() like this:
def callback_minute(self, context):
#-1001198785547
context.bot.send_message(
chat_id=update.effective_chat.id,
text='tempoooooo'
)
There is no update delivered when executing a job.
I have some code:
master = InlineKeyboardMarkup()
master.add(InlineKeyboardButton(text='7(800)555-35-35', url='tel:+78005553535'),
InlineKeyboardButton(text='8(800)555-35-35', url='tel:+88005553535'))
But when I try to summon this keyboard I have an error:
aiogram.utils.exceptions.BadRequest: Wrong http url
You need to write the code as follows:
main.py
from aiogram
import Bot, Dispatcher, executor, types
import keyboards as kb
bot = Bot(token = 'BOT_TOKEN')
dp = Dispatcher(bot)
#dp.message_handler(commands = ['inline'])
async def show_items(message: types.Message):
await message.answer('It is buttons', reply_markup = kb.start_keyboard)
if __name__ == '__main__':
executor.start_polling(dp, skip_updates = True)
keybords.py
from aiogram.types
import ReplyKeyboardMarkup, KeyboardButton, InlineKeyboardMarkup, InlineKeyboardButton
inline_keyboard = InlineKeyboardButton(text='7(800)555-35-35', url = 'tel:+78005553535'),
InlineKeyboardButton(text='8(800)555-35-35', url = 'tel:+88005553535')
start_keyboard = ReplyKeyboardMarkup(resize_keyboard = True).add(inline_keyboard)
bot doesn't come back to the start message after running once.
import logging
from config import TOKEN, hello_msg, key1_msg
import mysql.connector
from telegram.ext import Filters, ConversationHandler, CommandHandler, MessageHandler,
Filters, Updater, InlineQueryHandler, CallbackQueryHandler, CallbackContext
from telegram import InlineQueryResultArticle, InputTextMessageContent,
InlineKeyboardButton, InlineKeyboardMarkup, Update
CHOOSING, CHOOSING2 = range(2)
keyboard1 = [
[InlineKeyboardButton("Welcome Message", callback_data = 'welcome_Message')],
[InlineKeyboardButton("Commands", callback_data = 'Commands')],
[InlineKeyboardButton("Links to our website", callback_data = 'links_to_our_websites')],
[InlineKeyboardButton("Demo Try", callback_data = 'Demo_try')],
[InlineKeyboardButton("register", callback_data = 'register')],
[InlineKeyboardButton("Contact us", callback_data = 'Contact_us')]
]
def start(update: Update, context: CallbackContext):
global up, cal
up = update
cal = CallbackContext
context.bot.send_message(chat_id = update.effective_chat.id, text = hello_msg)
reply_markup = InlineKeyboardMarkup(keyboard1)
update.message.reply_text("please Choose: ", reply_markup = reply_markup)
return CHOOSING
def button1(update: Update, context: CallbackContext):
query = update.callback_query
query.answer()
answer = query.data
context.bot.send_message(chat_id = update.effective_chat.id, text = key1_msg[answer])
return CHOOSING
def main():
updater = Updater(TOKEN, use_context=True)
dp = updater.dispatcher
new = ConversationHandler(entry_points = [CommandHandler("start", start)], states = {CHOOSING : [MessageHandler(Filters.regex('^(Welcome Message|Commands|Links to our website|Demo Try|register|Contact us)$'), start)]},fallbacks=[MessageHandler(Filters.regex('^start$'), sart)])
dp.add_handler(new)
dp.add_handler(CallbackQueryHandler(button1))
updater.start_polling()
updater.idle()
if __name__ == "__main__":
main()
I want to run the start command again right after a user will choose an option from a button...
I wanna learn how to pass parameters when giving handlers inside the conversation handler.
thank you.