How to loop in python Telegram bot conversation handler - python

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.

Related

I am trying to create a telegram bot, I am getting error in command handler it is for casual talk

Below is my telegram bot code.
I am trying to get input from user and return eventually I will give input to my ML model:
def chat(s):
return s
def handle_message(update: Update, context: CallbackContext):
print("inside")
tx = update.message.text
re = chat(tx)
update.message.reply_text(re)
def main():
updater = Updater("API_KEY",use_context=True)
dp = updater.dispatcher
dp.add_handler(CommandHandler(Filters.text,handle_message))
dp.add_error_handler(error)
updater.start_polling()
updater.idle()
Here is the error I am getting:
File "C:\Users\NAMIT\AppData\Local\Programs\Python\Python39\lib\site- packages\telegram\ext\commandhandler.py", line 161, in __init__
self.command = [x.lower() for x in command]
TypeError: '_Text' object is not iterable
You have to use MessageHandler instead of CommandHandler
#dp.add_handler(CommandHandler(Filters.text, handle_message))
dp.add_handler(MessageHandler(Filters.text, handle_message))
Minimal working code:
import os
import logging
from telegram.ext import Updater, MessageHandler, CommandHandler, Filters
TOKEN = os.getenv('TELEGRAM_TOKEN')
def error(update, context):
logger.warning('Update "%s" caused error "%s"', update, context.error)
def chat(s):
return s
def handle_message(update, context):
print("inside")
tx = update.message.text
re = chat(tx)
update.message.reply_text(re)
def main():
updater = Updater(token=TOKEN, use_context=True)
dp = updater.dispatcher
#dp.add_handler(CommandHandler(Filters.text, handle_message))
dp.add_handler(MessageHandler(Filters.text, handle_message))
dp.add_error_handler(error)
updater.start_polling()
updater.idle()
main()

How Can I add URL for Inlinekeyboard in Telegram Bot

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)

How to Telegram auto Posting bot in Group?

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()

How to run separate instances of a Python Telegram Bot?

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()

Aiogram python InlineKeyboard

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)

Categories

Resources