### Install flyerapi Source: https://github.com/elicreator/flyerapi/blob/master/README.md Install the flyerapi library using pip. Requires Python 3.7+ and aiohttp. ```bash pip install flyerapi ``` -------------------------------- ### Full Subscription Example with Tasks (aiogram) Source: https://context7.com/elicreator/flyerapi/llms.txt This snippet demonstrates a complex scenario involving checking tasks, creating an inline keyboard with links and a 'Check' button, and performing parallel status checks using asyncio.gather. It's used to manage user access based on subscription and task completion. ```python import asyncio from typing import Optional from aiogram import types, exceptions, Bot from flyerapi import Flyer, APIError as FlyerAPIError bot = Bot("TELEGRAM_BOT_TOKEN") flyer = Flyer("FLYER_API_KEY") BUTTONS_ROW = 2 BUTTON_TEXTS = { 'start bot': '➕ Запустить бота', 'subscribe channel': '➕ Подписаться', 'give boost': '➕ Голосовать (3 раза)', 'follow link': '➕ Перейти', 'perform action': '➕ Выполнить действие', } TEXT = "Чтобы получить доступ, подпишитесь на ресурсы:" _incomplete_statuses = ('incomplete', 'abort') async def show_subscription_message( user_id: int, language_code: str, message_id: Optional[int] = None, ) -> bool: """Показывает клавиатуру с заданиями. Возвращает False, если есть незавершённые задания.""" try: tasks = await flyer.get_tasks(user_id=user_id, language_code=language_code, limit=5) except FlyerAPIError: return True if not tasks: return True tasks_incomplete = [t for t in tasks if t['status'] in _incomplete_statuses] if not tasks_incomplete: return True keyboard = {'inline_keyboard': [[]]} for task in tasks_incomplete: for index, link in enumerate(task['links']): btn_text = BUTTON_TEXTS.get(task['task'], task['task']) if len(keyboard['inline_keyboard'][-1]) == BUTTONS_ROW: keyboard['inline_keyboard'].append([]) keyboard['inline_keyboard'][-1].append({'text': btn_text, 'url': link}) keyboard['inline_keyboard'].append([{'text': '☑️ Проверить', 'callback_data': 'flyer_check'}]) if message_id is None: await bot.send_message(user_id, TEXT, parse_mode='HTML', reply_markup=keyboard) else: try: await bot.edit_message_text(user_id, message_id, TEXT, parse_mode='HTML', reply_markup=keyboard) except exceptions.MessageNotModified: pass return False async def verify_all_tasks(user_id: int) -> bool: """Параллельно проверяет все незавершённые задания. Возвращает True если все выполнены.""" try: tasks = await flyer.get_tasks(user_id=user_id) except FlyerAPIError: return True if not tasks: return True tasks_incomplete = [t for t in tasks if t['status'] in _incomplete_statuses] if not tasks_incomplete: return True results = await asyncio.gather( *[flyer.check_task(user_id=user_id, signature=t['signature']) for t in tasks_incomplete], return_exceptions=True, ) for i, (task, status) in enumerate(zip(tasks_incomplete, results)): if isinstance(status, str): tasks[i]['status'] = status return all(t['status'] not in _incomplete_statuses for t in tasks) # Обработчик кнопки «Проверить» async def on_check_callback(call: types.CallbackQuery): if not await verify_all_tasks(call.from_user.id): await show_subscription_message( user_id=call.from_user.id, language_code=call.from_user.language_code, message_id=call.message.message_id, ) await call.answer() return await call.message.delete() # Пользователь прошёл проверку — продолжаем # Обработчик входящего сообщения async def on_message(message: types.Message): if not await show_subscription_message( user_id=message.from_user.id, language_code=message.from_user.language_code, ): return # показали задания — ждём выполнения # Пользователь подписан — обрабатываем сообщение await message.answer("Привет! Вы прошли проверку подписки.") ``` -------------------------------- ### Get and check tasks Source: https://github.com/elicreator/flyerapi/blob/master/README.md Retrieve a list of tasks for a user and check the status of a specific task using its signature. The 'limit' parameter controls the number of tasks fetched. ```python # Получение заданий для пользователя tasks = await flyer.get_tasks(user_id=user_id, language_code=language_code, limit=5) # Получиение статуса задания signature = tasks[0]['signature'] # пример status = await flyer.check_task(user_id=user_id, signature=signature) ``` -------------------------------- ### Get User Tasks Source: https://context7.com/elicreator/flyerapi/llms.txt Retrieve a list of tasks a user needs to complete. Each task includes signature, status, task description, and links. Supports limiting the number of returned tasks. Handles API errors. ```python import asyncio from flyerapi import Flyer, APIError flyer = Flyer("ваш_api_ключ") async def main(): user_id = 123456789 try: tasks = await flyer.get_tasks( user_id=user_id, language_code="ru", limit=5, ) except APIError as e: print(f"Ошибка: {e}") return for task in tasks: print(f"Задание: {task['task']}, статус: {task['status']}") print(f"Ссылки: {task['links']}") print(f"Подпись: {task['signature']}") # Задание: subscribe channel, статус: incomplete # Ссылки: ['https://t.me/example_channel'] # Подпись: abc123xyz asyncio.run(main()) ``` -------------------------------- ### Get Bot Information Source: https://context7.com/elicreator/flyerapi/llms.txt Retrieve information about the bot associated with the current API key. This function is asynchronous and requires an asyncio event loop. ```python import asyncio from flyerapi import Flyer flyer = Flyer("ваш_api_ключ") async def main(): info = await flyer.get_me() print(info) # {'bot_id': 123456789, 'username': 'my_bot', ...} asyncio.run(main()) ``` -------------------------------- ### Get Completed Tasks from Flyer API Source: https://context7.com/elicreator/flyerapi/llms.txt Retrieve a dictionary of completed tasks for a given user ID. Returns None if data is unavailable or the server is unreachable. ```python import asyncio from flyerapi import Flyer, APIError flyer = Flyer("ваш_api_ключ") async def main(): user_id = 123456789 try: completed = await flyer.get_completed_tasks(user_id=user_id) if completed is None: print("Нет данных") return print(f"Завершённые задания: {completed}") except APIError as e: print(f"Ошибка API: {e}") asyncio.run(main()) ``` -------------------------------- ### Flyer Client Initialization Source: https://context7.com/elicreator/flyerapi/llms.txt Demonstrates how to create an instance of the Flyer client with an API key. Optional parameters like `debug` and `timeout` can be provided. ```APIDOC ## Flyer Client Initialization Creates an instance of the client with an API key. The `debug=True` parameter enables raw API responses to be printed to the console. Additional arguments `**request_kwargs` are passed directly to `aiohttp`. ```python from flyerapi import Flyer, APIError # Basic initialization flyer = Flyer("your_api_key") # With debug mode and timeout import aiohttp flyer = Flyer( "your_api_key", debug=True, timeout=aioiohttp.ClientTimeout(total=10), ) ``` ``` -------------------------------- ### Initialize Flyer API Client Source: https://context7.com/elicreator/flyerapi/llms.txt Create an instance of the Flyer client with your API key. Enable debug mode to see raw API responses. Additional request arguments can be passed directly to aiohttp. ```python from flyerapi import Flyer, APIError # Базовая инициализация flyer = Flyer("ваш_api_ключ") # С режимом отладки и таймаутом import aiohttp flyer = Flyer( "ваш_api_ключ", debug=True, timeout=aiohttp.ClientTimeout(total=10), ) ``` -------------------------------- ### get_me Source: https://context7.com/elicreator/flyerapi/llms.txt Retrieves information about the bot associated with the current API key. Returns a dictionary containing bot details. ```APIDOC ## `get_me` — Get Bot Information Returns a dictionary with information about the bot associated with the current API key. ```python import asyncio from flyerapi import Flyer flyer = Flyer("your_api_key") async def main(): info = await flyer.get_me() print(info) # {'bot_id': 123456789, 'username': 'my_bot', ...} asyncio.run(main()) ``` ``` -------------------------------- ### Flyer Webhook Handler with FastAPI Source: https://context7.com/elicreator/flyerapi/llms.txt Set up a webhook endpoint using FastAPI to receive and process events from the Flyer service. Handles 'test', 'sub_completed', and 'new_status' event types. ```python import uvicorn from fastapi import FastAPI, Request app = FastAPI() ANSWER = {'status': True} @app.post('/flyer_webhook') async def webhook_handler(request: Request): data = await request.json() # Тестовый ping от сервиса if data['type'] == 'test': return ANSWER # Пользователь завершил обязательную подписку elif data['type'] == 'sub_completed': user_id = data['data']['user_id'] # Разблокировать доступ пользователю, отправить приветствие и т.д. print(f"Пользователь {user_id} выполнил подписку") return ANSWER # Пользователь отписался от канала elif data['type'] == 'new_status' and data['data']['status'] == 'abort': user_id = data['data']['user_id'] # Уведомить пользователя или ограничить доступ print(f"Пользователь {user_id} отписался") return ANSWER return ANSWER if __name__ == '__main__': uvicorn.run(app, host='0.0.0.0', port=50000) ``` -------------------------------- ### get_tasks Source: https://context7.com/elicreator/flyerapi/llms.txt Retrieves a list of tasks that a user needs to complete. Each task includes `signature`, `status`, `task`, and `links`. The `limit` parameter can restrict the number of returned tasks. ```APIDOC ## `get_tasks` — Get User Tasks Returns a list of tasks (`List[dict]`) that the user must complete. Each task contains the fields `signature`, `status`, `task`, and `links`. The `limit` parameter restricts the number of returned tasks. ```python import asyncio from flyerapi import Flyer, APIError flyer = Flyer("your_api_key") async def main(): user_id = 123456789 try: tasks = await flyer.get_tasks( user_id=user_id, language_code="ru", limit=5, ) except APIError as e: print(f"Error: {e}") return for task in tasks: print(f"Task: {task['task']}, status: {task['status']}") print(f"Links: {task['links']}") print(f"Signature: {task['signature']}") # Task: subscribe channel, status: incomplete # Links: ['https://t.me/example_channel'] # Signature: abc123xyz asyncio.run(main()) ``` ``` -------------------------------- ### check Source: https://context7.com/elicreator/flyerapi/llms.txt Checks if a user has completed all mandatory subscription requirements. Returns `True` if subscribed or if the server is unavailable (fail-open), and `False` otherwise. Supports custom messages with buttons and caches results for 60 seconds. ```APIDOC ## `check` — Check User Subscription Checks if a user has completed all mandatory subscription requirements. Returns `True` if the user is subscribed (or the server is unavailable - fail-open), and `False` otherwise. Supports custom messages with buttons (`message`). Results are cached for 60 seconds. ```python from aiogram import types from flyerapi import Flyer, APIError flyer = Flyer("your_api_key") # Simple check in a message handler async def message_handler(message: types.Message): if not await flyer.check( message.from_user.id, language_code=message.from_user.language_code, ): return # user is not subscribed - stop processing await message.answer("Welcome!") # Check with a custom message (HTML + buttons) async def callback_handler(call: types.CallbackQuery): custom_message = { 'rows': 2, 'text': 'Subscribe to resources to continue, $name!', 'button_bot': '➕ Start Bot', 'button_channel': '➕ Subscribe', 'button_url': '➕ Go', 'button_boost': '➕ Vote', 'button_fp': '➕ Complete', } try: subscribed = await flyer.check( call.from_user.id, language_code=call.from_user.language_code, message=custom_message, ) except APIError as e: print(f"API Error: {e}") return if not subscribed: await call.answer("Please subscribe first!", show_alert=True) return await call.message.delete() ``` ``` -------------------------------- ### Check User Subscription Source: https://context7.com/elicreator/flyerapi/llms.txt Verify if a user has completed all required subscriptions. Returns True if subscribed or if the server is unavailable (fail-open). Supports custom messages with buttons and caches results for 60 seconds. ```python from aiogram import types from flyerapi import Flyer, APIError flyer = Flyer("ваш_api_ключ") # Простая проверка в обработчике сообщений async def message_handler(message: types.Message): if not await flyer.check( message.from_user.id, language_code=message.from_user.language_code, ): return # пользователь не подписан — прерываем обработку await message.answer("Добро пожаловать!") # Проверка с кастомным сообщением (HTML + кнопки) async def callback_handler(call: types.CallbackQuery): custom_message = { 'rows': 2, 'text': 'Подпишитесь на ресурсы, чтобы продолжить, $name!', 'button_bot': '➕ Запустить бота', 'button_channel': '➕ Подписаться', 'button_url': '➕ Перейти', 'button_boost': '➕ Голосовать', 'button_fp': '➕ Выполнить', } try: subscribed = await flyer.check( call.from_user.id, language_code=call.from_user.language_code, message=custom_message, ) except APIError as e: print(f"Ошибка API: {e}") return if not subscribed: await call.answer("Сначала подпишитесь!", show_alert=True) return await call.message.delete() ``` -------------------------------- ### Check user subscription with aiogram Source: https://github.com/elicreator/flyerapi/blob/master/README.md Integrate FlyerAPI's check function into aiogram message and callback handlers to verify user subscriptions. Ensure the Flyer instance is initialized with your API key. ```python from flyerapi import Flyer from aiogram import types flyer = Flyer(KEY) async def message_handler(message: types.Message): # Применяйте везде, где требуется проверка if not await flyer.check(message.from_user.id, language_code=message.from_user.language_code): return async def callback_handler(call: types.CallbackQuery): # Применяйте везде, где требуется проверка if not await flyer.check(call.from_user.id, language_code=call.from_user.language_code): return ``` -------------------------------- ### Webhook Handler Source: https://context7.com/elicreator/flyerapi/llms.txt Handles incoming events from the Flyer service. Supports event types like 'test', 'sub_completed', and 'new_status'. ```APIDOC ## Webhooks ### Description The Flyer service can send events to a specified endpoint. Supported types include: `test`, `sub_completed` (subscription completed), `new_status` (task status change, e.g., unsubscribe). ### Endpoint POST `/flyer_webhook` ### Request Body JSON payload containing event data. Expected fields depend on the `type`. ### Event Types - **test**: A test ping from the service. - **sub_completed**: Indicates a user has completed a required subscription. - **new_status**: Indicates a change in task status, such as an unsubscribe event. ### Response `{"status": True}` for successful handling. ### Example Implementation (FastAPI) ```python import uvicorn from fastapi import FastAPI, Request app = FastAPI() ANSWER = {'status': True} @app.post('/flyer_webhook') async def webhook_handler(request: Request): data = await request.json() if data['type'] == 'test': return ANSWER elif data['type'] == 'sub_completed': user_id = data['data']['user_id'] print(f"User {user_id} completed subscription") return ANSWER elif data['type'] == 'new_status' and data['data']['status'] == 'abort': user_id = data['data']['user_id'] print(f"User {user_id} unsubscribed") return ANSWER return ANSWER if __name__ == '__main__': uvicorn.run(app, host='0.0.0.0', port=50000) ``` ``` -------------------------------- ### get_completed_tasks Source: https://context7.com/elicreator/flyerapi/llms.txt Retrieves a dictionary containing information about the user's completed tasks. Returns None if the key is not set, the user is not in a private chat, or the server is unavailable. ```APIDOC ## get_completed_tasks ### Description Returns a dictionary with information about the user's completed tasks. Returns `None` if the key is not set, the user is not in a private chat, or the server is unavailable. ### Method Signature `async flyer.get_completed_tasks(user_id: int)` ### Parameters - **user_id** (int) - The ID of the user. ### Request Example ```python import asyncio from flyerapi import Flyer, APIError flyer = Flyer("your_api_key") async def main(): user_id = 123456789 try: completed = await flyer.get_completed_tasks(user_id=user_id) if completed is None: print("No data available") return print(f"Completed tasks: {completed}") except APIError as e: print(f"API Error: {e}") asyncio.run(main()) ``` ``` -------------------------------- ### check_task Source: https://context7.com/elicreator/flyerapi/llms.txt Checks the status of a specific task using its signature. Returns the task status (e.g., 'complete', 'incomplete', 'abort') or None if an error occurs. ```APIDOC ## check_task ### Description Checks the status of a specific task by its `signature`. Returns a string with the status (`"complete"`, `"incomplete"`, `"abort"`, etc.) or `None` in case of an error. ### Method Signature `async flyer.check_task(user_id: int, signature: str)` ### Parameters - **user_id** (int) - The ID of the user. - **signature** (str) - The unique signature of the task to check. ### Request Example ```python import asyncio from flyerapi import Flyer, APIError flyer = Flyer("your_api_key") async def main(): user_id = 123456789 try: tasks = await flyer.get_tasks(user_id=user_id, language_code="ru") if not tasks: print("All tasks are completed") return signature = tasks[0]['signature'] status = await flyer.check_task(user_id=user_id, signature=signature) print(f"Task status: {status}") # Task status: complete except APIError as e: print(f"API Error: {e}") asyncio.run(main()) ``` ``` -------------------------------- ### Use custom message for subscription check Source: https://github.com/elicreator/flyerapi/blob/master/README.md Customize the message and button texts used during the subscription check process. The 'message' parameter accepts a dictionary with predefined keys for text and button labels. ```python message = { 'rows': 2, 'text': 'Пользовательский текст для $name', # HTML 'button_bot': 'Запустить', 'button_channel': 'Подписаться', 'button_url': 'Перейти', 'button_boost': 'Голосовать', 'button_fp': 'Выполнить', } await flyer.check(user_id, language_code=language_code, message=message) ``` -------------------------------- ### Check Task Status with Flyer API Source: https://context7.com/elicreator/flyerapi/llms.txt Use this to check the status of a specific task using its signature. Ensure you have the user ID and task signature. ```python import asyncio from flyerapi import Flyer, APIError flyer = Flyer("ваш_api_ключ") async def main(): user_id = 123456789 try: tasks = await flyer.get_tasks(user_id=user_id, language_code="ru") if not tasks: print("Все задания выполнены") return # Проверяем первое незавершённое задание signature = tasks[0]['signature'] status = await flyer.check_task(user_id=user_id, signature=signature) print(f"Статус задания: {status}") # Статус задания: complete except APIError as e: print(f"Ошибка API: {e}") asyncio.run(main()) ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.