Trying to connect Dialogflow to telegram bot to use it with webhook, to avoid using .json file credentials.
A part of code from bot.py
from aiogram.dispatcher.webhook import SendMessage
API_HOST = os.getenv("API_HOST")
BOT_TOKEN = os.getenv("BOT_TOKEN")
APP_NAME = os.getenv("APP_NAME")
WEBHOOK_HOST = f"https://{APP_NAME}.herokuapp.com"
WEBHOOK_PATH = f"/webhook/{BOT_TOKEN}"
WEBHOOK_URL = f"{WEBHOOK_HOST}{WEBHOOK_PATH}"
WEBAPP_HOST = "0.0.0.0"
WEBAPP_PORT = int(os.environ.get("PORT", "5000"))
logging.basicConfig(level=logging.INFO)
bot = Bot(token=BOT_TOKEN)
dp = Dispatcher(bot, storage=MemoryStorage())
async def scheduler():
"""Scheduler for sending messages."""
# aioschedule.every(10).seconds.do(prepare_message)
# keep in mind that this is remote server time
aioschedule.every().day.at("17:00").do(prepare_message)
while True:
await aioschedule.run_pending()
await asyncio.sleep(1)
async def on_startup(dispatcher):
"""Startup function."""
# add commands to MENU button
await set_commands(bot)
asyncio.create_task(scheduler())
if not DEVELOP:
await bot.set_webhook(url=WEBHOOK_URL)
async def on_shutdown(dispatcher):
"""Shutdown function."""
await bot.delete_webhook()
#dp.message_handler(content_types=["text"])
async def reply_to_user(message: types.Message):
# this code should reply to user with data from a webhook, but I do not khow how to retrieve it
return SendMessage(message.chat.id, message.text)
if __name__ == "__main__":
if DEVELOP:
executor.start_polling(dispatcher=dp, skip_updates=True, on_startup=on_startup)
else:
executor.start_webhook(
dispatcher=dp,
webhook_path=WEBHOOK_PATH,
on_startup=on_startup,
on_shutdown=on_shutdown,
skip_updates=True,
host=WEBAPP_HOST,
port=WEBAPP_PORT,
)
Bot hosted on Heroku, it works, but but I do not khow how to retrieve payload from webhook url. Aiogram docs tells to use from aiogram.dispatcher.webhook import SendMessage and nothing more.
Related
import logging
from aiogram import Bot, types
from aiogram.contrib.middlewares.logging import LoggingMiddleware
from aiogram.dispatcher import Dispatcher
from aiogram.dispatcher.webhook import SendMessage
from aiogram.utils.executor import start_webhook
API_TOKEN = ''
# webhook settings
WEBHOOK_HOST = 'https://xxxxx211.eu.ngrok.io'
WEBHOOK_PATH = ''
WEBHOOK_URL = f"{WEBHOOK_HOST}{WEBHOOK_PATH}"
# webserver settings
WEBAPP_HOST = 'localhost' # or ip
WEBAPP_PORT = 5000
logging.basicConfig(level=logging.INFO)
bot = Bot(token=API_TOKEN)
dp = Dispatcher(bot)
dp.middleware.setup(LoggingMiddleware())
#dp.message_handler()
async def echo(message: types.Message):
# Regular request
# await bot.send_message(message.chat.id, message.text)
# or reply INTO webhook
return SendMessage(message.chat.id, message.text)
async def on_startup(dp):
await bot.set_webhook(WEBHOOK_URL.format(token=API_TOKEN))
with bot.with_token("token"):
await bot.set_webhook(WEBHOOK_URL.format(token="token"))
with bot.with_token("token2"):
await bot.set_webhook(WEBHOOK_URL.format(token="token2"))
async def on_shutdown(dp):
logging.warning('Shutting down..')
# insert code here to run it before shutdown
# Remove webhook (not acceptable in some cases)
await bot.delete_webhook()
with bot.with_token("token"):
await bot.delete_webhook()
with bot.with_token("token2"):
await bot.delete_webhook()
# Close DB connection (if used)
await dp.storage.close()
await dp.storage.wait_closed()
logging.warning('Bye!')
if __name__ == '__main__':
start_webhook(
dispatcher=dp,
webhook_path=WEBHOOK_PATH,
on_startup=on_startup,
on_shutdown=on_shutdown,
host=WEBAPP_HOST,
port=WEBAPP_PORT,
)
Here I took the code for multibot from the FAQ aiogram gabbhack repository But there is a problem with the Dispatcher there is a concept
Major token and minor
Because of this, when sending code using await message.answer and the like on the aiogram dock using the second bot, the answer comes to the first bot
And the problem is solved with the help of return SendMessage but this is not an option because 2 requests or more cannot be sent and asynchrony is lost
How can I make it so that the Dispatcher is for each token separately (tokens in an unlimited number)
So that you can turn to #dp and await message.answer and the answer comes to this very bot
python-telegram-bot==20.0
I'm trying to run a telegram bot that proxies messages retrieved via HTTP to telegram. I found the example that does a very similar thing that I want to do and most of the code I've copied from it
Here's my code (handlers are not included. They worked before I added the webserver to the code):
async def main() -> NoReturn:
async def webhook_update(update: WebhookUpdate, context: CallbackContext) -> None:
"""Callback that handles the custom updates."""
await context.bot.send_message(
chat_id=update.user_id,
text=update.payload,
parse_mode=ParseMode.HTML
)
async def custom_updates(request: Request) -> JSONResponse:
"""
Handle incoming webhook updates by also putting them into the `update_queue` if
the required parameters were passed correctly.
"""
data = await request.json()
user_id = data["user_id"]
payload = data['payload']
await telegram_bot_application.update_queue.put(WebhookUpdate(user_id=user_id, payload=payload))
return JSONResponse({'success': True})
telegram_bot_application = ApplicationBuilder() \
.token(settings.TELEGRAM_TOKEN) \
.build()
# .updater(None) \
telegram_bot_application.add_handler(CommandHandler('start', command.start_handler))
telegram_bot_application.add_handler(CallbackQueryHandler(button.button_handler))
telegram_bot_application.add_handler(TypeHandler(type=WebhookUpdate, callback=webhook_update))
telegram_bot_application.add_handler(MessageHandler(filters.TEXT & (~filters.COMMAND), message.message_handler))
logging.info('telegram bot is configured')
await telegram_bot_application.bot.set_webhook(url=f"{settings.BASE_HOST}/external_message")
starlette_app = Starlette(
routes=[
Route("/external_message", custom_updates, methods=["POST"]),
]
)
webserver = uvicorn.Server(
config=uvicorn.Config(
app=starlette_app,
port=8080,
use_colors=False,
host="0.0.0.0",
)
)
logging.info('webserver configured')
async with telegram_bot_application:
await telegram_bot_application.start()
logging.info('bot started')
await webserver.serve()
await telegram_bot_application.stop()
if __name__ == "__main__":
asyncio.run(main())
The code runs without errors but never logs the messages placed inside handlers (all of them are async).
I use aiogram. Logic of my bot is very simple - he receive messages from user and send echo-message after 10 seconds. This is a test bot, but in general, I want to make a bot for buying movies with very big database of users. So, my bot must be able to process messages from many users simultaneously and must receive messages using Webhooks. Here are two python scripts:
Telegram-bot on Long Polling:
import asyncio
import logging
from aiogram import Bot, Dispatcher, executor, types
from bot_files.config import *
# Configure logging
logging.basicConfig(level=logging.INFO)
# Initialize bot and dispatcher
bot = Bot(token=bot_token)
dp = Dispatcher(bot)
#dp.message_handler()
async def echo(message: types.Message):
await asyncio.sleep(10)
await message.answer(message.text)
if __name__ == '__main__':
executor.start_polling(dp, skip_updates=True)
Telegram-bot on Webhooks:
import asyncio
import logging
from aiogram import Bot, Dispatcher, executor, types
from bot_files.config import *
# Configure logging
logging.basicConfig(level=logging.INFO)
# Initialize bot and dispatcher
bot = Bot(token=bot_token)
dp = Dispatcher(bot)
WEBHOOK_HOST = f'https://7417-176-8-60-184.ngrok.io'
WEBHOOK_PATH = f'/webhook/{bot_token}'
WEBHOOK_URL = f'{WEBHOOK_HOST}{WEBHOOK_PATH}'
# webserver settings
WEBAPP_HOST = '0.0.0.0'
WEBAPP_PORT = os.getenv('PORT', default=5000)
async def on_startup(dispatcher):
await bot.set_webhook(WEBHOOK_URL, drop_pending_updates=True)
async def on_shutdown(dispatcher):
await bot.delete_webhook()
#dp.message_handler()
async def echo(message: types.Message):
await asyncio.sleep(10)
await message.answer(message.text)
if __name__ == '__main__':
executor.start_webhook(
dispatcher=dp,
webhook_path=WEBHOOK_PATH,
skip_updates=True,
on_startup=on_startup,
on_shutdown=on_shutdown,
host=WEBAPP_HOST,
port=WEBAPP_PORT
)
In the first case, if two users send messages simultaneously, both of messages are processed also simultaneously(acynchrony) - 10 seconds. In the second case messages are processed linearly(not asynchrony) - one of two users must wait 20 seconds. Why telegram-bot on Python with Webhooks can't process messages from many users simultaneously unlike a bot with Long Polling?
Actually telegram-bot on Python with Webhooks can process messages from many users simultaneously. You need just to put #dp.async_task after handler
#dp.message_handler()
#dp.async_task
async def echo(message: types.Message):
await asyncio.sleep(10)
await message.answer(message.text)
Installed aiogram version 20.0.4. Python - version 3.10.4. Wrote the echo of the bot for telegrams, when the bot is allowed to /start, it is silent. Where is the mistake ?
`import logging
from aiogram import Bot, Dispatcher, executor, types
API_TOKEN = '...'
logging.basicConfig(level=logging.INFO)
bot = Bot(token=API_TOKEN)
dp = Dispatcher(bot)
#dp.message_handler(commands=['start', 'help'])
async def send_welcome(message: types.Message):
await message.reply("Hi!\nI'm EchoBot!\nPowered by
aiogram.")
#dp.message_handler()
async def echo(message: types.Message):
await message.answer(message.text)
if __name__ == '__main__':
executor.start_polling(dp, skip_updates=True)`
I'm hosting a python discord bot on Replit.com 24/7 with a hacker plan.
Is there a way to make the bot DM me when the code stops running by any reason?
I've tried the atexit and signal function but it's not doing anything when I stop the code. Here's the code:
import atexit
import signal
async def handle_exit():
user = await getUserByID(my_ID)
await user.send(f"{bot.user} is offline! :x:")
atexit.register(handle_exit)
signal.signal(signal.SIGTERM, handle_exit)
signal.signal(signal.SIGINT, handle_exit)
#discord code here
Any other way than DM on discord is okay too, as long as I get notified when the bot goes offline.
Thank you in advance.
ok, so u have to add an file with flask server :
from threading import Thread
from itertools import cycle
from flask import Flask
app = Flask('')
#app.route('/test')
def main():
return "Your Bot Is Ready"
#app.route('/')
def lol():
return "Your Bot Is Ready"
def run():
app.run(host="0.0.0.0", port=8080)
def keep_alive():
server = Thread(target=run)
server.start()
and then import that file in ur main.py or bot file and then add file_name.keep_alive()
and then make a new bot and use following code:
from discord.ext import commands
import requests
bot = commands.Bot(prefix="!")
#client.event
async def on_ready():
channel = bot.get_channel()
while True:
r = requests.get("url that u get on bar of replit")
if r.status_code != 200:
await channel.send("bot is offline")
bot.run("token of another bot")
and to get url