Перейти к содержанию

Airtable x GREEN-API - разработка собственной интеграции#

Данная интеграция позволяет отправлять сообщения WhatsApp*, Telegram и MAX из базы Airtable и получать ответы обратно в базу через платформу GREEN-API. Разработана на базе Universal Integration Platform от GREEN-API и состоит из двух частей, которые находятся в одном репозитории: расширения Airtable (extension/) и сервиса-адаптера (src/).

Содержание#

Обзор#

Данная документация проведет вас через процесс развертывания собственной копии интеграции между GREEN-API и Airtable. Вы:

  1. Развернёте сервис-адаптер на публичном домене с HTTPS и базой данных MySQL.
  2. Зарегистрируете собственную OAuth-интеграцию Airtable с адресом перенаправления на вашем домене и укажете её client id и client secret в .env.
  3. Создадите собственное расширение (custom extension) в базе Airtable и подключите к нему проект extension/.
  4. Откроете расширение, в Settings → Advanced укажете адрес вашего адаптера, подтвердите личность и добавите инстансы.

Работа с интеграцией после установки - подтверждение личности, права участников по ролям, отправка и приём сообщений - описана в разделе Подключение интеграции. Ниже описано только то, что нужно для развёртывания и доработки своей копии.

Архитектура#

Airtable base ──(extension UI)──▶ adapter ──▶ GREEN-API ──▶ WhatsApp / Telegram / MAX
      ▲                              │
      └──(Airtable Web API, OAuth)───┘◀── webhooks (messages, statuses) ◀── GREEN-API

Расширение Airtable#

Расширение на Blocks SDK, которое:

  • Хранит настройки базы: сопоставление таблиц и полей, настройки отправки
  • Формирует сообщение для каждой строки и показывает предпросмотр
  • Передаёт пакет сообщений в адаптер и показывает результат по каждой строке
  • Хранит персональный ключ участника в локальном хранилище браузера

Сервис-адаптер#

Приложение NestJS, которое:

  • Хранит учётные данные инстансов GREEN-API. В базе Airtable секреты не хранятся
  • Подтверждает личность участников через Airtable OAuth, проверяет их роль в базе и выдаёт персональные ключи
  • Отправляет сообщения через GREEN-API и возвращает результат по каждой строке
  • Принимает вебхуки GREEN-API и записывает входящие и исходящие сообщения и статусы в базу через Airtable Web API

Установка#

Минимальные требования#

  • Node.js 24
  • База данных MySQL 8 (или MariaDB)
  • Публичный HTTPS-адрес для адаптера - на него приходят вебхуки GREEN-API и перенаправления OAuth
  • Аккаунт и инстанс(ы) GREEN-API
  • Платный тариф Airtable - собственные расширения и Marketplace доступны только на платных тарифах

Регистрация OAuth-интеграции в Airtable#

На странице airtable.com/create/oauth:

  1. Задайте название и зарегистрируйте интеграцию.

  2. Сгенерируйте client secret (Generate a client secret). Обмен токенов выполняет адаптер, то есть сервер, поэтому Airtable требует секрет. Скопируйте секрет в .env.

  3. Укажите OAuth redirect URL: <APP_URL>/api/v1/oauth/callback.

  4. Выберите scopes - ровно эти четыре:

    Scope Для чего используется
    user.email:read определение участника при подтверждении личности
    schema.bases:read чтение роли участника в базе, названий таблиц и полей для приёма сообщений
    data.records:read поиск контакта, с которым нужно связать входящее сообщение
    data.records:write запись строк сообщений и статусов

Адаптер всегда использует PKCE (этого требует Airtable). Client secret передаётся в заголовке HTTP Basic при запросах получения и обновления токена. Токены доступа действуют 60 минут, адаптер обновляет их сам. Refresh-токены действуют 60 дней и продлеваются при каждом использовании.

Настройка адаптера#

1. Клонируйте репозиторий:

```bash
git clone https://github.com/green-api/greenapi-integration-airtable.git
cd greenapi-integration-airtable
```
  1. Установите зависимости:

    npm ci
    
  2. Настройте переменные окружения:

    cp .env.example .env
    

    Заполните в .env следующие переменные:

    Переменная Значение
    DATABASE_URL строка подключения к MySQL, например mysql://user:pass@host:3306/adapter
    APP_URL публичный адрес адаптера, например https://your-adapter-domain.com. Из него строятся адрес перенаправления OAuth (/api/v1/oauth/callback) и адрес вебхуков (/api/v1/webhooks/green-api)
    PORT порт, по умолчанию 3000
    AIRTABLE_CLIENT_ID client id OAuth-интеграции Airtable (шаг выше)
    AIRTABLE_CLIENT_SECRET client secret той же интеграции. Обязательная переменная: без неё адаптер не запустится

    Все переменные проверяются при запуске адаптера.

  3. Примените миграции базы данных:

    npx prisma migrate deploy
    
  4. Соберите и запустите адаптер:

    # Сборка приложения
    npm run build
    
    # Запуск в production режиме
    npm run start:prod
    

Развертывание в Docker#

В корне репозитория есть Dockerfile и docker-compose.yml. Для запуска выполните:

docker compose up --build

Команда применяет миграции базы данных, а затем запускает адаптер.

Запуск и выпуск расширения#

Каталог extension/ - стандартный проект Blocks SDK, уже инициализированный. Создайте расширение в базе и запустите его в режиме разработки по инструкции Установка расширения в базу. При разработке учитывайте:

  • файл extension/.block/remote.json у каждого разработчика свой и не попадает в git;
  • скрипты npm start, npm run release и npm run submit в extension/package.json запускают Blocks CLI фиксированной версии (@airtable/blocks-cli@3.0.3) через npx, поэтому npm start можно использовать вместо block run;
  • dev-сервер пересобирает панель при каждом изменении кода;
  • после запуска укажите в расширении адрес вашего адаптера: Settings → Advanced. Адрес по умолчанию задан константой DEFAULT_ADAPTER_URL в extension/frontend/defaults.ts.

Для публикации:

npm run release    # block release - выпускает сборку в расширение базы
npm run submit     # block submit - отправка на проверку в Marketplace

Собственное расширение работает в одной базе. Чтобы использовать его в другой базе, добавьте её как ещё один remote (block add-remote) и выполните выпуск снова.

Как работает интеграция#

Отправка сообщений#

  1. Расширение формирует сообщение для каждой строки и передаёт пакет в адаптер (POST jobs). Типы сообщений и ограничения по мессенджерам описаны в разделе Типы сообщений.
  2. Адаптер не делает пауз между сообщениями - интервал задаёт очередь GREEN-API, параметр delaySendMessagesMilliseconds в настройках инстанса.
  3. Файлы отправляются загрузкой: когда адаптер доходит до строки, он скачивает вложение и загружает его в GREEN-API методом sendFileByUpload.

Отправку без панели расширения - из автоматизаций Airtable и внешних сервисов - выполняет маршрут POST send с ключом для автоматизаций. Формат запроса и ответа описан в разделе Отправка из автоматизаций Airtable и других сервисов.

Приём сообщений#

  1. Для записи в базу адаптеру нужен доступ Airtable OAuth с data.records:read/write и schema.bases:read. Первое подтверждение личности владельца уже включает этот доступ.
  2. При включении приёма для инстанса адаптер вызывает setSettings с webhookUrl = <APP_URL>/api/v1/webhooks/green-api и случайным webhookUrlToken. При выключении приёма адрес вебхуков очищается.
  3. Адаптер записывает каждый вебхук в Airtable синхронно и отвечает GREEN-API кодом 200. Если запись не удалась (ограничение Airtable на число запросов, истёкший токен, удалённое поле, сбой Airtable), адаптер отвечает 503, и GREEN-API повторяет доставку того же вебхука.
  4. Повторно доставленное сообщение, которое уже записано, распознаётся по idMessage и не дублируется.

Что видит владелец базы при настройке приёма и как обновляются статусы, описано в разделе Приём входящих сообщений.

Номера телефонов и ID чатов#

Как расширение распознаёт номера телефонов, ID чатов и ID групп, описано в разделе Номера телефонов и ID чатов. При отправке номер телефона приводится к виду <цифры>@c.us: в WhatsApp - любое значение, кроме ID группы (…@g.us), в Telegram и MAX - только значение, записанное как номер телефона.

Методы GREEN-API#

Что делает каждый инструмент, описано в разделе Дополнительные инструменты. Ниже указано, какие методы GREEN-API он вызывает.

Где в расширении Метод GREEN-API
Tools → Check numbers checkWhatsapp / checkAccount
Tools → Chat history checkAccount, getChatHistory. Для Telegram и MAX номер телефона сначала преобразуется в ID чата, потому что их журналы ведутся по ID чата
Tools → Import history lastIncomingMessages, lastOutgoingMessages
Tools → Import contacts getContacts
Instances → Link phone qr
Вкладка Send, очередь сообщений showMessagesQueue, clearMessagesQueue

Ссылки ведут на описание методов для WhatsApp.

API адаптера#

Все маршруты находятся под /api/v1. Каждый маршрут, кроме oauth/* и webhooks/*, требует заголовок Authorization: Bearer pk_… (персональный ключ). Ограничения: 300 запросов в минуту с одного IP; для oauth/identity - 10 в минуту.

Метод Маршрут Кто Назначение
POST oauth/identity любой начать подтверждение личности для базы → адрес авторизации
POST oauth/claim любой обменять завершённую авторизацию на персональный ключ
GET oauth/callback Airtable адрес перенаправления OAuth
POST oauth/base владелец (повторно) дать адаптеру доступ Airtable к базе
GET bases/me участник данные базы: подключение Airtable, настройки приёма, инстансы, текущий пользователь
PUT / DELETE bases/inbound владелец задать / удалить настройки приёма
DELETE bases/airtable владелец отключить доступ Airtable к базе
GET instances участник инстансы с текущим состоянием и номером
POST instances владелец добавить инстанс (idInstance, apiTokenInstance, apiUrl, name?)
PATCH instances/:id/receive владелец включить / выключить приём
DELETE instances/:id владелец удалить инстанс (сначала очищает его вебхук)
GET users/me, users участник / владелец текущий пользователь; все, кто подтвердил личность
PUT users/:id/instances владелец какие инстансы доступны редактору
POST users/:id/revoke, DELETE users/:id владелец отозвать ключ / удалить пользователя
POST jobs участник отправить пакет (idInstance, items[], writeBack?)
GET jobs, jobs/:id участник последние задания; одно задание с результатами по строкам
POST jobs/:id/cancel участник остановить выполняемое задание
GET / POST automation-keys владелец список / создание ключей для автоматизаций (сам ключ возвращается один раз)
DELETE automation-keys/:id владелец отозвать ключ
POST instances/:id/check участник проверить номера в мессенджере инстанса
POST instances/:id/history, instances/:id/chat-history участник загрузить журнал / один чат в таблицу сообщений
GET instances/:id/queue, POST instances/:id/queue/clear участник размер очереди GREEN-API; очистка очереди
GET instances/:id/qr участник QR-код для привязки
GET instances/:id/contacts участник контакты мессенджера
POST send ключ для автоматизаций отправить одно сообщение и дождаться результата (формат)
POST webhooks/green-api GREEN-API приём вебхуков (Bearer webhookUrlToken)

Какие данные хранит адаптер#

Содержимое сообщений не хранится. В базе данных адаптера находятся:

  • ID базы Airtable, её настройки приёма и OAuth-токены Airtable для базы;
  • участники, подтвердившие личность: ID пользователя Airtable, email, имя, роль, хеш персонального ключа, а также инстансы, доступные редакторам;
  • инстансы: idInstance, apiTokenInstance, apiUrl, мессенджер, состояние, настройки вебхуков;
  • ключи для автоматизаций: название, ограничение по инстансу, хеш ключа, время последнего использования;
  • задания на отправку: по одной строке на пакет и на каждого получателя со статусом, ID сообщения GREEN-API и ошибкой. Содержимое сообщения хранится, только пока строка стоит в очереди, и удаляется сразу после отправки или ошибки.

Входящие вебхуки сразу записываются в Airtable и не хранятся. Буфером для повторов служит очередь GREEN-API.

Логи адаптера

Библиотека greenapi-integration записывает тела запросов и вебхуков в лог на уровне info. Поэтому текст сообщений и номера телефонов попадают в stdout адаптера, если вывод логов не фильтруется.

Разработка и тесты#

npm test                         # unit-тесты адаптера (jest)
cd extension && npm test         # unit-тесты расширения
  • Адаптер: NestJS 11, Prisma 7 (prisma/schema.prisma), все константы - в src/defaults.ts, коды ошибок - в src/errors.ts.
  • Расширение: React 16 и Blocks SDK 1.19. Настройки хранятся в globalConfig под ключом greenapi (extension/frontend/config), формирование сообщений - в extension/frontend/send/compose.ts, стили - в extension/frontend/style.css.

Лицензия#

Лицензировано в соответствии с MIT