Телеграм бот в несколько файлов
Всех приветствую, делаю бота на aiogram. Из-за специфического предназначения бота, его функционал должен иметь два режима работы "отправка сообщений целиком" и "отправка с эффектом печати". Для этого было решено разделить код на три файла main.py, func1.py, func2.py. В main.py пользователь посредством Inline кнопок должен выбрать режим работы бота.
К проблеме. Из-за малого опыта, я пока не очень догоняю, как можно из одного файла запустить код бота в другом. Долго гуглил, но так и не сообразил, как это сделать.
main.py
from aiogram import Bot, types, asyncio
from aiogram.dispatcher import Dispatcher
from aiogram.utils import executor, exceptions
import config
import scenario
import markups as mark
from time import sleep as sl
from config import TOKEN
bot = Bot(token=TOKEN)
dp = Dispatcher(bot)
@dp.message_handler(commands = ['start'])
async def choice_effect(mes):
choice_button=InlineKeyboardMarkup(row_width = 1)
One = InlineKeyboardButton("Начать выполнение кода из func1.py", callback_data= "choice_one")
choice_button.add(One)
await bot.send_message(mes.chat.id, "Нажмите на кнопку для запуска кода из func1.py", reply_markup = choice_button)
@dp.callback_query_handler(text_startswith="choice_")
async def call_back0(call: types.CallbackQuery):
if call.data == 'choice_one':
#После соблюдения условия должен выполняться код из func1.py
if __name__ == "__main__":
executor.start_polling(dp, skip_updates = True)
Файл с кодом для постепенного вывода сообщений.
func1.py
from aiogram import Bot, types, asyncio
from aiogram.dispatcher import Dispatcher
from aiogram.utils import executor, exceptions
import config
import scenario
import markups as mark
from time import sleep as sl
from config import TOKEN
bot = Bot(token=TOKEN)
dp = Dispatcher(bot)
f = list(open ('file_with_text.txt', encoding = 'Windows-1251'))
@dp.message_handler("Пока не знаю, что сюда передать")
async def start(message: types.Message):
for i, line in enumerate(f):
if i < 7:
orig_text = line
msg = await bot.send_message(message.chat.id, 'I')
sl(0.1)
tbp = orig_text[:1]
for x in orig_text[1:]:
try:
await bot.edit_message_text(chat_id=message.chat.id, message_id=msg.message_id, text=f'{tbp}|')
sl(0.1)
tbp += x
await bot.edit_message_text(chat_id=message.chat.id, message_id=msg.message_id, text=tbp)
except exceptions.RetryAfter as e:
await asyncio.sleep(e.timeout)
Ответы (2 шт):
Если вопрос состоит в том как вызвать метод/код из другого файла на питоне, то вы можете его подключить в main.py следующим образом (если они в одном каталоге):
from func1 import *
При этом вы сможете вызвать метод start расположенный func1.py. Но вам придется удалить как миниумум следующий код из func1.py, так как при подключении файла они вызовутся автоматически.
bot = Bot(token=TOKEN)
dp = Dispatcher(bot)
Используйте роутеры, в Aiogram 3.x, они позволяют вам добиться многофайловой структуры.
Можно показать на примере, как работают роутере.
Создадим файл main.py, в котором у нас будет инициализироваться бот, добавим функцию main(), в которой будет запускаться поллинг бота.
import asyncio
from aiogram import Bot, Dispatcher
async def main():
bot = Bot(token="TOKEN")
dp = Dispatcher()
await dp.start_polling(bot)
if __name__ == "__main__":
asyncio.run(main())
Создадим новый файл msg.py, в котором будет содержаться команда /start. Помимо стандартного импорта, укажите Router, то есть from aiogram import Router. И как обычно слушаем команду пользователя и пишем какой-нибудь ответ. Однако, вместо привычного Dispatcher мы должны использовать Router.
То есть теперь router = Router(), в результате получается
from aiogram import Router
from aiogram.filters import CommandStart
router = Router()
@router.message(CommandStart())
async def message_with_text(message: Message):
await message.answer("Привет!")
Как же теперь сделать так, чтобы команда подключилась?
В main.py сначала импортируем наш файл msg.py, а именно его роутер.
import msg. В функции main() добавляем роутеры методом include_routers()
dp.include_routers(msg.router)
В итоге получается:
main.py
import asyncio
from aiogram import Bot, Dispatcher
import msg
async def main():
bot = Bot(token="TOKEN")
dp = Dispatcher()
dp.include_routers(msg.router) # Метод позволяет указывать роутеры, перечисляя их через запятую
# dp.include_router(msg.router) # Аналогичный вариант, который позволяет указывать роутеры по одному
# На строку
await dp.start_polling(bot)
if __name__ == "__main__":
asyncio.run(main())
msg.py
from aiogram import Router
from aiogram.filters import CommandStart
router = Router()
@router.message(CommandStart())
async def message_with_text(message: Message):
await message.answer("Привет!")