{"id":1122,"date":"2021-07-12T09:40:49","date_gmt":"2021-07-12T09:40:49","guid":{"rendered":"https:\/\/www.bearloga.space\/?page_id=1122"},"modified":"2021-07-12T09:40:49","modified_gmt":"2021-07-12T09:40:49","slug":"futbolnyj-telegram-bot-na-python-2-4-funkczionalnost-bota","status":"publish","type":"page","link":"https:\/\/www.bearloga.space\/en\/futbolnyj-telegram-bot-na-python-2-4-funkczionalnost-bota\/","title":{"rendered":"\u0424\u0443\u0442\u0431\u043e\u043b\u044c\u043d\u044b\u0439 \u0442\u0435\u043b\u0435\u0433\u0440\u0430\u043c \u0431\u043e\u0442 \u043d\u0430 Python (2\/4): \u0424\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0431\u043e\u0442\u0430"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">\u0412\u043e \u0432\u0442\u043e\u0440\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u0441\u0435\u0440\u0438\u0438 \u0441\u0442\u0430\u0442\u0435\u0439 \u043f\u043e&nbsp;<a href=\"https:\/\/pythonru.com\/primery\/python-telegram-bot\" target=\"_blank\" rel=\"noopener\">\u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044e \u0442\u0435\u043b\u0435\u0433\u0440\u0430\u043c \u0431\u043e\u0442\u0430 \u043d\u0430 python<\/a>, \u043c\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u044c. \u0411\u043e\u0442 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u0438\u0432\u0435\u0442\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u043d\u043e\u0432\u044b\u0445 \u044e\u0437\u0435\u0440\u043e\u0432, \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0442\u044c \u0432\u044b\u0431\u0440\u0430\u0442\u044c \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0442\u044c \u043b\u0438\u0433\u0438. \u0414\u043e\u0431\u0430\u0432\u0438\u043c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u043f\u043e \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u043c \u043b\u0438\u0433\u0430\u043c.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-\">\u00ab\u0420\u044b\u0431\u0430\u00bb \u043a\u043e\u0434\u0430 \u0431\u043e\u0442\u0430<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0421\u0440\u0430\u0437\u0443 \u0437\u0430\u043f\u0438\u0448\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0432 \u00abbot.py\u00bb, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u044f\u0442\u0441\u044f. \u041f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0443\u0434\u0430\u043b\u0438\u0442\u0435\u00a0<code>test_message<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># fonlinebot\/app\/bot.py\n# ...\ndp.middleware.setup(LoggingMiddleware())\n\n\n@dp.message_handler(commands=&#91;'start'])\nasync def start_handler(message: types.Message):\n    \"\"\"\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043a\u043e\u043c\u0430\u043d\u0434\u044b start. \u0412\u044b\u0432\u043e\u0434 \u0442\u0435\u043a\u0441\u0442\u0430 \u0438 \u043c\u0435\u043d\u044e\"\"\"\n    ...\n\n\n@dp.message_handler(commands=&#91;'help'])\nasync def help_handler(message: types.Message):\n    \"\"\"\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043a\u043e\u043c\u0430\u043d\u0434\u044b help. \u0412\u044b\u0432\u043e\u0434 \u0442\u0435\u043a\u0441\u0442\u0430 \u0438 \u043c\u0435\u043d\u044e\"\"\"\n    ...\n\n\n@dp.callback_query_handler(lambda c: c.data == 'main_window')\nasync def show_main_window(callback_query: types.CallbackQuery):\n    \"\"\"\u0413\u043b\u0430\u0432\u043d\u044b\u0439 \u044d\u043a\u0440\u0430\u043d\"\"\"\n    ...\n\n\n@dp.message_handler(lambda message: message.text == msg.btn_online)\n@dp.message_handler(commands=&#91;'online'])\nasync def get_results(message: types.Message):\n    \"\"\"\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043a\u043e\u043c\u0430\u043d\u0434\u044b online \u0438 \u043a\u043d\u043e\u043f\u043a\u0438 \u041e\u043d\u043b\u0430\u0439\u043d.\n    \u0417\u0430\u043f\u0440\u043e\u0441 \u043c\u0430\u0442\u0447\u0435\u0439. \u0412\u044b\u0432\u043e\u0434 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432\"\"\"\n    ...\n\n\n@dp.callback_query_handler(lambda c: c.data.startswith('update_results'))\nasync def update_results():\n    \"\"\"\u041e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432\"\"\"\n    ...\n\n\n@dp.message_handler(lambda message: message.text == msg.btn_config)\nasync def get_config(message: types.Message):\n    \"\"\"\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043a\u043d\u043e\u043f\u043a\u0438 \u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438.\n    \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0432\u044b\u0431\u043e\u0440\u0430 \u043b\u0438\u0433. \u0412\u044b\u0432\u043e\u0434 \u043c\u0435\u043d\u044e \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a\"\"\"\n    ...\n\n\n@dp.callback_query_handler(lambda c: c.data.startswith('edit_config'))\nasync def set_or_update_config(user_id: str):\n    \"\"\"\u041f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0438\u043b\u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0445 \u043b\u0438\u0433\"\"\"\n    ...\n\n\n@dp.callback_query_handler(lambda c: c.data&#91;:6] in &#91;'del_le', 'add_le'])\nasync def update_leagues_info(callback_query: types.CallbackQuery):\n    \"\"\"\u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435\/\u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u043b\u0438\u0433\u0438 \u0438\u0437 \u043a\u0435\u0448\u0430, \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f\"\"\"\n    ...\n\n\n@dp.callback_query_handler(lambda c: c.data == 'save_config')\nasync def save_config(callback_query: types.CallbackQuery):\n    \"\"\"\u0421\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0432 \u0431\u0430\u0437\u0443 \u0434\u0430\u043d\u043d\u044b\u0445\"\"\"\n    ....\n\n@dp.callback_query_handler(lambda c: c.data == 'delete_config')\nasync def delete_config(user_id: str):\n    \"\"\"\u0423\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0438\u0437 \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445\"\"\"\n    ...\n\n\n@dp.message_handler()\nasync def unknown_message(message: types.Message):\n    \"\"\"\u041e\u0442\u0432\u0435\u0442 \u043d\u0430 \u043b\u044e\u0431\u043e\u0435 \u043d\u0435\u043e\u0436\u0438\u0434\u0430\u0435\u043c\u043e\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435\"\"\"\n    ...\n\n\nasync def on_shutdown(dp):\n   # ...\n\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u042d\u0442\u043e \u043d\u0435 \u043e\u043a\u043e\u043d\u0447\u0430\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f, \u044f \u043c\u043e\u0433 \u0447\u0442\u043e-\u0442\u043e \u0443\u043f\u0443\u0441\u0442\u0438\u0442\u044c. \u0412 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u044e\u0449\u0438\u0435.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u041a\u0430\u0436\u0434\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043e\u0431\u0435\u0440\u043d\u0443\u0442\u0430 \u0434\u0435\u043a\u043e\u0440\u0430\u0442\u043e\u0440\u043e\u043c, \u0442\u0430\u043a \u043c\u044b \u043e\u0431\u0449\u0430\u0435\u043c\u0441\u044f \u0441 \u0422\u0435\u043b\u0435\u0433\u0430\u0440\u043c\u043e\u043c:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><code>@dp.message_handler(commands=['start'])<\/code>&nbsp;\u2014 \u0434\u0435\u043a\u043e\u0440\u0430\u0442\u043e\u0440 \u043e\u0436\u0438\u0434\u0430\u0435\u0442 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f-\u043a\u043e\u043c\u0430\u043d\u0434\u044b (\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0430\u0447\u0438\u043d\u0430\u044e\u0442\u0441\u044f \u0441&nbsp;<code>\/<\/code>). \u0412 \u044d\u0442\u043e\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043e\u043d \u043e\u0436\u0438\u0434\u0430\u0435\u0442 \u043a\u043e\u043c\u0430\u043d\u0434\u0443&nbsp;<code>\/start<\/code>.<\/li><li><code>@dp.callback_query_handler(lambda c: c.data == 'main_window')<\/code>&nbsp;\u2014 \u043e\u0436\u0438\u0434\u0430\u0435\u0442 callback \u0438 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 lambda-\u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0434\u043b\u044f \u0435\u0433\u043e \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u0438. Callback \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f inline-\u043a\u043d\u043e\u043f\u043a\u0430\u043c\u0438. \u0412 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043c\u044b \u043e\u0436\u0438\u0434\u0430\u0435\u043c callback \u0441\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c&nbsp;<code>'main_window'<\/code>.<\/li><li><code>@dp.message_handler(lambda message: message.text == msg.btn_config)<\/code>&nbsp;\u2014 \u044d\u0442\u043e\u0442 \u0434\u0435\u043a\u043e\u0440\u0430\u0442\u043e\u0440 \u043f\u043e\u0445\u043e\u0436 \u043d\u0430 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0439, \u043d\u043e \u043e\u0436\u0438\u0434\u0430\u0435\u0442 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043e\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f. \u0412 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0441 \u0442\u0435\u043a\u0441\u0442\u043e\u043c \u0438\u0437&nbsp;<code>msg.btn_config<\/code>.<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">\u0418\u0442\u0430\u043a. \u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0430\u0436\u0438\u043c\u0430\u0435\u0442 \u043a\u043e\u043c\u0430\u043d\u0434\u0443 \u0441\u0442\u0430\u0440\u0442, \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u043f\u0440\u0438\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435. \u0412 \u043d\u0435\u043c \u043c\u044b \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u043c \u0432\u044b\u0431\u0440\u0430\u0442\u044c 3 \u043b\u0438\u0433\u0438 \u0438 \u043c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u0442\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u043f\u043e \u043d\u0438\u043c. \u041f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u043c\u043e\u0436\u043d\u043e \u043a\u043e\u043c\u0430\u043d\u0434\u043e\u0439 \u0438\u043b\u0438 \u043a\u043d\u043e\u043f\u043a\u043e\u0439 \u043c\u0435\u043d\u044e. \u0422\u0430\u043a \u0436\u0435 \u043c\u044b \u0434\u0430\u0435\u043c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0435 \u0441\u043e\u0440\u0435\u0432\u043d\u043e\u0432\u0430\u043d\u0438\u044f \u0438\u043b\u0438 \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u0441\u0432\u043e\u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u0438\u0437 \u0431\u043e\u0442\u0430.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u041f\u043e\u043b\u043d\u044b\u0439&nbsp;<a href=\"https:\/\/gitlab.com\/PythonRu\/fonlinebot\/-\/tree\/master\/second_step\" target=\"_blank\" rel=\"noreferrer noopener\">\u043a\u043e\u0434 \u0431\u043e\u0442\u0430 \u0438\u0437 \u044d\u0442\u043e\u0433\u043e \u0443\u0440\u043e\u043a\u0430 \u043d\u0430 gitlab<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h--1\">\u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043a\u043e\u043c\u0430\u043d\u0434 \u0432 \u0431\u043e\u0442\u0430<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0418\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u043d\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043d\u044b. \u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0438 \u043c\u043e\u0433\u0443\u0442 \u0432\u0432\u043e\u0434\u0438\u0442\u044c \u0438\u0445, \u043d\u043e \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e \u043c\u0435\u043d\u044e \u043d\u0435\u0442. \u0414\u043b\u044f \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043d\u0443\u0436\u043d\u043e \u0441\u043d\u043e\u0432\u0430 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c&nbsp;<a href=\"https:\/\/t.me\/botfather\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/t.me\/botfather<\/a>&nbsp;\u043a\u043e\u043c\u0430\u043d\u0434\u0443&nbsp;<code>\/setcommands<\/code>. \u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u0441\u0432\u043e\u0435\u0433\u043e \u0431\u043e\u0442\u0430 \u0438 \u0434\u043e\u0431\u0430\u0432\u044c\u0442\u0435 \u044d\u0442\u043e\u0442 \u0442\u0435\u043a\u0441\u0442:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">start - \u0417\u0430\u043f\u0443\u0441\u043a \u0438 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a \u0431\u043e\u0442\u0430<br>help - \u0412\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0431\u043e\u0442\u0430<br>online - \u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u043c\u0430\u0442\u0447\u0435\u0439<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0412 \u043e\u0442\u0432\u0435\u0442 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0435 \u00abSuccess! Command list updated. \/help\u00bb. \u0422\u0435\u043f\u0435\u0440\u044c \u043c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u0432 \u0441\u0432\u043e\u0435\u0433\u043e \u0431\u043e\u0442\u0430 \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/pythonru.com\/wp-content\/uploads\/2021\/01\/dobavlenie-komand-v-bota.png\" alt=\" \u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043a\u043e\u043c\u0430\u043d\u0434 \u0432 \u0431\u043e\u0442\u0430\" class=\"wp-image-4619\"\/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h--2\">\u041e\u0442\u0432\u0435\u0442\u044b \u043d\u0430 \u043a\u043e\u043c\u0430\u043d\u0434\u044b<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0412\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u0441 \u0431\u043e\u0442\u043e\u043c \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u0441 \u043a\u043e\u043c\u0430\u043d\u0434\u044b&nbsp;<code>\/start<\/code>. \u041d\u0443\u0436\u043d\u043e \u043f\u043e\u043f\u0440\u0438\u0432\u0435\u0442\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u0438 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0438\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0448\u0430\u0433. \u042d\u0442\u0430 \u043a\u043e\u043c\u0430\u043d\u0434\u0430 \u0431\u0443\u0434\u0435\u0442 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c \u0442\u0435\u043a\u0441\u0442 \u0441 \u043a\u043b\u0430\u0432\u0438\u0430\u0442\u0443\u0440\u043e\u0439. \u0422\u043e\u0447\u043d\u043e \u0442\u0430\u043a \u0436\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0438&nbsp;<code>\/help<\/code>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0414\u043e\u0431\u0430\u0432\u0438\u043c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u044d\u0442\u0438\u0445 \u043a\u043e\u043c\u0430\u043d\u0434 \u0432 \u00abbot.py\u00bb, \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u0435\u00a0<code>start_handler<\/code>\u00a0<code>help_handler<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># fonlinebot\/app\/bot.py\n# ...\nfrom config import TOKEN, YEAR, MINUTE\nimport app.service as s\n\n# ...\n@dp.message_handler(commands=&#91;'start'])\nasync def start_handler(message: types.Message):\n    \"\"\"\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043a\u043e\u043c\u0430\u043d\u0434\u044b start. \u0412\u044b\u0432\u043e\u0434 \u0442\u0435\u043a\u0441\u0442\u0430 \u0438 \u043c\u0435\u043d\u044e\"\"\"\n    # \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430, \u0435\u0441\u0442\u044c \u043b\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0432 \u0431\u0430\u0437\u0435\n    user_league_ids = await s.get_league_ids(message.from_user.id)\n    if not user_league_ids:\n        await message.answer(msg.start_new_user)\n        #  \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 id \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a\n        cache.setex(f\"last_msg_{message.from_user.id}\", YEAR, message.message_id+2)\n        await set_or_update_config(user_id=message.from_user.id)\n    else:\n        await message.answer(msg.start_current_user,\n                             reply_markup=s.MAIN_KB)\n\n\n@dp.message_handler(commands=&#91;'help'])\nasync def help_handler(message: types.Message):\n    \"\"\"\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043a\u043e\u043c\u0430\u043d\u0434\u044b help. \u0412\u044b\u0432\u043e\u0434 \u0442\u0435\u043a\u0441\u0442\u0430 \u0438 \u043c\u0435\u043d\u044e\"\"\"\n    await message.answer(msg.help, reply_markup=s.MAIN_KB)\n\n# ...\n\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u042f \u0434\u043e\u0431\u0430\u0432\u0438\u043b \u0438\u043c\u043f\u043e\u0440\u0442&nbsp;<code>import app.service as s<\/code>. \u0412 \u044d\u0442\u043e\u043c \u043c\u043e\u0434\u0443\u043b\u0435 \u043a\u043b\u0430\u0432\u0438\u0430\u0442\u0443\u0440\u0430 \u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f.&nbsp;<code>start_handler<\/code>&nbsp;\u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442 \u0435\u0441\u0442\u044c \u043b\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0432 \u043a\u0435\u0448\u0435 \u0438\u043b\u0438 \u0431\u0430\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445, \u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u0435\u043c\u0443 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 \u0442\u0435\u043a\u0441\u0442.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u041f\u0435\u0440\u0435\u0434 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u043e\u0439 \u0442\u0435\u043a\u0441\u0442\u0430 \u0434\u043b\u044f \u0432\u044b\u0431\u043e\u0440\u0430 \u043b\u0438\u0433, \u044f \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u043b \u0435\u0433\u043e \u0431\u0443\u0434\u0443\u0449\u0438\u0439 id. \u041f\u043e\u043b\u0443\u0447\u0438\u043b \u043d\u043e\u043c\u0435\u0440 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0433\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f (\u044d\u0442\u043e \u0441\u0430\u043c\u0430 \u043a\u043e\u043c\u0430\u043d\u0434\u0430 \u00abstart\u00bb) \u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u043b 2 \u043f\u0443\u043d\u043a\u0442\u0430: +1 \u0437\u0430 \u043d\u0430\u0448 \u043e\u0442\u0432\u0435\u0442 \u043d\u0430 \u043a\u043e\u043c\u0430\u043d\u0434\u0443 \u0438 +1 \u0437\u0430 \u0441\u0430\u043c\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0432\u044b\u0431\u043e\u0440\u0430 \u043b\u0438\u0433. \u0417\u043d\u0430\u044f id \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f, \u0435\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u0432\u0430\u0442\u044c.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u043a\u043b\u0430\u0432\u0438\u0430\u0442\u0443\u0440\u0443 \u0438\u00a0<code>get_league_ids<\/code>\u00a0\u0432 \u043c\u043e\u0434\u0443\u043b\u044c \u00abservice\u00bb.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># fonlinebot\/app\/service.py\nfrom aiogram.types import ReplyKeyboardMarkup, KeyboardButton, \\\n                          InlineKeyboardMarkup, InlineKeyboardButton\nfrom emoji import emojize\nfrom config import BOT_LEAGUES, BOT_LEAGUE_FLAGS\nfrom database import cache, database as db\nfrom app.dialogs import msg\n\n\nMAIN_KB = ReplyKeyboardMarkup(\n    resize_keyboard=True,\n    one_time_keyboard=True\n).row(\n    KeyboardButton(msg.btn_online),\n    KeyboardButton(msg.btn_config)\n)\n\n\nasync def get_league_ids(user_id: str) -&gt; list:\n    \"\"\"\u0424\u0443\u043d\u043a\u0446\u0438\u044f \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 id \u043b\u0438\u0433 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0432 \u0431\u0430\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445\"\"\"\n    leagues = cache.lrange(f\"u{user_id}\", 0, -1)\n    if leagues is None:\n        leagues = await db.select_users(user_id)\n        if leagues is not None:\n            leagues = leagues.split(',')\n            &#91;cache.lpush(f\"u{user_id}\", lg_id) for lg_id in leagues]\n        else:\n            return &#91;]\n    return leagues\n\n<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/pythonru.com\/wp-content\/uploads\/2021\/01\/otvety-na-komandy.png\" alt=\"\u041e\u0442\u0432\u0435\u0442\u044b \u043d\u0430 \u043a\u043e\u043c\u0430\u043d\u0434\u044b\" class=\"wp-image-4622\"\/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><code>MAIN_KB<\/code>&nbsp;\u2014 \u043e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u043a\u043b\u0430\u0432\u0438\u0430\u0442\u0443\u0440\u0430, \u043a\u0430\u043a \u043d\u0430 \u0441\u043a\u0440\u0438\u043d\u0448\u043e\u0442\u0435 \u0432\u044b\u0448\u0435. \u0420\u0430\u0437\u0431\u0435\u0440\u0435\u043c \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><code>ReplyKeyboardMarkup<\/code>&nbsp;\u2014 \u043e\u0431\u044a\u0435\u043a\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u043e\u0437\u0434\u0430\u0435\u0442 \u043a\u043b\u0430\u0432\u0438\u0430\u0442\u0443\u0440\u0443.<\/li><li>\u041f\u0430\u0440\u0430\u043c\u0435\u0442\u0440&nbsp;<code>resize_keyboard=True<\/code>&nbsp;\u0443\u043c\u0435\u043d\u044c\u0448\u0430\u0435\u0442 \u0435\u0435 \u0440\u0430\u0437\u043c\u0435\u0440.<\/li><li>\u0410 \u0441&nbsp;<code>one_time_keyboard=True<\/code>&nbsp;\u043a\u043b\u0430\u0432\u0438\u0430\u0442\u0443\u0440\u0430 \u0431\u0443\u0434\u0435\u0442 \u0441\u043a\u0440\u044b\u0432\u0430\u0442\u044c\u0441\u044f, \u043f\u043e\u0441\u043b\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f.<\/li><li><code>.row<\/code>&nbsp;\u2014 \u043c\u0435\u0442\u043e\u0434 \u0434\u043b\u044f \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0438 \u043a\u043d\u043e\u043f\u043e\u043a \u0432 \u0441\u0442\u0440\u043e\u043a\u0443.<\/li><li><code>KeyboardButton(msg.btn_online)<\/code>&nbsp;\u0438&nbsp;<code>KeyboardButton(msg.btn_config)<\/code>&nbsp;\u2014 \u043a\u043d\u043e\u043f\u043a\u0438 \u0441 \u0437\u0430\u0434\u0430\u043d\u043d\u044b\u043c \u0442\u0435\u043a\u0441\u0442\u043e\u043c.<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">\u041e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0442\u0435\u043a\u0441\u0442\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0432 dialogs. \u0412\u0441\u0442\u0430\u0432\u044c\u0442\u0435 \u044d\u0442\u043e\u0442 \u043a\u043e\u0434 \u0432 \u043a\u043b\u0430\u0441\u0441\u00a0<code>Messages<\/code>.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># fonlinebot\/app\/dialogs.py\n    # ...\n    start_new_user: str = \"\u041f\u0440\u0438\u0432\u0435\u0442. \u042f \u043c\u043e\u0433\u0443 \u0441\u043e\u043e\u0431\u0449\u0430\u0442\u044c \u0442\u0435\u0431\u0435 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u043c\u0430\u0442\u0447\u0435\u0439 online.\"\n    start_current_user: str = \"\u041f\u0440\u0438\u0432\u0435\u0442. \u0421 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0435\u043d\u0438\u0435\u043c! \" \\\n                              \"\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439 \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u0438\u043b\u0438 \u043c\u0435\u043d\u044e \u0432\u043d\u0438\u0437\u0443 \u0434\u043b\u044f \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u044f.\"\n    help: str = \"\"\"\n    \u042d\u0442\u043e\u0442 \u0431\u043e\u0442 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u043c\u0430\u0442\u0447\u0435\u0439 \u0437\u0430 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0435 48 \u0447\u0430\u0441\u043e\u0432.\n    \u0412\u043a\u043b\u044e\u0447\u0430\u044f \u0440\u0435\u0436\u0438\u043c LIVE.\n    - \u0427\u0442\u043e \u0431\u044b \u0432\u044b\u0431\u0440\u0430\u0442\u044c\/\u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u043b\u0438\u0433\u0438 \u043d\u0430\u0436\u043c\u0438\u0442\u0435 \"\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438\".\n    - \u0414\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432 \u043d\u0430\u0436\u043c\u0438\u0442\u0435 \"\u041e\u043d\u043b\u0430\u0439\u043d\".\n    \u0411\u043e\u0442 \u0441\u043e\u0437\u0434\u0430\u043d \u0432 \u0443\u0447\u0435\u0431\u043d\u044b\u0445 \u0446\u0435\u043b\u044f\u0445, \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u0430 pythonru.com\n    \"\"\"\n\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h--3\">\u0412\u044b\u0431\u043e\u0440, \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0438 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u043b\u0438\u0433<\/h2>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/pythonru.com\/wp-content\/uploads\/2021\/02\/bot-config.gif\" alt=\"\u0412\u044b\u0431\u043e\u0440, \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0438 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u043b\u0438\u0433\" class=\"wp-image-4672\"\/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">\u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u0432\u043d\u0435\u0441\u0435\u043c \u043f\u0440\u0430\u0432\u043a\u0438 \u0432 \u043d\u0430\u0448\u0438 \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u043c\u043e\u0434\u0443\u043b\u0438.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0412 \u00abdababase\u00bb \u0432 \u043a\u043b\u0430\u0441\u0441\u00a0<code>Database<\/code>\u00a0\u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043d\u043e\u0432\u044b\u0439 \u043c\u0435\u0442\u043e\u0434\u00a0<code>insert_or_update_users<\/code>.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># fonlinebot\/database.py\n#...\n\n    async def insert_or_update_users(self, user_id: int, leagues: str):\n        user_leagues = await self.select_users(user_id)\n        if user_leagues is not None:\n            await self.update_users(user_id, leagues)\n        else:\n            await self.insert_users(user_id, leagues)\n#...\n\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0412 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u043c\u0435\u0442\u0440\u0438\u043a \u0432\u0440\u0435\u043c\u0435\u043d\u0438:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># fonlinebot\/config.py\n#...\n\nMINUTE = 60\nYEAR = 60*60*24*366\n\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0418 \u0434\u043e\u043f\u0438\u0448\u0435\u043c \u0442\u0435\u043a\u0441\u0442\u0430 \u0434\u043b\u044f \u0431\u043b\u043e\u043a\u0430 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># fonlinebot\/app\/dialogs.py\n# ...\n    league_row: str = \"{i}. {flag} {name}\"\n    config: str = \"\u0421\u0435\u0439\u0447\u0430\u0441 \u0432\u044b\u0431\u0440\u0430\u043d\u044b:\\n{leagues}\"\n    btn_back: str = \"&lt;- \u041d\u0430\u0437\u0430\u0434\"\n    btn_go: str = \"\u0412\u043f\u0435\u0440\u0435\u0434 -&gt;\"\n    btn_save: str = \"\u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c\"\n    config_btn_edit: str = \"\u0418\u0437\u043c\u0435\u043d\u0438\u0442\u044c\"\n    config_btn_delete: str = \"\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435\"\n    data_delete: str = \"\u0414\u0430\u043d\u043d\u044b\u0435 \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0443\u0434\u0430\u043b\u0435\u043d\u044b\"\n    set_leagues: str = \"\u0412\u044b\u0431\u0435\u0440\u0438 3 \u043b\u0438\u0433\u0438 \u0434\u043b\u044f \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u043d\u0438\u044f.\\n\u0412\u044b\u0431\u0440\u0430\u043d\u044b:\\n{leagues}\"\n    main: str = \"\u0427\u0442\u043e \u0431\u0443\u0434\u0435\u043c \u0434\u0435\u043b\u0430\u0442\u044c?\"\n    db_saved: str = \"\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u044b\"\n    cb_not_saved: str = \"\u041b\u0438\u0433\u0438 \u043d\u0435 \u0432\u044b\u0431\u0440\u0430\u043d\u044b\"\n    cb_limit: str = \"\u041f\u0440\u0435\u0432\u044b\u0448\u0435\u043d \u043b\u0438\u043c\u0438\u0442. \u041c\u0430\u043a\u0441\u0438\u043c\u0443\u043c 3 \u043b\u0438\u0433\u0438.\"\n\n# ...\n\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u041d\u0430 \u044d\u0442\u043e\u043c \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0430 \u043e\u043a\u043e\u043d\u0447\u0435\u043d\u0430, \u043f\u043e\u0440\u0430 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043b\u043e\u0433\u0438\u043a\u0443 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043b\u0438\u0433. \u0412 \u043c\u043e\u0434\u0443\u043b\u044c \u00abservice\u00bb \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0434\u0432\u0435 inline-\u043a\u043b\u0430\u0432\u0438\u0430\u0442\u0443\u0440\u044b.<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\" id=\"h-inline-callback\"><p>Inline-\u043a\u043b\u0430\u0432\u0438\u0430\u0442\u0443\u0440\u0430 \u043f\u0440\u0438\u0432\u044f\u0437\u0430\u043d\u0430 \u043a \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u043c\u0443 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044e. \u0421 \u0438\u0445 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043c\u043e\u0436\u043d\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0438 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0441\u0438\u0433\u043d\u0430\u043b\u044b \u0431\u043e\u0442\u0443.<\/p><\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># fonlinebot\/app\/service.py\n# ...\n\nCONFIG_KB = InlineKeyboardMarkup().row(\n    InlineKeyboardButton(msg.btn_back, callback_data='main_window'),\n    InlineKeyboardButton(msg.config_btn_edit, callback_data='edit_config#')\n).add(InlineKeyboardButton(msg.config_btn_delete, callback_data='delete_config'))\n\n\ndef leagues_kb(active_leagues: list, offset: int = 0):\n    kb = InlineKeyboardMarkup()\n    league_keys = list(BOT_LEAGUES.keys())&#91;0+offset:5+offset]\n    for lg_id in league_keys:\n        if lg_id in active_leagues:\n            kb.add(InlineKeyboardButton(\n                f\"{emojize(':white_heavy_check_mark:')} {BOT_LEAGUES&#91;lg_id]}\",\n                callback_data=f'del_league_#{offset}#{lg_id}'\n            ))\n        else:\n            kb.add(InlineKeyboardButton(\n                BOT_LEAGUES&#91;lg_id],\n                callback_data=f'add_league_#{offset}#{lg_id}'\n            ))\n    kb.row(\n        InlineKeyboardButton(\n            msg.btn_back if offset else msg.btn_go,\n            callback_data=\"edit_config#0\" if offset else \"edit_config#5\"),\n        InlineKeyboardButton(msg.btn_save, callback_data=\"save_config\")\n    )\n    return kb\n# ...\n\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0412 \u043a\u043b\u0430\u0432\u0438\u0430\u0442\u0443\u0440\u0435&nbsp;<code>CONFIG_KB<\/code>&nbsp;3 \u043a\u043d\u043e\u043f\u043a\u0438. \u041a\u043b\u0430\u0441\u0441 \u043a\u043d\u043e\u043f\u043a\u0438&nbsp;<code>InlineKeyboardButton<\/code>&nbsp;\u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0442\u0435\u043a\u0441\u0442 \u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440&nbsp;<code>callback_data<\/code>. \u0418\u043c\u0435\u043d\u043d\u043e callback \u043d\u0430\u043c \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442 \u0422\u0435\u043b\u0435\u0433\u0440\u0430\u043c \u043f\u043e\u0441\u043b\u0435 \u043d\u0430\u0436\u0430\u0442\u0438\u044f \u043d\u0430 \u043a\u043d\u043e\u043f\u043a\u0443. \u0412\u043e\u0442 \u0442\u0430\u043a \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u044d\u0442\u0430 \u043a\u043b\u0430\u0432\u0438\u0430\u0442\u0443\u0440\u0430:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/pythonru.com\/wp-content\/uploads\/2021\/02\/inline-klaviatura.png\" alt=\"Inline-\u043a\u043b\u0430\u0432\u0438\u0430\u0442\u0443\u0440\u0430\" class=\"wp-image-4685\"\/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">\u0410&nbsp;<code>leagues_kb<\/code>&nbsp;\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 \u0431\u043e\u043b\u0435\u0435 \u0441\u043b\u043e\u0436\u043d\u0443\u044e \u043a\u043b\u0430\u0432\u0438\u0430\u0442\u0443\u0440\u0443, \u0441 \u043f\u0430\u0433\u0438\u043d\u0430\u0446\u0438\u0435\u0439. \u041c\u044b \u0432\u044b\u0432\u043e\u0434\u0438\u043c 5 \u043b\u0438\u0433, \u043a\u043d\u043e\u043f\u043a\u0443 \u00ab\u0434\u0430\u043b\u0435\u0435\/\u043d\u0430\u0437\u0430\u0434\u00bb \u0438 \u00ab\u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c\u00bb. \u0424\u0443\u043d\u043a\u0446\u0438\u044f \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0435 \u043b\u0438\u0433\u0438 \u0438 \u043e\u0442\u0441\u0442\u0443\u043f. \u041e\u0442\u0441\u0442\u0443\u043f \u043d\u0443\u0436\u0435\u043d, \u0434\u043b\u044f \u0432\u044b\u0432\u043e\u0434\u0430 \u043b\u0438\u0433 \u043f\u043e\u0441\u0442\u0440\u0430\u043d\u0438\u0447\u043d\u043e.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u041a\u043e\u0433\u0434\u0430 \u044e\u0437\u0435\u0440 \u043d\u0430\u0436\u0438\u043c\u0430\u0435\u0442 \u043d\u0430 \u043b\u0438\u0433\u0443, \u043c\u044b \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0435\u0435 \u0432 \u043a\u0435\u0448, \u043d\u0430\u0436\u0438\u043c\u0430\u0435\u0442 \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e \u2014 \u0443\u0434\u0430\u043b\u044f\u0435\u043c. \u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u044f \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u044e \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0443\u044e \u0441\u0442\u0440\u043e\u043a\u0443 \u0432&nbsp;<code>callback_data<\/code>. \u041f\u043e\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u044e \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b&nbsp;<code>offset<\/code>&nbsp;\u0438&nbsp;<code>lg_id<\/code>, \u0447\u0442\u043e \u0431\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0435.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u043a\u0440\u0430\u0441\u0438\u0432\u043e\u0433\u043e \u0432\u044b\u0432\u043e\u0434\u0430 \u0441\u043f\u0438\u0441\u043a\u0430 \u043b\u0438\u0433 \u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u044d\u0442\u043e\u0433\u043e \u0441\u043f\u0438\u0441\u043a\u0430 \u0432 \u043a\u0435\u0448\u0435:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># fonlinebot\/app\/service.py\n# ...\n\n\nasync def get_league_names(ids: list) -&gt; str:\n    \"\"\"\u0424\u0443\u043d\u043a\u0446\u0438\u044f \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u0442 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0441 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f\u043c\u0438 \u043b\u0438\u0433 \u0438\u0437 id\"\"\"\n    leagues_text = \"\"\n    for i, lg_id in enumerate(ids, start=1):\n        if i != 1:\n            leagues_text += '\\n'\n        leagues_text += msg.league_row.format(\n            i=i,\n            flag=emojize(BOT_LEAGUE_FLAGS.get(lg_id, '-')),\n            name=BOT_LEAGUES.get(lg_id, '-')\n        )\n    return leagues_text\n\n\ndef update_leagues(user_id: str, data: str):\n    \"\"\"\u0424\u0443\u043d\u043a\u0446\u0438\u044f \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u0438\u043b\u0438 \u0443\u0434\u0430\u043b\u044f\u0435\u0442 id \u043b\u0438\u0433\u0438 \u0434\u043b\u044f \u044e\u0437\u0435\u0440\u0430\"\"\"\n    league_id = data.split(\"#\")&#91;-1]  # data ~ add_league_#5#345\n    if data.startswith(\"add\"):\n        cache.lpush(f\"u{user_id}\", league_id)\n    else:\n        cache.lrem(f\"u{user_id}\", 0, league_id)\n\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h--4\">\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0441 \u0422\u0435\u043b\u0435\u0433\u0440\u0430\u043c\u043e\u043c<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">\u0412 \u0444\u0430\u0439\u043b\u0435 \u0431\u043e\u0442\u0430 \u0434\u043e\u043f\u0438\u0448\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0434\u043b\u044f \u043c\u0435\u043d\u044e \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># fonlinebot\/app\/bot.py\n\n@dp.callback_query_handler(lambda c: c.data == 'main_window')\nasync def show_main_window(callback_query: types.CallbackQuery):\n    \"\"\"\u0413\u043b\u0430\u0432\u043d\u044b\u0439 \u044d\u043a\u0440\u0430\u043d\"\"\"\n    await callback_query.answer()\n    await bot.send_message(callback_query.from_user.id, msg.main, reply_markup=s.MAIN_KB)\n\n\ndp.message_handler(lambda message: message.text == msg.btn_config)\nasync def get_config(message: types.Message):\n    \"\"\"\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043a\u043d\u043e\u043f\u043a\u0438 \u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438.\n    \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0432\u044b\u0431\u043e\u0440\u0430 \u043b\u0438\u0433. \u0412\u044b\u0432\u043e\u0434 \u043c\u0435\u043d\u044e \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a\"\"\"\n    user_league_ids = await s.get_league_ids(message.from_user.id)\n    if user_league_ids:\n        cache.setex(f\"last_msg_{message.from_user.id}\", YEAR, message.message_id+2)\n        leagues = await s.get_league_names(user_league_ids)\n        await message.answer(msg.config.format(leagues=leagues),\n                             reply_markup=s.CONFIG_KB)\n    else:\n        cache.setex(f\"last_msg_{message.from_user.id}\", YEAR, message.message_id+1)\n        await set_or_update_config(user_id=message.from_user.id)\n\n\n@dp.callback_query_handler(lambda c: c.data == 'delete_config')\nasync def delete_config(callback_query: types.CallbackQuery):\n    \"\"\"\u0423\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0438\u0437 \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445\"\"\"\n    await db.delete_users(callback_query.from_user.id)\n    cache.delete(f\"u{callback_query.from_user.id}\")\n    await callback_query.answer()\n    cache.incr(f\"last_msg_{callback_query.from_user.id}\")\n    await bot.send_message(callback_query.from_user.id,\n                           msg.data_delete,\n                           reply_markup=s.MAIN_KB)\n\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0424\u0443\u043d\u043a\u0446\u0438\u044f&nbsp;<code>get_config<\/code>&nbsp;\u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u043e\u0441\u043b\u0435 \u043d\u0430\u0436\u0430\u0442\u0438\u044f \u043d\u0430 \u00ab\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438\u00bb. \u0415\u0441\u043b\u0438 \u0443 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0432\u044b\u0431\u0440\u0430\u043d\u044b \u043b\u0438\u0433\u0438, \u043e\u043d\u0430 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0438 \u043c\u0435\u043d\u044e \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a. \u0412 \u0434\u0440\u0443\u0433\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0437\u0432\u0430\u043d\u0430&nbsp;<code>set_or_update_config<\/code>&nbsp;\u0434\u043b\u044f \u0432\u044b\u0431\u043e\u0440\u0430 \u043b\u0438\u0433.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u041e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u044f \u0434\u043e\u0431\u0430\u0432\u0438\u043b \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438 \u0433\u043b\u0430\u0432\u043d\u044b\u0439 \u044d\u043a\u0440\u0430\u043d.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0421\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0438 \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u043f\u0438\u0441\u043e\u043a \u0431\u0443\u0434\u0435\u043c \u0432 \u043e\u0434\u043d\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438. \u0415\u0439 \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u044f\u0442\u0441\u044f \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0438\u0437 \u0441\u0442\u0440\u043e\u043a\u0438 callback. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0430\u0436\u0430\u043b \u00ab\u0432\u043f\u0435\u0440\u0435\u0434 ->\u00bb \u0438 \u0422\u0435\u043b\u0435\u0433\u0440\u0430\u043c \u043f\u0440\u0438\u0441\u043b\u0430\u043b\u00a0<code>\"edit_config#5\"<\/code>. \u041c\u044b \u0440\u0430\u0437\u0434\u0435\u043b\u0438\u043b\u0438 \u0441\u0442\u0440\u043e\u043a\u0443 \u043f\u043e\u00a0<code>#<\/code>\u00a0\u0438 \u0432\u0437\u044f\u043b\u0438 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 (\u20185\u2019). \u0422\u0430\u043a \u0431\u0443\u0434\u0443\u0442 \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c\u0441\u044f \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u043c\u0435\u0436\u0434\u0443 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f\u043c\u0438.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># fonlinebot\/app\/bot.py\n\n@dp.callback_query_handler(lambda c: c.data.startswith('edit_config'))\nasync def set_or_update_config(callback_query: types.CallbackQuery = None,\n                               user_id=None, offset=\"\"):\n    \"\"\"\u041f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0438\u043b\u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0445 \u043b\u0438\u0433\"\"\"\n    # \u0435\u0441\u043b\u0438 \u043f\u0440\u0438\u0448\u0435\u043b callback, \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u0434\u0430\u043d\u043d\u044b\u0435\n    if callback_query is not None:\n        user_id = callback_query.from_user.id\n        offset = callback_query.data.split(\"#\")&#91;-1]\n\n    league_ids = await s.get_league_ids(user_id)\n    leagues = await s.get_league_names(league_ids)\n\n    # \u0435\u0441\u043b\u0438 \u044d\u0442\u043e \u043f\u0435\u0440\u0432\u044b\u0439 \u0432\u044b\u0437\u043e\u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u043c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435\n    # \u0435\u0441\u043b\u0438 \u043d\u0435\u0442, \u043e\u0442\u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u0443\u0435\u043c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0438 \u043a\u043b\u0430\u0432\u0438\u0430\u0442\u0443\u0440\u0443\n    if offset == \"\":\n        await bot.send_message(\n            user_id,\n            msg.set_leagues.format(leagues=leagues),\n            reply_markup=s.leagues_kb(league_ids)\n        )\n    else:\n        msg_id = cache.get(f\"last_msg_{user_id}\")\n        await bot.edit_message_text(\n            msg.set_leagues.format(leagues=leagues),\n            user_id,\n            message_id=msg_id\n        )\n        await bot.edit_message_reply_markup(\n            user_id,\n            message_id=msg_id,\n            reply_markup=s.leagues_kb(league_ids, int(offset))\n        )\n\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u041d\u0435 \u0445\u0432\u0430\u0442\u0430\u0435\u0442 \u0435\u0449\u0435 \u0440\u0435\u0430\u043a\u0446\u0438\u0438 \u043d\u0430 \u043d\u0430\u0436\u0430\u0442\u0438\u0435 \u043f\u043e \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044e \u043b\u0438\u0433 \u0438 \u043a\u043d\u043e\u043f\u043a\u0435 \u00ab\u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c\u00bb.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># fonlinebot\/app\/bot.py\n\ndp.callback_query_handler(lambda c: c.data&#91;:6] in &#91;'del_le', 'add_le'])\nasync def update_leagues_info(callback_query: types.CallbackQuery):\n    \"\"\"\u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435\/\u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u043b\u0438\u0433\u0438 \u0438\u0437 \u043a\u0435\u0448\u0430, \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f\"\"\"\n    offset = callback_query.data.split(\"#\")&#91;-2]\n    s.update_leagues(callback_query.from_user.id, callback_query.data)\n    await set_or_update_config(user_id=callback_query.from_user.id, offset=offset)\n    await callback_query.answer()\n\n\n@dp.callback_query_handler(lambda c: c.data == 'save_config')\nasync def save_config(callback_query: types.CallbackQuery):\n    \"\"\"\u0421\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0432 \u0431\u0430\u0437\u0443 \u0434\u0430\u043d\u043d\u044b\u0445\"\"\"\n    leagues_list = await s.get_league_ids(callback_query.from_user.id)\n    if len(leagues_list) &gt; 3:\n        # \u043d\u0435 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c, \u0435\u0441\u043b\u0438 \u043f\u0440\u0435\u0432\u044b\u0448\u0435\u043d \u043b\u0438\u043c\u0438\u0442 \u043b\u0438\u0433\n        await callback_query.answer(msg.cb_limit, show_alert=True)\n    elif leagues_list:\n        await db.insert_or_update_users(\n            callback_query.from_user.id,\n            \",\".join(leagues_list)\n        )\n        await callback_query.answer()\n        await bot.send_message(\n            callback_query.from_user.id,\n            msg.db_saved,\n            reply_markup=s.MAIN_KB\n        )\n    else:\n        # \u043d\u0435 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u0435\u0441\u043b\u0438 \u0441\u043f\u0438\u0441\u043e\u043a \u043f\u0443\u0441\u0442\u043e\u0439\n        await callback_query.answer(msg.cb_not_saved)\n\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0413\u043e\u0442\u043e\u0432\u043e. \u0422\u0435\u043f\u0435\u0440\u044c \u043c\u043e\u0436\u0435\u0442\u0435 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0431\u043e\u0442\u0430 \u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043b\u0438\u0433\u0438 \u0432 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u0445.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h--5\">\u0421\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0441 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430\u043c\u0438 \u043c\u0430\u0442\u0447\u0435\u0439<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0422\u0430\u043a \u043a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430 \u0441 API \u0435\u0449\u0435 \u043d\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043d\u0430, \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u0437\u0430\u0433\u043b\u0443\u0448\u043a\u0443 \u0434\u043b\u044f \u044d\u0442\u0438\u0445 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0432.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># fonlinebot\/app\/bot.py\n\n@dp.message_handler(lambda message: message.text == msg.btn_online)\n@dp.message_handler(commands=&#91;'online'])\nasync def get_results(message: types.Message):\n    \"\"\"\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043a\u043e\u043c\u0430\u043d\u0434\u044b online \u0438 \u043a\u043d\u043e\u043f\u043a\u0438 \u041e\u043d\u043b\u0430\u0439\u043d.\n    \u0417\u0430\u043f\u0440\u043e\u0441 \u043c\u0430\u0442\u0447\u0435\u0439. \u0412\u044b\u0432\u043e\u0434 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432\"\"\"\n    user_leagues = await s.get_league_ids(message.from_user.id)\n    cache.setex(f\"last_msg_{message.from_user.id}\", YEAR, message.message_id+1)\n    if not user_leagues:\n        await set_or_update_config(user_id=message.from_user.id)\n    else:\n        answer = await s.generate_results_answer(user_leagues)\n        cache.setex(f\"last_update_{message.from_user.id}\", MINUTE, \"Updated\")\n        await message.answer(answer, reply_markup=s.results_kb(user_leagues))\n\n\n@dp.callback_query_handler(lambda c: c.data.startswith('update_results'))\nasync def update_results(callback_query: types.CallbackQuery):\n    \"\"\"\u041e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432\"\"\"\n    if cache.get(f\"last_update_{callback_query.from_user.id}\") is None:\n        user_leagues = callback_query.data.split(\"#\")&#91;1:]\n        answer = await s.generate_results_answer(user_leagues)\n        cache.setex(f\"last_update_{callback_query.from_user.id}\", MINUTE, \"Updated\")\n        await bot.edit_message_text(\n            answer,\n            callback_query.from_user.id,\n            message_id=int(cache.get(f\"last_msg_{callback_query.from_user.id}\"))\n        )\n    # \u0438\u0433\u043d\u043e\u0440\u0438\u0440\u0443\u0435\u043c \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435, \u0435\u0441\u043b\u0438 \u043f\u0440\u043e\u0448\u043b\u043e \u043c\u0435\u043d\u044c\u0448\u0435 \u043c\u0438\u043d\u0443\u0442\u044b\n    await callback_query.answer(msg.cb_updated)\n\n\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><code>get_results<\/code>&nbsp;\u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u043b\u0438\u0433\u0438 \u0438 \u0444\u0438\u043a\u0441\u0438\u0440\u0443\u0435\u0442 id \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0434\u043b\u044f \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f. \u0415\u0441\u043b\u0438 \u0443 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043d\u0435\u0442 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u043d\u044b\u0445 \u043b\u0438\u0433 \u2014 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442&nbsp;<code>set_or_update_config<\/code>, \u0432 \u0434\u0440\u0443\u0433\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435\u0442 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u043e\u0442\u0432\u0435\u0442 \u0441 \u043c\u0430\u0442\u0447\u0430\u043c\u0438 \u0438 \u043a\u043d\u043e\u043f\u043a\u043e\u0439 \u00ab\u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c\u00bb.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/pythonru.com\/wp-content\/uploads\/2021\/02\/soobshenie-s-rezultatami-matchej-1.png\" alt=\"\u0424\u0443\u0442\u0431\u043e\u043b\u044c\u043d\u044b\u0439 \u0442\u0435\u043b\u0435\u0433\u0440\u0430\u043c \u0431\u043e\u0442 \u043d\u0430 Python (2\/4): \u0424\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0431\u043e\u0442\u0430\" class=\"wp-image-4695\"\/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">\u0424\u0443\u043d\u043a\u0446\u0438\u044f \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u043b\u043e\u0433\u0438\u043a\u0443 \u0442\u043e\u043b\u044c\u043a\u043e \u0435\u0441\u043b\u0438 \u043f\u0440\u043e\u0448\u043b\u043e \u0431\u043e\u043b\u044c\u0448\u0435 \u043c\u0438\u043d\u0443\u0442\u044b \u0441 \u043c\u043e\u043c\u0435\u043d\u0442\u0430 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0433\u043e \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043f\u043e\u0441\u043b\u0435 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u043e\u0442\u0432\u0435\u0442\u0430 \u0441 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430\u043c\u0438 \u043c\u044b \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0437\u0430\u043f\u0438\u0441\u044c \u0432 \u043a\u0435\u0448 \u0441\u043e \u0441\u0440\u043e\u043a\u043e\u043c \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f 1 \u043c\u0438\u043d\u0443\u0442\u0430.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0414\u043e\u043f\u0438\u0448\u0435\u043c \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># fonlinebot\/app\/dialogs.py\n#...\n\n    results: str = \"\u0412\u0441\u0435 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u0437\u0430 \u0441\u0435\u0433\u043e\u0434\u043d\u044f\\n{matches}\"\n    no_results: str = \"\u0421\u0435\u0433\u043e\u0434\u043d\u044f \u043d\u0435\u0442 \u043c\u0430\u0442\u0447\u0435\u0439\"\n    update_results: str = \"\u041e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b\"\n    cb_updated: str = f\"{emojize(':white_heavy_check_mark:')} \u0413\u043e\u0442\u043e\u0432\u043e\"\n\n#...\n\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u041a\u043d\u043e\u043f\u043a\u0443 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0438 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044e \u043e\u0442\u0432\u0435\u0442\u0430 \u0432 \u00abservice.py\u00bb.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># fonlinebot\/app\/service.py\nfrom config import BOT_LEAGUES, BOT_LEAGUE_FLAGS, MINUTE\n#...\n\ndef results_kb(leagues: list):\n    params = &#91;f\"#{lg}\" for lg in leagues]\n    kb = InlineKeyboardMarkup()\n    kb.add(InlineKeyboardButton(\n        msg.update_results,\n        callback_data=f\"update_results{''.join(params)}\"\n    ))\n    return kb\n\n\nasync def generate_results_answer(ids: list) -&gt; str:\n    \"\"\"\u0424\u0443\u043d\u043a\u0446\u0438\u044f \u0441\u043e\u0437\u0434a\u0435\u0442 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u0432\u044b\u0432\u043e\u0434\u0430 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432 \u043c\u0430\u0442\u0447\u0435\u0439\"\"\"\n    results = await get_last_results(ids)\n    if results:\n        text_results = results_to_text(results)\n        return msg.results.format(matches=text_results)\n    else:\n        return msg.no_results\n\n\ndef ids_to_key(ids: list) -&gt; str:\n    \"\"\"\u0421\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u0438\u0437\u0430\u0446\u0438\u044f \u043a\u043b\u044e\u0447\u0435\u0439 \u0434\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u043c\u0430\u0442\u0447\u0435\u0439\"\"\"\n    ids.sort()\n    return \",\".join(ids)\n\n\nasync def parse_matches(ids: list) -&gt; list:\n    \"\"\"\u0424\u0443\u043d\u043a\u0446\u0438\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u043c\u0430\u0442\u0447\u0435\u0439 \u043f\u043e API\"\"\"\n    # \u043b\u043e\u0433\u0438\u043a\u0443 \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u0432 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0447\u0430\u0441\u0442\u0438\n    return &#91;]\n\n\nasync def get_last_results(league_ids: list) -&gt; list:\n    lg_key = ids_to_key(league_ids)\n    last_results = cache.jget(lg_key)\n    if last_results is None:\n        last_results = await parse_matches(league_ids)\n        if last_results:\n            # \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043d\u043e\u0432\u044b\u0435 \u043c\u0430\u0442\u0447\u0438, \u0435\u0441\u043b\u0438 \u043e\u043d\u0438 \u0435\u0441\u0442\u044c\n            cache.jset(lg_key, last_results, MINUTE)\n    return last_results\n\n\ndef results_to_text(matches: list) -&gt; str:\n    \"\"\"\n    \u0424\u0443\u043d\u043a\u0446\u0438\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0441 \u043c\u0430\u0442\u0447\u0430\u043c\u0438\n    \"\"\"\n    # \u043b\u043e\u0433\u0438\u043a\u0443 \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u0432 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0447\u0430\u0441\u0442\u0438\n    ...\n\n#...\n\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0424\u0443\u043d\u043a\u0446\u0438\u044f&nbsp;<code>generate_results_answer<\/code>&nbsp;\u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u043c\u0430\u0442\u0447\u0438, \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u044b\u0432\u0430\u0435\u0442 \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 \u0442\u0435\u043a\u0441\u0442 \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0435\u0433\u043e. \u0415\u0441\u043b\u0438 \u043c\u0430\u0442\u0447\u0435\u0439 \u043d\u0435\u0442, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 \u0442\u0435\u043a\u0441\u0442.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0427\u0442\u043e \u0431\u044b \u0441\u044d\u043a\u043e\u043d\u043e\u043c\u0438\u0442\u044c \u0440\u0435\u0441\u0443\u0440\u0441\u044b \u043c\u044b \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u043c\u0430\u0442\u0447\u0435\u0439 \u0432 \u043a\u0435\u0448\u0435 \u0438 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0442\u043e\u043c \u043e\u0431\u0440\u0430\u0449\u0430\u0435\u043c\u0441\u044f \u043a API.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h--6\">\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u044b\u0445 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u041b\u044e\u0434\u0438 \u0431\u0443\u0434\u0443\u0442 \u043f\u0438\u0441\u0430\u0442\u044c \u0442\u0435\u043a\u0441\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u043d\u0435 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c. \u041e\u0431\u043d\u043e\u0432\u0438\u0442\u0435 \u043a\u043b\u0430\u0441\u0441\u00a0<code>Messages<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># fonlinebot\/app\/dialogs.py\n#...\n    unknown_text: str = \"\u041d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u043f\u043e\u043d\u044f\u0442\u043d\u043e, \u043d\u043e \u043e\u0447\u0435\u043d\u044c \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e.\\n\u041f\u043e\u043f\u0440\u043e\u0431\u0443\u0439 \u043a\u043e\u043c\u0430\u043d\u0434\u0443 \/help\"\n\n#...\n\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0418\u00a0<code>unknown_message<\/code>.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># fonlinebot\/app\/bot.py\n#...\n\n@dp.message_handler()\nasync def unknown_message(message: types.Message):\n    \"\"\"\u041e\u0442\u0432\u0435\u0442 \u043d\u0430 \u043b\u044e\u0431\u043e\u0435 \u043d\u0435\u043e\u0436\u0438\u0434\u0430\u0435\u043c\u043e\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435\"\"\"\n    await message.answer(msg.unknown_text, reply_markup=s.MAIN_KB)\n\n#...\n\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0423\u0431\u0435\u0434\u0438\u043c\u0441\u044f, \u0447\u0442\u043e \u0432\u0441\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/pythonru.com\/wp-content\/uploads\/2021\/02\/obrabotka-neizvestnyh-soobshenij.png\" alt=\"\u0424\u0443\u0442\u0431\u043e\u043b\u044c\u043d\u044b\u0439 \u0442\u0435\u043b\u0435\u0433\u0440\u0430\u043c \u0431\u043e\u0442 \u043d\u0430 Python (2\/4): \u0424\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0431\u043e\u0442\u0430\" class=\"wp-image-4689\"\/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">\u041e\u0442\u043b\u0438\u0447\u043d\u043e. \u041c\u044b \u043d\u0430\u043f\u0438\u0441\u0430\u043b\u0438 \u0431\u043e\u0442\u0430 \u0441 \u043a\u043b\u0430\u0432\u0438\u0430\u0442\u0443\u0440\u0430\u043c\u0438, \u043a\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0438 \u0431\u0430\u0437\u043e\u0439 \u0434\u0430\u043d\u043d\u044b\u0445. \u0422\u0435\u043f\u0435\u0440\u044c \u043f\u043e\u0440\u0430 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0442\u0435\u0441\u0442\u043e\u0432.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h--7\">\u041e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u0442\u0435\u0441\u0442\u043e\u0432<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u0414\u043e\u0431\u0430\u0432\u0438\u043c \u043a\u043b\u0430\u0441\u0441\u00a0<code>TestService<\/code>\u00a0\u0434\u043b\u044f \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0438\u00a0<code>get_league_ids<\/code>\u00a0\u0438\u00a0<code>get_last_results<\/code>.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># fonlinebot\/test.py\nfrom app import bot, service\n#...\n\n\nclass TestService(IsolatedAsyncioTestCase):\n    async def test_get_league_ids(self):\n        ids = await service.get_league_ids(\"1111\")\n        self.assertEqual(type(ids), list)\n\n    async def test_get_last_results(self):\n        results = await service.get_last_results(&#91;\"1\", \"2\", \"3\"])\n        self.assertEqual(type(results), list)\n#...\n\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u0421\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439 \u0441 \u043a\u043e\u0434\u043e\u043c \u0432 \u043d\u0430\u0447\u0430\u043b\u0435 \u0441\u0442\u0430\u0442\u044c\u0438. \u0423\u0434\u0430\u0447\u0438!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u0412\u043e \u0432\u0442\u043e\u0440\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u0441\u0435\u0440\u0438\u0438 \u0441\u0442\u0430\u0442\u0435\u0439 \u043f\u043e&nbsp;\u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044e \u0442\u0435\u043b\u0435\u0433\u0440\u0430\u043c \u0431\u043e\u0442\u0430 \u043d\u0430 python, \u043c\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u044c. \u0411\u043e\u0442 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u0438\u0432\u0435\u0442\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u043d\u043e\u0432\u044b\u0445 \u044e\u0437\u0435\u0440\u043e\u0432, \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0442\u044c \u0432\u044b\u0431\u0440\u0430\u0442\u044c [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"categories":[79],"tags":[],"class_list":["post-1122","page","type-page","status-publish","hentry","category-futbolnyj-telegram-bot-na-python"],"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.bearloga.space\/en\/wp-json\/wp\/v2\/pages\/1122","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.bearloga.space\/en\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.bearloga.space\/en\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.bearloga.space\/en\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.bearloga.space\/en\/wp-json\/wp\/v2\/comments?post=1122"}],"version-history":[{"count":0,"href":"https:\/\/www.bearloga.space\/en\/wp-json\/wp\/v2\/pages\/1122\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.bearloga.space\/en\/wp-json\/wp\/v2\/media?parent=1122"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.bearloga.space\/en\/wp-json\/wp\/v2\/categories?post=1122"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.bearloga.space\/en\/wp-json\/wp\/v2\/tags?post=1122"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}