Как написать логи telegram бота python для вывода всех сообщений в консоль
Вот код, который у меня есть:
from aiogram import Bot, types, Dispatcher, Router, F
from aiogram.filters import Command
import asyncio
import uuid
import json
import websockets
bot.polling(none_stop=True, interval=0)
token = 'токен бота' # Ваш токен бота взятый из @BotFather
runware_api = 'апи нейронки' # Тот самый ключик разработчиков для работы нейросети
bot = Bot(token=token)
dp = Dispatcher()
router = Router()
async def create_image(prompt): # Генерируем картинку
async with websockets.connect('wss://ws-api.runware.ai/v1') as websocket:
auth_request = [{"taskType": "authentication","apiKey": runware_api}]
await websocket.send(json.dumps(auth_request)) # Логинимся и получаем успешный ответ от сервера
auth_response = await websocket.recv()
n = 1
image_request = [{"positivePrompt": prompt,"model": "runware:100@1",'steps':4,'width':512,'height':512,'numberResults':n,'outputType':['URL'],'taskType':'imageInference','taskUUID':uuid.uuid4().hex}]
await websocket.send(json.dumps(image_request)) # Отправляем запрос на генерацию и получаем картинку
img = await websocket.recv()
data = json.loads(img)['data'][0]
return data
@router.message(Command('start')) # Добавляем ответ на команду /start
async def start(message: types.Message):
await message.answer('Привет!\nЯ бот для моментальной генерации картинок, отправь мне на английском любой промпт и я в ту же секунду сгенерирую тебе изображение')
@router.message() # Ловим промпты
async def gen(message: types.Message):
if not message.text:
return await message.answer('Отправь мне запрос текстом, я не понимаю другие форматы :(')
msg = await message.answer(f'Начинаю генерацию по запросу:\n\n{message.text}')
image = await create_image(message.text)
await message.answer_photo(image['imageURL'], caption=f'Вот ваша генерация по запросу:\n\n{message.text}')
await bot.delete_messages(message.chat.id, [msg.message_id, message.message_id])
async def main():
router.message.filter(F.chat.type == 'private')
dp.include_router(router)
await dp.start_polling(bot)
if __name__ == '__main__':
print('Деньги уже текут')
asyncio.run(main())
Ответы (1 шт):
Как я понял, задача в том, чтобы текст всех сообщений, отправляемых боту, выводился в консоль. Звучит как задача для мидлвари. Причем, мидлварь должна быть внешней, чтобы первым делом сообщение попадало в неё, а потом уже обрабатывалось в хендлерах.
Про мидлвари можно прочитать в официальной документации.
Код мидлвари будет выглядеть так:
import logging
from aiogram import BaseMiddleware
from aiogram.types import Message
from typing import Callable, Dict, Awaitable, Any
# Создаем класс мидлвари, унаследованный от
# aiogram'овского BaseMiddleware
class MessageLogMiddleware(BaseMiddleware):
async def __call__(
self,
handler: Callable[[Message, Dict[str, Any]], Awaitable[Any]],
event: Message,
data: Dict[str, Any]
) -> Any:
logging.info(event.text) # Выводим текст сообщения
return await handler(event, data) # Возвращаем обновление хендлерам
# Регистрируем внешнюю миддлварь
dp.message.outer_middleware(MessageLogMiddleware())
Как это работает?
В документации есть такая замечательная картинка:
По ней наглядно видно, что сообщение (или любой другой апдейт) прилетает сначала во внешнюю мидлварь, в нашем случае - это MessageLogMiddleware
. У нее тип аргумента handler
указан как Callable[[Message, Dict[str, Any]], Awaitable[Any]]
. Здесь Message
- тип апдейта, который мы хотим ловить (мы хотим ловить сообщения).
Когда пользователь пишет что-либо боту, его сообщение попадает сперва во внешнюю мидлварь (следим по картинке), затем проходит через фильтры в простые мидлвари, а затем только попадает в хендлеры.
Мидлварь регистрируем до включения роутеров, то есть, до строчки dp.include_router(router)
, и будет у вас вывод всех сообщений в консоль.
Полный код:
import json
import uuid
import logging
import websockets
from typing import Callable, Dict, Awaitable, Any
from aiogram import Bot, types, Dispatcher, Router, F, BaseMiddleware
from aiogram.types import Message
from aiogram.filters import Command
bot.polling(none_stop=True, interval=0)
token = 'токен бота'
runware_api = 'апи нейронки'
class MessageLogMiddleware(BaseMiddleware):
async def __call__(
self,
handler: Callable[[Message, Dict[str, Any]], Awaitable[Any]],
event: Message,
data: Dict[str, Any]
) -> Any:
logging.info(event.text) # Выводим текст сообщения
return await handler(event, data)
bot = Bot(token=token)
dp = Dispatcher()
router = Router()
async def create_image(prompt): # Генерируем картинку
async with websockets.connect('wss://ws-api.runware.ai/v1') as websocket:
auth_request = [{"taskType": "authentication","apiKey": runware_api}]
await websocket.send(json.dumps(auth_request)) # Логинимся и получаем успешный ответ от сервера
auth_response = await websocket.recv()
n = 1
image_request = [{"positivePrompt": prompt,"model": "runware:100@1",'steps':4,'width':512,'height':512,'numberResults':n,'outputType':['URL'],'taskType':'imageInference','taskUUID':uuid.uuid4().hex}]
await websocket.send(json.dumps(image_request)) # Отправляем запрос на генерацию и получаем картинку
img = await websocket.recv()
data = json.loads(img)['data'][0]
return data
@router.message(Command('start')) # Добавляем ответ на команду /start
async def start(message: types.Message):
await message.answer('Привет!\nЯ бот для моментальной генерации картинок, отправь мне на английском любой промпт и я в ту же секунду сгенерирую тебе изображение')
@router.message() # Ловим промпты
async def gen(message: types.Message):
if not message.text:
return await message.answer('Отправь мне запрос текстом, я не понимаю другие форматы :(')
msg = await message.answer(f'Начинаю генерацию по запросу:\n\n{message.text}')
image = await create_image(message.text)
await message.answer_photo(image['imageURL'], caption=f'Вот ваша генерация по запросу:\n\n{message.text}')
await bot.delete_messages(message.chat.id, [msg.message_id, message.message_id])
async def main():
logging.basicConfig(level=logging.INFO) # Выставляем уровень логов на INFO
dp.message.outer_middleware(MessageLogMiddleware())
router.message.filter(F.chat.type == 'private')
dp.include_router(router)
await dp.start_polling(bot)
if __name__ == '__main__':
print('Деньги уже текут')
asyncio.run(main())