How do I edit a telegram message multiple times? - python

Hi I'm trying to make a telegram bot that edits its same message multiple times like BotFather does, but every time that I try it gives me this error:
telegram.error.BadRequest: Message is not modified: specified new message content and reply markup are exactly the same as a current content and reply markup of the message
Here is the code, I tried to make it as clear as possible.
from telegram import InlineKeyboardButton, InlineKeyboardMarkup
from telegram.ext import *
from API import API_KEY
from bot_messages import *
updater = Updater(API_KEY, use_context=True)
dispatcher = updater.dispatcher
def start(update, context):
update.message.reply_text(WELCOME, reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton("Ciao", callback_data="ciao")]]))
def ciao(update, context):
update.callback_query.edit_message_text("Ciao", reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton("Dona!", callback_data="donate")]]))
def donate(update, context):
update.callback_query.edit_message_text("Dona", reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton("Dona", callback_data="dona")]]))
dispatcher.add_handler(CommandHandler("start", start))
dispatcher.add_handler(CommandHandler("restart", start))
dispatcher.add_handler(CallbackQueryHandler(ciao))
dispatcher.add_handler(CallbackQueryHandler(donate))
updater.start_polling()
updater.idle()
Also can you tell me the proper way of making inline query handlers? Because if it is giving me error it could perhaps mean that I'm not doing it quite right. Thanks in advance.

In your snippet only the first CallbackQueryHandler will ever handle updates - please see the docs of Dispatcher.add_handler for details on how dispatcher decides which handler gets to handle an update.
That's why your code is trying to update the message with the unchanged text and you get that error.
To fix that, you can e.g. use the pattern argument of CallbackQueryhandler.
Disclaimer: I'm currently the maintainer of python-telegram-bot.

Related

Trying to retrieve the answer of a Telegram poll

I have been able to do a poll successfully, but not able to retrieve the results (to log them in local).
I've been all day trying to get results. My lasts tries are with the # at the end, but no luck.
Here's the code I'm currently running (without token). It runs but haven't figured out how to get the answers:
from telegram import Update, Poll
from telegram.ext import ApplicationBuilder, CommandHandler, ContextTypes, PollHandler
import requests
async def poll(update: Update, context: ContextTypes.DEFAULT_TYPE):
q_text="What have you done today?"
poll_text=['train','study','show love']
await
def poll_handler2(update,context): #
option_1_text=Update.poll.options[1].text #
print(option_1_text) #
return option_1_text #
context.bot.send_poll(chat_id=update.effective_chat.id,question=q_text,options=poll_text,allows_multiple_answers=True,is_anonymous=False)
if __name__=='__main__':
application=ApplicationBuilder().token('TOKEN').build()
poll_handler=CommandHandler('poll', poll)
application.add_handler(poll_handler)
application.add_handler(PollHandler(poll_handler2)) #
application.run_polling()
Any help would be more than welcomed.
I got to an answer reading and rereading the answer from a similar question of the maintainer of python-telegram-bot here, with trial and error with the code from here:
https://github.com/python-telegram-bot/python-telegram-bot/blob/master/examples/pollbot.py
Thank you very much CallMeStag.

How to add members to Telegram with pyrogram?

I have been able to login to Telegram and send messages to myself and also retrieve users from a group. But whenever I try to add members to a group, I get an error.
Here is my code
from pyrogram import Client
import asyncio
from pyrogram.errors import FloodWait
TARGET = 'intendingcouples_class'
async def main():
app = Client("my_account")
users = []
async with app:
async for member in app.get_chat_members(TARGET):
users.append(member.user.id)
print(users)
await app.add_chat_members('myenki', member.user.id)
asyncio.run(main())
When I run the above code, I get this error
pyrogram.errors.exceptions.flood_420.FloodWait: Telegram says: [420 FLOOD_WAIT_X] - A wait of 73958 seconds is required (caused by "channels.InviteToChannel")
Please, how do I solve this problem?
Your error is clear:
pyrogram.errors.exceptions.flood_420.FloodWait: Telegram says: [420 FLOOD_WAIT_X] - A wait of 73958 seconds is required (caused by "channels.InviteToChannel")
You'll have to wait 73958 seconds to be able to use the method again. Besides that, adding members against their will to random groups can get both your group, and your account permanently banned.

Get User Input after keyboard inline keyboard selection Telegram Bot Python

I have an issue with my telegram bot. I wrote a bot in which the user needs to make a choice with an Inline Keyboard. If he selects 'Cerca un prodotto' the bot should wait for user input and print it. But if I start the bot then it prints the text 'FU' in update.message.reply_text('HELLO FU', reply_markup=reply_markup_main) row instead of printing user input. This is my code:
from telegram.ext import Updater, CommandHandler, MessageHandler, Filters
from telegram.ext import CommandHandler, CallbackQueryHandler, CallbackContext
from telegram import InlineKeyboardButton, InlineKeyboardMarkup, ReplyKeyboardMarkup
from telegram import Update
import telegram
def start(update, context):
kb_main = [
[InlineKeyboardButton("Cerca le migliori offerte", callback_data='trovaofferte')],
[InlineKeyboardButton("Cerca un prodotto", callback_data='cercaprod')]
]
reply_markup_main = InlineKeyboardMarkup(kb_main)
update.message.reply_text('HELLO FU', reply_markup=reply_markup_main)
def kb(update: Update, _: CallbackContext) -> None:
query = update.callback_query
query.answer()
#===> IF USER CHOICE IS 'cercaprod' THEN BOT SHOULD WAIT FOR USER INPUT<====
if query.data == 'cercaprod':
print(query.message.text)
def main():
update= Updater('1655760090:AAFKyOR-i7wLW1zIAH9-air0EtqIDQJrCwk', use_context=True)
disp=update.dispatcher
disp.add_handler(CommandHandler("start", start))
disp.add_handler(MessageHandler(Filters.text & ~Filters.command, kb))
update.dispatcher.add_handler(CallbackQueryHandler(kb))
update.start_polling()
update.idle()
if __name__=='__main__':
main()
A have a few remarks:
You should revoke your bot token with #Botfather. Otherwise anyone could use it, because you posted it
you use the callback kb in both a MessageHandler and a CallbackQueryHandler, but call update.callback_query.answer(). However, if the update is a message (in the MessageHandler case, update.callback_query will be None and you'll get an exception.
Now to the actual problem:
When the button is pressed, the only update you get is the CallbackQuery and query.message is the message that the button is attached to - in your case the message with text HELLO FU. If you want the user to enter some text after pressing the button, that will come in a new update. So you'd have to use a MessageHandler to catch that. I guess that's what you tried by setting up a MessageHandler with kb as callback, but as mentioned above that will only raise an error, which you currently won't see because you have no logging set up and no error handler.
For this kind of setup, I strongly recommend to use ConversationHandler, which is perfect for setups where multiple user inputs are needed. There's also a neat example here.

How to create a cyclic thread that can be started/stopped at any time via python-telegram-bot command?

I'm writing a Telegram bot (with python-telegram-bot) that based on a command, cyclically sends messages to the user every hour.
I want to start/stop this using bot commands, adding command handlers like /start_cycle and /stop_cycle. To clarify, this is what I have in mind:
def start_cycle()
# start in some way send_hourly_message()
def stop_cycle()
# stop in some way send_hourly_message()
def main():
"""Entrypoint of the bot"""
# Create updater and get dispatcher
updater = Updater(...)
dp = updater.dispatcher
# Add command handlers
dp.add_handler(CommandHandler("start_cycle", start_cycle))
dp.add_handler(CommandHandler("stop_cycle", stop_cycle))
# Start the bot until interrupt
updater.start_polling(timeout=3)
updater.idle()
The thing that puzzles me is that for how the Telegram library is conceived, there is already an event-based logic, started by updater.start_polling() and updater.idle(). I didn't find any documentation/specific information on how to make this work properly with triggerable time-based events.
What would be in your opinion the best way to do what I have in mind? I looked into asyncio a little but maybe is too complex for what I actually need?
Thanks in advance for any suggestion!
Thanks to #GaganTK I was able to find what i need:
def start_notify(update, context):
new_job = context.job_queue.run_repeating(my_callback, interval=3, first=0, name="my_job")
def stop_notify(update, context):
job = context.job_queue.get_jobs_by_name("my_job")
job[0].schedule_removal()
def my_callback(context: telegram.ext.CallbackContext):
print(datetime.datetime.now())

Telegram Quiz Bot with pyTelegramBotAPI

Trying to build a Telegram Quiz Bot using pyTelegramBotAPI. I'm using sched to schedule the message Handler but i don't know how to stop the Message Handler and return to my Main Script which will scheudle the next Round.
Tryed to use timeout but it is not working!
My Code:
import telebot
import sched, time
def listen():
print("Send my your Answer")
#bot.message_handler(func=lambda message: True, content_types=['text'])
def command_default(m):
print(m.text)
bot.polling()
API_TOKEN = 'xxxx'
s = sched.scheduler(time.time, time.sleep)
bot = telebot.TeleBot(API_TOKEN)
s.enter(50, 1, listen)
s.run()
In this use case you have to use something called a Finite State Machine (FSM). You keep track of user states, such as one where the user is ready to send an answer.
This is already implemented in pyTelegramBotAPI, with the next_step_handler(). However, I suggest you instead create your own solution, as the one provided by the wrapper is quite buggy.
Here is an example (you can translate the page): https://groosha.gitbooks.io/telegram-bot-lessons/content/chapter11.html

Categories