Я хотел использовать Claude прямо в мессенджере MAX — без браузера, без переключения контекста. Готового решения не было. Нашёл на GitHub китайский проект cc-connect — Go-фреймворк с plugin-архитектурой для подключения AI-агентов к мессенджерам. Telegram, Feishu, Discord там были. MAX — нет.

Написал адаптер, открыл PR. Приняли. Теперь поддержка MAX — часть основного репозитория.

Что такое cc-connect

cc-connect — Go-фреймворк с чёткой трёхслойной архитектурой:

core/        — ядро: интерфейсы, engine, роутинг
platform/*/  — адаптеры мессенджеров (Telegram, Feishu, Discord, MAX...)
agent/*/     — адаптеры AI-агентов (Claude, GPT, DeepSeek...)

Главное правило: core/ не импортирует platform/ и agent/. Engine работает через интерфейсы и capability checks — никаких if platform == "telegram" в ядре.

Чтобы добавить новый мессенджер — создаёшь пакет в platform/, реализуешь интерфейс, регистрируешь через init() с build tag. Больше ничего не трогаешь.

MAX API: сюрпризы

Перед тем как писать адаптер, изучил MAX Bot API. Несколько неочевидных моментов:

Авторизация без Bearer. Большинство API ожидают Authorization: Bearer <token>. MAX принимает токен напрямую: Authorization: <token>. Без Bearer. Потерял на этом час.

Пагинация участников канала. Endpoint /chats/{id}/members?user_ids= фильтрацию не поддерживает — возвращает пустой список даже если пользователь есть в канале. Единственный способ проверить подписку — перебирать участников постранично через marker.

Вложения через share. Когда пользователь отправляет ссылку в чат, MAX автоматически прикрепляет HTML-превью страницы как вложение типа share. Нужно фильтровать, иначе агент будет обрабатывать каждую ссылку как загруженный файл.

Структура адаптера

Интерфейс core.Platform требует реализовать три метода:

type Platform interface {
    Name() string
    Start(ctx context.Context, handler MessageHandler) error
    Send(ctx context.Context, msg OutgoingMessage) error
    Capabilities() PlatformCapabilities

Capabilities() — ключевая часть. Engine принимает решения на основе того, что умеет платформа:

func (p *MAX) Capabilities() core.PlatformCapabilities {
    return core.PlatformCapabilities{
        SupportsVoice:      true,
        SupportsFiles:      true,
        SupportsInlineKeys: true,
        MaxMessageLen:      4096,
    }
}

Если агент поддерживает стриминг и платформа позволяет редактировать сообщения — engine стримит ответ. MAX это поддерживает, поэтому ответы Claude приходят по мере генерации, а не одним куском в конце.

Регистрация через init() с build tag:

//go:build !no_max

package max

func init() {
    core.RegisterPlatform("max", New)
}

Выборочная компиляция: go build -tags no_max ./... — и в бинарнике нет ни строчки MAX-кода.

## PR и что меня удивило

Открыл PR с адаптером. Ожидал стандартное code review с правками по стилю.

Мейнтейнеры попросили одну вещь: покрыть edge cases в обработке вложений — как раз тот самый share-тип, который я обнаружил при тестировании. Поправил, PR приняли.

Занятно работать с командой где никто не говорит по-русски, ты не говоришь по-китайски, и весь диалог в комментариях к PR на английском об интеграции российского мессенджера.

Итог

Сейчас через этот адаптер у меня работает личный ассистент на базе Claude в MAX. Отвечает на вопросы, запускает команды, работает с файлами, генерирует изображения, делает скриншоты. Всё прямо в чате мессенджера — никаких браузерных вкладок.

Если пользуетесь MAX и хотите подключить AI-агента — адаптер уже в основном репозитории cc-connect.

Комментарии (0)