VK Lead Forms → n8n → Google Sheets: заявки с UTM без дублей ¶
Обновлено: 2026-05-30
Импортируйте workflow, замените credentials и прогоните тестовый payload до включения production.
Проблема: лиды из VK Lead Forms часто приходят повторно, содержат телефон в разных форматах и теряют рекламные метки при ручной выгрузке. Если каждый lead append-ить в Google Sheets, менеджеры быстро получают дубли и грязную таблицу.
Решение: делаем контролируемую интеграцию VK Lead Forms и Google Sheets через n8n: используем `lead_id` и нормализованный телефон как ключи, сохраняем UTM в отдельные колонки, обновляем существующую строку и добавляем новые заявки только при настоящем новом лиде.
Проблема: почему VK Lead Forms создают дубли в Google Sheets ¶
В рекламной воронке VK Lead Ads Google Sheets часто используется как быстрый операционный буфер: маркетолог смотрит заявки, менеджер отмечает статус, руководитель выгружает отчёт. Но append каждой заявки превращает таблицу в хаос: повторный lead, одинаковый телефон, разные UTM и ручные правки создают несколько строк на одного клиента.
Эта страница решает конкретную задачу: настроить передачу данных из формы VK в Google Sheets через n8n так, чтобы строка обновлялась по `lead_id` или телефону, а не плодила дубли. При этом UTM, форма, кампания и статус обработки остаются отдельными колонками.
Архитектура workflow VK Lead Forms → n8n → Sheets ¶
| Нода | Роль | Что проверить |
|---|---|---|
| VK lead event | передаёт lead_id и поля формы | секрет, group_id, form_id, lead_id |
| Normalize lead | чистит телефон, имя, UTM | +7, 8, пробелы, lowercase email |
| Find row in Sheets | ищет строку по lead_id/phone | колонки lead_id и phone_normalized |
| Update or append row | обновляет или добавляет заявку | статус, updated_at, update_count |
| Notify manager | отправляет уведомление при новом лиде | без дублей и без персональных данных в публичный чат |
| Error route | пишет ошибку в DLQ/alert | 429, Google API, неверные поля формы |
Для новых версий Google Sheets node можно использовать встроенную операцию Append or Update. Ручная схема Find → IF → Update/Append полезна, когда нужно вести `update_count`, разные правила для новых и повторных лидов или отдельный alert только для новых заявок.
Контракт входных данных VK lead event ¶
{
"lead_id": "vk-lead-77821",
"group_id": "club123456",
"form_id": "consultation-main",
"created_at": "2026-05-30T10:00:00+03:00",
"name": "Олег",
"phone": "8 (916) 555-44-33",
"email": "oleg@example.ru",
"utm_source": "vk",
"utm_medium": "cpc",
"utm_campaign": "n8n_leads",
"utm_content": "leadform_banner",
"ad_id": "ad-987",
"campaign_id": "camp-321"
}
Если VK отдаёт только `lead_id`, а полные поля нужно забирать отдельным API-запросом, оставьте этот же контракт внутри n8n после enrichment-ноды. Для Google Sheets важно, чтобы на выходе был стабильный `lead_id` и `phone_normalized`.
Code Node: нормализация телефона, UTM и ключа строки ¶
const src = $json.body ?? $json;
const leadId = String(src.lead_id ?? src.id ?? '').trim();
if (!leadId) throw new Error('Missing VK lead_id');
const rawPhone = String(src.phone ?? src.Phone ?? '').trim();
let digits = rawPhone.replace(/\D/g, '');
if (digits.length === 11 && digits.startsWith('8')) digits = `7${digits.slice(1)}`;
if (digits.length === 10) digits = `7${digits}`;
if (!/^7\d{10}$/.test(digits)) throw new Error(`Invalid VK lead phone: ${rawPhone}`);
const email = String(src.email ?? '').trim().toLowerCase();
const now = new Date().toISOString();
return [{
json: {
row_key: `vk:${leadId}`,
dedupe_phone_key: `phone:+${digits}`,
lead_id: leadId,
phone_raw: rawPhone,
phone_normalized: `+${digits}`,
name: String(src.name ?? src.first_name ?? 'Новый лид VK').trim(),
email,
group_id: String(src.group_id ?? ''),
form_id: String(src.form_id ?? ''),
campaign_id: String(src.campaign_id ?? ''),
ad_id: String(src.ad_id ?? ''),
utm_source: src.utm_source ?? 'vk',
utm_medium: src.utm_medium ?? '',
utm_campaign: src.utm_campaign ?? '',
utm_content: src.utm_content ?? '',
first_seen_at: src.created_at ?? now,
updated_at: now,
status: 'new'
}
}];
Какие колонки создать в Google Sheets
Минимум: lead_id, row_key, phone_normalized, name, email, group_id, form_id, campaign_id, ad_id, utm_source, utm_medium, utm_campaign, utm_content, status, first_seen_at, updated_at, update_count.
Готовый workflow JSON: скачать и импортировать ¶
Скачать готовый workflow JSON Скачать тестовый payload
{
"name": "Nodbot - VK Lead Forms to Google Sheets with UTM dedupe",
"nodes": [
{
"name": "VK Lead Webhook",
"type": "n8n-nodes-base.webhook",
"purpose": "Принять lead_id и поля формы"
},
{
"name": "Normalize VK lead",
"type": "n8n-nodes-base.code",
"purpose": "Нормализовать телефон, UTM и row_key"
},
{
"name": "Find row in Google Sheets",
"type": "n8n-nodes-base.httpRequest",
"purpose": "Найти строку по lead_id или phone_normalized"
},
{
"name": "Update or append row",
"type": "n8n-nodes-base.httpRequest",
"purpose": "Обновить существующую строку или добавить новую"
},
{
"name": "Notify manager",
"type": "n8n-nodes-base.telegram",
"purpose": "Сообщить о новой заявке без дублей"
},
{
"name": "Respond",
"type": "n8n-nodes-base.respondToWebhook",
"purpose": "Вернуть VK безопасный 200"
}
],
"connections": "VK Lead Webhook → Normalize VK lead → Find row in Google Sheets → Update or append row → Notify manager → Respond"
}
Пошаговая настройка VK webhook, n8n и Google Sheets ¶
- Создайте лист Google Sheets с колонками lead_id, phone_normalized, UTM и status.
- Настройте VK Lead Forms webhook или API-забор lead_id в n8n.
- Импортируйте workflow и замените Google credential, spreadsheetId и sheet name.
- Выберите правило upsert: lead_id как основной ключ, телефон как дополнительная проверка дублей.
- Добавьте alert/DLQ для ошибок Google API и отсутствующих обязательных полей.
Тесты перед production и проверка дублей ¶
curl -X POST "https://YOUR-N8N-DOMAIN/webhook/vk-lead-form-to-sheets" \
-H "Content-Type: application/json" \
--data @vk-lead-form-to-sheets-payload.json
- Отправьте один и тот же lead_id дважды: строка должна обновиться, а не добавиться.
- Отправьте тот же телефон с другим форматом `8 916...` и проверьте нормализацию.
- Проверьте заявку без email и с кириллицей в UTM.
- Удалите колонку в тестовом листе и убедитесь, что ошибка попадает в alert.
- Проверьте, что новый лид отправляет уведомление менеджеру только один раз.
Production-риски VK Lead Ads и Google Sheets ¶
- Append вместо upsert. Таблица быстро заполняется дублями и теряет управляемость.
- UTM лежат в комментарии. Маркетинг не сможет фильтровать заявки по кампании и объявлению.
- Поиск только по телефону. Один клиент с несколькими заявками может перезаписать нужные данные без lead_id.
- Секрет webhook не проверяется. В таблицу можно отправить мусорные заявки.
- Нет DLQ. Ошибка Google API теряет лид без следа.
Полезные ссылки и смежные workflow ¶
См. также Google Sheets upsert по телефону, Tilda → amoCRM, retry/DLQ для HTTP Request и Google Sheets integrations. Официальные документы: VK Ads leads API, n8n Google Sheets node и Google Sheets API.
Критерии готовности ¶
- Повторный lead_id не создаёт вторую строку.
- Телефон нормализуется для +7, 8, пробелов и скобок.
- UTM, form_id, campaign_id и ad_id записываются в отдельные колонки.
- Ошибки Google API уходят в alert/DLQ.
- Менеджер получает уведомление только по новым лидам.
Nodbot настроит VK Lead Forms → n8n → Google Sheets: upsert, UTM, уведомления менеджерам, DLQ и проверку качества лидов.
Настроить VK leads workflow