Интеграция WhatsApp с amoCRM через API и вебхуки
Обновлено
amoCRM ведёт сделку по этапам, wapi.kz отправляет и принимает сообщения WhatsApp с вашего номера. Если их связать, клиент получает сообщение в тот момент, когда сделка переходит на нужный этап, а его ответы появляются в карточке сделки примечаниями.
Ниже — сценарии, механика с обеих сторон и рабочий обработчик на Node.js. Номер остаётся на телефоне — писать клиентам вручную можно и дальше.
- Сделка на этапе «Оплачено»
- Webhook в цифровой воронке
- ваш обработчик
- POST /messages/send
- клиент в WhatsApp
- Клиент пишет в WhatsApp
- вебхук wapi.kz
- ваш обработчик
- примечание в сделке
Что можно автоматизировать
- Оплата получена. Сделка переходит на этап «Оплачено» — клиенту уходит подтверждение и срок отгрузки.
- Заявка принята. Сделка создана из формы на сайте — клиент, который сам оставил телефон, получает «Заявку получили, менеджер напишет в течение часа».
- Встреча или замер. На этапе «Назначена встреча» — сообщение с адресом и временем. Ответ «перенесите на завтра» ляжет примечанием в ту же сделку.
- Счёт файлом. На этапе «Выставлен счёт» обработчик отправляет PDF по публичной ссылке — подробнее в гайде о фото и файлах.
- Входящие в карточку. Клиент написал в WhatsApp — текст появляется примечанием в его сделке. Ответы менеджера с телефона (событие
message.out) можно писать туда же.
Как это устроено
Со стороны amoCRM работают два механизма:
- Webhook в цифровой воронке. На этап добавляется действие «Webhook» с адресом вашего обработчика. Когда сделка попадает на этап, amoCRM отправляет POST с id сделки. Данные приходят как form-urlencoded, а не JSON. Есть и общие вебхуки в настройках (раздел интеграций/вебхуков) — на события по сделкам и контактам.
- REST API v4. По id обработчик получает сделку и контакт (
/api/v4/leads,/api/v4/contacts) и пишет примечание (/api/v4/leads/{id}/notes). Нужен OAuth-токен вашей интеграции в amoCRM.
Со стороны wapi.kz:
POST /messages/send— отправка текста, фото или файла (документация).- Вебхук номера — входящие (
message), ответы с телефона (message.out), статусы доставки (документация).
Между ними — ваш обработчик: небольшой сервер или сценарий в n8n. Он достаёт телефон из контакта и приводит его к виду 77011234567.
Настройка по шагам
- Зарегистрируйтесь, пополните баланс и подключите номер по QR-коду — около 5 минут (как подключить).
- В карточке номера выпустите ключ номера: он работает только с этим номером, поле
fromне нужно. - В amoCRM создайте свою интеграцию в разделе интеграций и получите OAuth-токен — порядок описан в документации amoCRM для разработчиков.
- Разверните обработчик (код ниже) на сервере с публичным https-адресом.
- В цифровой воронке на этапе «Оплачено» добавьте действие «Webhook» с адресом
https://ваш-сервер.kz/amo/paid?token=СЕКРЕТ. - В кабинете wapi.kz на карточке номера укажите вебхук
https://ваш-сервер.kz/wapi?token=ДРУГОЙ_СЕКРЕТ. - Переведите тестовую сделку на этап и проверьте: сообщение пришло, примечание появилось.
Залогируйте первый запрос от amoCRM целиком — так вы увидите точную структуру полей в вашем аккаунте и сверите её с документацией amoCRM.
Пример кода
Node.js 18+ и Express. Первый маршрут принимает Webhook цифровой воронки, второй — входящие из WhatsApp.
const express = require("express");
const app = express();
const AMO = process.env.AMO_BASE + "/api/v4"; // https://вашаккаунт.amocrm.ru
const amo = (path, init = {}) =>
fetch(AMO + path, {
...init,
headers: { Authorization: `Bearer ${process.env.AMO_TOKEN}`, "Content-Type": "application/json" },
}).then((r) => (r.status === 204 ? null : r.json()));
const note = (leadId, text) =>
amo(`/leads/${leadId}/notes`, {
method: "POST",
body: JSON.stringify([{ note_type: "common", params: { text } }]),
});
const digits = (p) => {
let d = String(p).replace(/\D/g, "");
if (d.length === 11 && d[0] === "8") d = "7" + d.slice(1);
return d.length === 10 ? "7" + d : d;
};
// 1. Сделка на этапе «Оплачено» → WhatsApp клиенту
app.post("/amo/paid", express.urlencoded({ extended: true }), async (req, res) => {
if (req.query.token !== process.env.AMO_HOOK_TOKEN) return res.sendStatus(403);
res.sendStatus(200);
try {
const l = req.body.leads || {};
const leadId = (l.status || l.add || l.update || [])[0]?.id;
if (!leadId) return;
const lead = await amo(`/leads/${leadId}?with=contacts`);
const contactId = lead?._embedded?.contacts?.[0]?.id;
if (!contactId) return;
const contact = await amo(`/contacts/${contactId}`);
const field = (contact.custom_fields_values || []).find((f) => f.field_code === "PHONE");
if (!field) return;
const r = await fetch("https://wapi.kz/api/v1/messages/send", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.WAPI_KEY}`, "Content-Type": "application/json" },
body: JSON.stringify({
to: digits(field.values[0].value),
text: "Здравствуйте! Оплату получили, спасибо. Заказ передаём в работу.",
}),
});
const sent = await r.json();
await note(leadId, r.ok ? `WhatsApp отправлен, id ${sent.id}` : `WhatsApp не отправлен: ${sent.code}`);
} catch (err) {
console.error(err);
}
});
// 2. Входящее в WhatsApp → примечание в сделке контакта
app.post("/wapi", express.json(), async (req, res) => {
if (req.query.token !== process.env.WAPI_HOOK_TOKEN) return res.sendStatus(403);
res.sendStatus(200);
const e = req.body;
if (e.event !== "message" || !e.payload.from.endsWith("@c.us")) return;
try {
const phone = e.payload.from.split("@")[0];
const found = await amo(`/contacts?query=${phone.slice(-10)}&with=leads`);
const leadId = found?._embedded?.contacts?.[0]?._embedded?.leads?.[0]?.id;
if (!leadId) return; // сделки нет — создайте её или поставьте задачу
await note(leadId, "WhatsApp от клиента: " + (e.payload.hasMedia ? "[файл]" : e.payload.body));
} catch (err) {
console.error(err);
}
});
app.listen(3000);Поиск контакта по телефону зависит от того, в каком формате номера хранятся в вашей amoCRM, — проверьте на своих данных. В бою выбирайте открытую сделку, а не первую попавшуюся.
Ограничения
- Готового виджета wapi.kz в маркетплейсе amoCRM нет — связка делается через обработчик или сценарий.
- Переписка не появится в окне чатов amoCRM, как у встроенных каналов: мы пишем её примечаниями в сделку.
- Файлы от клиентов в вебхуке не приходят: там признак
hasMedia: true, а сам файл сохраняется у нас и через несколько секунд доступен по ссылкеmedia.urlвGET /messages/{id}— её можно забрать и приложить к сделке. В группы через API отправить нельзя. - Лимиты номера: не чаще 1 сообщения в секунду, первые сообщения новым людям — не чаще раза в 5 секунд и до 150 в сутки на уровне «Хороший», в первые 2 недели — меньше (лимиты). Массовый перенос сотен сделок на этап с сообщением упрётся в защиту от рассылок — и это прямой путь к блокировке номера (как её избежать).
- Повторной доставки вебхуков нет: пропущенные входящие заберите через
GET /messages?since=…(история).
Не хотите писать обработчик сами? Зарегистрируйтесь, подключите номер и оставьте заявку из кабинета — типовую связку с amoCRM настраиваем примерно за час. Номер стоит 9 900 ₸ в месяц, без платы за сообщения (цены).
Частые вопросы
Есть ли у wapi.kz виджет в маркетплейсе amoCRM?
Нет. Связка работает через Webhook цифровой воронки, API v4 и ваш обработчик — код выше или сценарий в n8n/Make.
Увидит ли менеджер переписку в чате amoCRM?
Нет, окно чатов amoCRM работает со встроенными каналами. Сообщения клиента и отметки об отправке ложатся примечаниями в сделку, а отвечают менеджеры с телефона.
Можно ли написать сразу всем сделкам воронки?
Перенос сотен сделок на этап упрётся в лимиты новых контактов и защиту от рассылок, а холодные массовые сообщения — главная причина блокировок. Пишите тем, кто ждёт сообщения по своей сделке.
Подойдёт ли это для Kommo?
Kommo — международная версия amoCRM, механика та же: вебхуки и API v4. Отличается адрес аккаунта — сверьтесь с документацией Kommo.
Подключите WhatsApp к amoCRM
9 900 ₸ в месяц за номер, без платы за сообщения. Сервер в Казахстане, оплата Kaspi или счётом на ТОО/ИП. Подключение — около 5 минут.