I'm trying to call an async function inside my CallbackQueryHandler, however after calling main() nothing happens, the program run fine, but if i trigger the callback function, it doesn't work
this is my code
from telegram.ext import Updater, CallbackQueryHandler
async def button(update, context) -> None:
query = update.callback_query
query.answer()
data = query.data
print(data)
if await post_data(data):
bot.send_message(chat_id=update.chat_instance, text='Done!')
async def main() -> None:
updater = Updater(TELEGRAM_BOT_TOKEN)
updater.dispatcher.add_handler(CallbackQueryHandler(button, run_async=True))
updater.start_polling()
updater.idle()
await main()
am i missing something?
python-telegram-bot does (yet) not natively support the asyncio module, see also here. The run_async features uses threading.
Disclaimer: I'm currently the maintainer of python-telegram-bot.
Related
Using python-telegram-bot, I recently installed the --pre version which broke this code.
It seems now it wants everything to be async. In this example, I use code that has nothing to do with telegram bot to decide what will be the value of mymsg, so I don't need/want to havea commandHandler, I just want to be able to send a message in a Telegram channel whenever I decide so in my code
async def teleg_mail(msg):
bot = telegram.Bot('TOKEN')
keyboard = [[InlineKeyboardButton("Publish", callback_data='1///'+msg)]]
reply_markup = InlineKeyboardMarkup(keyboard)
await bot.send_message('CHANNEL',msg, reply_markup=reply_markup)
def main() -> None:
#...
mymsg="code above will decide what's in this string"
teleg_mail(mymsg)
if __name__ == "__main__":
main()
I used async and await because I was getting error, but even when using it, now I get
RuntimeWarning: coroutine 'teleg_mail' was never awaited
And I cannot use await on teleg_mail() because it's not in an async function...
How can I solve this?
import asyncio
async def main() -> None:
#...
mymsg="code above will decide what's in this string"
await teleg_mail(mymsg)
if __name__ == "__main__":
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
For switching from v13.x to v20.x, I highly recommend reading the v20.0a0 release notes as well as the transition guide. Please also note that the recommended way to use the bot methods without handlers is descriped here.
Disclaimer: I'm currently the maintainer of python-telegram-bot.
I'd like to make a telegram bot that when started sends a hello world message with an inline button that when clicked sends another hello world messge, but the code (the one below) that I'm using doesn't work. Can you tell me what I'm doing wrong? Using python-telegram-bot==20.0a0
from telegram.ext import ApplicationBuilder, CommandHandler, CallbackQueryHandler
from telegram import InlineKeyboardButton, InlineKeyboardMarkup
from TOKEN import TOKEN
keyboard = [
[InlineKeyboardButton("Start", callback_data="start")],
]
start_query_keyboard = InlineKeyboardMarkup(keyboard)
async def start(update, context) -> None:
await update.message.reply_text("Hello World!", reply_markup=start_query_keyboard)
def start2(callback) -> None:
callback.message.reply_text("Hello World!")
if __name__ == "__main__":
app = ApplicationBuilder().token(TOKEN).build()
app.add_handlers([CommandHandler("start", start), CallbackQueryHandler("start", start2)])
app.run_polling(stop_signals=None)
The first argument of CallbackQueryHandler must be a callback function, not a string. That callback function must accept exactly two positional arguments and must be a coroutine function (async def), just as for CommandHandler (or any other handler, in fact). Please have a look at the docs of CallbackQueryhandler as well as the inlinekeyboard.py example .
Disclaimer: I'm currently the maintainer of python-telegram-bot
I'm trying to combine a Twitch API package (twitchio) with a webserver (sanic) with the intent of serving chat commands to a game running locally to the python script. I don't have to use Sanic or twitchio but those are the best results I've found for my project.
I think I understand why what I have so far isn't working but I'm at a total loss of how to resolve the problem. Most of the answers I've found so far deal with scripts you've written to use asyncio and not packages that make use of event loops.
I can only get the webserver OR the chat bot to function. I can't get them to both run concurrently.
This is my first attempt at using Python so any guidance is greatly appreciated.
#!/usr/bin/python
import os
from twitchio.ext import commands
from sanic import Sanic
from sanic.response import json
app = Sanic(name='localserver')
bot = commands.Bot(
token=os.environ['TMI_TOKEN'],
client_id=os.environ['CLIENT_ID'],
nick=os.environ['BOT_NICK'],
prefix=os.environ['BOT_PREFIX'],
initial_channels=[os.environ['CHANNEL']]
)
#app.route("/")
async def query(request):
return json(comcache)
#bot.event
async def event_ready():
'Called once when the bot goes online.'
print(f"{os.environ['BOT_NICK']} is online!")
ws = bot._ws # this is only needed to send messages within event_ready
await ws.send_privmsg(os.environ['CHANNEL'], f"/me has landed!")
#bot.event
async def event_message(ctx):
'Runs every time a message is sent in chat.'
# make sure the bot ignores itself and the streamer
if ctx.author.name.lower() == os.environ['BOT_NICK'].lower():
return
await bot.handle_commands(ctx)
# await ctx.channel.send(ctx.content)
if 'hello' in ctx.content.lower():
await ctx.channel.send(f"Hi, #{ctx.author.name}!")
#bot.command(name='test')
async def test(ctx):
await ctx.send('test passed!')
if __name__ == "__main__":
app.run(host="127.0.0.1", port=8080)
bot.run()
I use python-telegram-bot
this is my main.py
from telegram import InlineKeyboardButton, InlineKeyboardMarkup, Update
from telegram.ext import Updater, CommandHandler, CallbackQueryHandler, CallbackContext
def start(update: Update, context: CallbackContext) -> None:
"""Sends a message with inline buttons attached."""
keyboard = [
[
InlineKeyboardButton("Connect wallet", callback_data='connectwallet'),
],
update.message.reply_text('Please choose:', reply_markup=reply_markup)
def button(update: Update, context: CallbackContext) -> None:
"""Parses the CallbackQuery and updates the message text."""
query = update.callback_query
query.answer()
if query.data == 'connectwallet':
context.bot.send_message(chat_id=chat_id, text=f'This is test msg')
def main() -> None:
"""Run the bot."""
# Create the Updater and pass it your bot's token.
updater = Updater('180666756:AAGX__token__WdNO_YOVa7nA35EBXc')
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( )
# timeout=300
# Run the bot until the user presses Ctrl-C or the process receives SIGINT,
# SIGTERM or SIGABRT
updater.idle()
if __name__ == '__main__':
main()
But whenever I shut down main.py, change some code and restart it( Using ctrl+c and then python3 main.py)
Telegram bot freezes and stops responding to user commands. Sometimes it get's back to life, sometimes it doesn't and i need to restart bot from telegram.
I've tried to search a solution but didn't find it.
Any help would be appreciated.
That's because of telegram api limitations and if you are in local host maybe your ram and internet be slow. use heroku for deploying. Hope it will work also if you know threading you can use it it's good with its issue. Also make sure to enable logging if you need codes ask me I will give.
I copied this code from another thread as is, but was unable to get it to work...
from telegram.ext import Updater, CommandHandler, MessageHandler, Filters, InlineQueryHandler
def sayhi(bot, job):
job.context.message.reply_text("hi")
def time(bot, update,job_queue):
job = job_queue.run_repeating(sayhi, 5, context=update)
def main():
updater = Updater('BotKey')
dp = updater.dispatcher
dp.add_handler(MessageHandler(Filters.text , time,pass_job_queue=True))
updater.start_polling()
updater.idle()
if __name__ == '__main__':
main()
The Error I was give in my command terminal is:
TypeError: time() missing 1 required positional argument: 'job_queue'
I found this strange as I thought I already had set pass_job_queue=True...
(also, I did change the BotKey to the required key. I can get my bot to reply to texts but cant get it to periodically send stuff...)
pass_job_queue was deprecated in version 12.0.0, Tutorial to switch version here
You need to use context based callbacks, like in this example.
Here's your code changed:
from telegram.ext import Updater, CommandHandler, MessageHandler, Filters, InlineQueryHandler
def sayhi(context):
context.bot.send_message(context.job.context, text="hi")
def time(update, context):
context.job_queue.run_repeating(sayhi, 5, context=update.message.chat_id)
def main():
updater = Updater('Token', use_context=True)
dp = updater.dispatcher
dp.add_handler(MessageHandler(Filters.text , time))
updater.start_polling()
updater.idle()
main()