Metadata-Version: 2.4
Name: aiovkteams
Version: 0.3.3
Summary: Библиотека для VK Teams ботов в стиле aiogram 3.x
Author-email: Vladislav K <x-original@mail.ru>
Requires-Python: >=3.10
Description-Content-Type: text/markdown
Requires-Dist: aiohttp>=3.9
Provides-Extra: postgres
Requires-Dist: asyncpg>=0.29; extra == "postgres"

# aiovkteams

Асинхронная библиотека для создания ботов в **VK Workspace (VK Teams)** в стиле [aiogram 3.x](https://docs.aiogram.dev/).

## Установка

```bash
pip install aiovkteams
```

С поддержкой PostgreSQL-хранилища FSM:

```bash
pip install aiovkteams[postgres]
```

## Быстрый старт

```python
import asyncio
from aiovkteams.bot import Bot
from aiovkteams.dispatcher import Dispatcher
from aiovkteams.filters import Command
from aiovkteams.fsm.storage.memory import MemoryStorage
from aiovkteams.types import HandlerContext
from aiovkteams.fsm import FSMContext

bot = Bot(token="001.xxxxxxxxxx")
dp  = Dispatcher(bot, storage=MemoryStorage())

@dp.message(Command("start"))
async def cmd_start(ctx: HandlerContext, fsm: FSMContext):
    await ctx.reply("Привет!")

asyncio.run(dp.start_polling())
```

## Возможности

- **Polling** — long polling из коробки, автоматический реконнект
- **FSM** — конечный автомат состояний (MemoryStorage / PostgresStorage)
- **Роутеры** — разбивка хендлеров по модулям (`Router`)
- **Inline-клавиатуры** — кнопки с callback, ссылками, стилями (`primary`, `attention`)
- **Middleware** — обработка запросов до/после хендлеров
- **Фильтры** — `Command`, `F.data`, `StateFilter` и произвольные
- **Отправка файлов** — загрузка изображений с кэшированием по `fileId`

## Примеры

### Inline-клавиатура

```python
from aiovkteams.types import InlineKeyboard

kb = (
    InlineKeyboard()
    .button("Подтвердить", callback_data="confirm", style="primary")
    .row()
    .button("Отмена", callback_data="cancel", style="attention")
)

await ctx.reply("Подтвердите действие:", inline_keyboard=kb.build())
```

### Callback-хендлер

```python
from aiovkteams.filters import F

@dp.callback_query(F.data == "confirm")
async def on_confirm(ctx: HandlerContext, fsm: FSMContext):
    await ctx.answer_callback()
    await ctx.edit_text("Подтверждено!")
```

### FSM

```python
from aiovkteams.fsm import State, StatesGroup
from aiovkteams.filters import StateFilter

class Form(StatesGroup):
    WaitingName = State()

@dp.message(Command("form"))
async def cmd_form(ctx: HandlerContext, fsm: FSMContext):
    await fsm.set_state(Form.WaitingName)
    await ctx.reply("Введите имя:")

@dp.message(Form.WaitingName)
async def process_name(ctx: HandlerContext, fsm: FSMContext):
    name = ctx.event.text
    await fsm.clear()
    await ctx.reply(f"Привет, {name}!")
```

### Отправка изображения

```python
with open("photo.jpg", "rb") as f:
    result = await bot.upload_file(
        chat_id=ctx.chat_id,
        file=f.read(),
        filename="photo.jpg",
        caption="Подпись к фото",
    )
# result["fileId"] — можно сохранить для повторной отправки без загрузки
```

### Роутеры

```python
# handlers/catalog.py
from aiovkteams.router import Router
router = Router(name="catalog")

@router.message(Command("catalog"))
async def cmd_catalog(ctx: HandlerContext, fsm: FSMContext):
    ...

# main.py
dp.include_router(catalog.router)
```

## Changelog

### 0.3.3
- Исправлен `KeyError: 'userId'` в `User.from_dict` при обработке `ChatMemberEvent`
  (некоторые системные события VK Teams не содержат поле `userId`)

### 0.3.2
- Добавлено PostgreSQL-хранилище FSM (`aiovkteams.fsm.storage.postgres`)
- Поддержка `upload_voice` для голосовых сообщений

### 0.3.1
- Добавлены стили кнопок: `primary`, `attention`, `base`
- Поддержка кнопок-ссылок (`url=`)

### 0.3.0
- Первый публичный релиз
- Polling, FSM (MemoryStorage), Router, Middleware, Inline-клавиатуры
