### 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.