Сценарий 3 — AI Подбор матчей | Make.com
⚡ Make.com · Matchlane

Сценарий 3
AI Подбор матчей

Пошаговая сборка сценария: от триггера по расписанию до уведомления в Telegram. Все ловушки учтены.

Схема потока данных

1Scheduler
2Search Airtable
3Iterator
4Get candidates
5Claude API
6Parse JSON
7Check Б free
8Create match
9Update A + Б
10Sleep 3s
11Telegram ×2
МОД 1 Scheduler — запуск по расписанию
Scheduled trigger
Tools → Scheduler
TRIGGER
Run scenarioEvery day
At time10:00
TimezoneEurope/Moscow (или ваш часовой пояс)
ℹ️ Scheduler не передаёт данных в следующий модуль — он просто запускает сценарий. Первый «реальный» модуль — Search Airtable.
МОД 2 Search Airtable — найти компании для матчинга
????️
Search Records
Airtable → Search Records
FILTER
BaseВаша база Matchlane
TableКомпании
Formula (Filter by formula)
AND( FIND("????", {Статус активности}), {Баланс мэтчей} > 0, IS_BEFORE({Дата следующего мэтча}, TODAY()), {ID активного матча} = "" )
Max records100
⚠️ Про фильтр по дате: IS_BEFORE включает и сегодняшнюю дату если писать IS_BEFORE({Дата следующего мэтча}, DATEADD(TODAY(), 1, 'days')). Или использовать <= TODAY().
⚠️ Linked record = пустое: В Airtable linked record возвращает [] а не "". Поэтому для проверки пустого поля через Formula используйте COUNT({ID активного матча}) = 0 вместо = "".
???? Альтернатива: Если фильтр через Formula не работает стабильно — уберите его и добавьте модуль Filter после Search, с условиями через Make-интерфейс (Contains для статуса, Greater than для баланса, и т.д.).
МОД 3 Iterator — обработать каждую компанию по очереди
????
Iterator
Flow Control → Iterator
LOOP
Array{{2.records}} — массив из Search Records
???? Iterator разворачивает массив. Каждый следующий модуль получает одну запись за раз. Переменные будут {{3.value.fields.*}}
МОД 4 Get candidates — собрать список кандидатов
????️
Search Records — кандидаты
Airtable → Search Records
ВАЖНО
TableКомпании
Formula
AND( FIND("????", {Статус активности}), {Баланс мэтчей} > 0, COUNT({ID активного матча}) = 0, RECORD_ID() != "{{3.value.id}}" )
Max records50
???? Стоп-лист! Нужно исключить компании из поля "Уже предложено с". Это linked record-массив. В Formula Airtable нет простого способа проверить "входит ли recXXX в массив linked records". Решение: фильтровать в Make через модуль Array Aggregator + Filter после получения кандидатов (см. Примечание ниже).
???? Как отработать стоп-лист в Make:
1. Получите стоп-лист компании А: {{3.value.fields["Уже предложено с"][]}} — это массив ID
2. После Search кандидатов добавьте Filter: поле {{4.records[].id}} Not in array {{3.value.fields["Уже предложено с"][]}}
3. Или используйте Tools → Array Aggregator для сборки ID кандидатов, потом фильтруй
МОД 5 Claude API — AI подбор партнёра
????
HTTP Request → Claude API
HTTP → Make an API Key Auth Request
API
URLhttps://api.anthropic.com/v1/messages
MethodPOST
Headers
x-api-key: YOUR_CLAUDE_API_KEY anthropic-version: 2023-06-01 content-type: application/json
Body typeRaw (JSON)
Body JSON:
REQUEST BODY { "model": "claude-opus-4-5", "max_tokens": 1000, "system": "Ты — система AI-матчинга B2B партнёров. Анализируй профили и выбирай наилучшего партнёра. Отвечай ТОЛЬКО валидным JSON без markdown и пояснений.", "messages": [ { "role": "user", "content": "{{promptText}}" } ] }
⚠️ Переменную {{promptText}} собери отдельно в модуле Tools → Set Variable перед этим шагом — чтобы не захламлять HTTP-модуль.
Промпт (собирается в Set Variable):
КОМПАНИЯ А (ищет партнёра): {{3.value.fields["Профиль для AI"]}} КАНДИДАТЫ НА ПАРТНЁРСТВО: {{candidatesText}} ЗАДАЧА: Выбери одного лучшего партнёра для Компании А из списка кандидатов. Учитывай: пересечение аудиторий, дополняемость продуктов, потенциал коллабораций. Ответь ТОЛЬКО в формате JSON (без markdown, без пояснений): { "partner_id": "recXXXXXXXXXXXXXX", "score": 87, "match_type": "Сильный", "analysis": "2-3 предложения почему это хороший матч" } match_type должен быть одним из: Базовый / Сильный / Стратегический score — число от 0 до 100
???? candidatesText — собери через Array Aggregator: для каждого кандидата склеиваем строку ID: {{record.id}} | {{record.fields["Профиль для AI"]}}, разделитель \n---\n
МОД 6 Parse JSON — разобрать ответ Claude
????
Tools → Set Variable (с парсингом)
JSON parse + fallback
PARSE
???? Claude может вернуть не чистый JSON! Например, обернуть в ```json ... ```. Нужен парсинг с очисткой.
Модуль: Tools → Parse JSON
JSON string
// Сначала достань текст из ответа Claude: {{5.data.content[1].text}} // Если Claude обернул в ```json ... ``` — используй: {{replace(replace(5.data.content[1].text, "```json", ""), "```", "")}}
⚠️ После Parse JSON поля доступны как {{6.partner_id}}, {{6.score}}, {{6.match_type}}, {{6.analysis}}
Fallback — Router + Error handler:
// Добавь Router после Parse JSON: Ветка 1: partner_id существует → продолжаем Ветка 2: partner_id пустой → логируем ошибку, пропускаем компанию
МОД 7 Get Record Б — проверить что у партнёра нет матча
????️
Get a Record → Компания Б
Airtable → Get a Record
ПРОВЕРКА
TableКомпании
Record ID{{6.partner_id}}
Filter после Get Record:
{{7.fields["ID активного матча"][]}} Is empty
???? Это защита от двойного матча у Компании Б. Если у неё уже есть матч — фильтр остановит ветку и мы не создадим второй.
МОД 8 Create Record — создать матч
????️
Create a Record → Матчи
Airtable → Create a Record
CREATE
TableМатчи
Компания А[{{3.value.id}}] — массив с одним ID
Компания Б[{{6.partner_id}}]
Статус мэтча АОжидает ответ от Б
Статус мэтча БОжидает ответ от А
Оценка совместимости{{6.score}}
Тип мэтча{{6.match_type}}
Анализ совместимости{{6.analysis}}
Дата предложения{{addDays(now, 7)}} — дедлайн 7 дней
???? Linked record в Airtable через Make передаётся как массив строк: ["recXXXXXX"]. Если передать просто строку — получишь ошибку.
МОД 9 Update Records — обновить обе компании
????️
Update Record → Компания А
Airtable → Update a Record
UPDATE A
Record ID{{3.value.id}}
ID активного матча[{{8.id}}] — ID созданной записи Матча
Статус мэтчаОжидает ответ
Баланс мэтчей{{3.value.fields["Баланс мэтчей"] - 1}}
Уже предложено сдобавить [{{6.partner_id}}] к существующим
⚠️ Уже предложено с — linked record, нужно добавить к массиву, а не перезаписать. В Make используй метод "Link" или передавай полный массив: объедини текущий {{3.value.fields["Уже предложено с"][]}} + новый ID.
????️
Update Record → Компания Б
Airtable → Update a Record
UPDATE Б
Record ID{{6.partner_id}}
ID активного матча[{{8.id}}]
Статус мэтчаОжидает ответ
Уже предложено сдобавить [{{3.value.id}}]
МОД 10 Sleep 3s — дать Airtable обновиться
????
Sleep
Flow Control → Sleep
ВАЖНО
Delay3 секунды
⚠️ Airtable не гарантирует мгновенную запись. Без Sleep Telegram-уведомление может уйти до того, как данные матча появятся в AirTable — и ЛК покажет пустой экран.
МОД 11 Telegram — уведомить обе компании
✈️
Send Message → Компания А
Telegram Bot → Send a Text Message or a Reply
NOTIFY A
ConnectionВаш бот
Chat ID{{3.value.fields["Телеграм chat_id"]}}
Text
???? Новое предложение о партнёрстве! Мы подобрали для вас партнёра. Откройте личный кабинет чтобы посмотреть детали.
Parse ModeHTML
Inline keyboard
Button textОткрыть личный кабинет
TypeWeb App
URLhttps://partnemix.com/tg-lk
✈️
Send Message → Компания Б
Telegram Bot → Send a Text Message or a Reply
NOTIFY Б
Chat ID{{7.fields["Телеграм chat_id"]}}
TextТо же сообщение
Inline keyboardТа же кнопка с WebApp
???? Данные Компании Б берём из модуля 7 (Get Record), не из Parse JSON — там есть chat_id.

???? Все подводные камни в одном месте
01
Linked record = массив
Всегда писать {{поле[]}} для linked records. Передавать как ["recXXX"] при записи.
02
Статусы с эмодзи
В фильтрах Make использовать Contains вместо Equal to — эмодзи могут ломать точное сравнение.
03
Sleep после Update
3 секунды Sleep обязательны перед Get Record того же поля. Airtable не успевает.
04
Claude ≠ чистый JSON
Всегда чистить ответ от ```json ... ```. Добавить Router с fallback-веткой если JSON не распарсился.
05
Двойной матч у Б
Проверять GET + Filter перед созданием матча что у Компании Б поле "ID активного матча" пустое.
06
Content-Type обязателен
В HTTP-запросе к Claude API всегда указывать content-type: application/json.
07
Стоп-лист в Formula
В Airtable нельзя напрямую фильтровать "не входит в linked record array" — фильтруй в Make через Filter модуль.
08
candidatesText для Claude
Собирай список кандидатов через Array Aggregator с полем "Профиль для AI". Без этого Claude не знает о ком выбирать.

???? Ожидаемый ответ Claude
CLAUDE RESPONSE { "partner_id": "recABCDEF12345678", "score": 87, "match_type": "Сильный", "analysis": "Обе компании работают с малым бизнесом в сфере услуг. Skybase предлагает CRM, а LeadFlow — лидогенерацию, что создаёт прямую синергию: общие клиенты получают полный цикл продаж. Высокий потенциал для cross-promotion." }
Made on
Tilda