Đưa lead từ form web về Telegram bằng n8n

Khách vừa bấm gửi, điện thoại anh chị rung. Bài này dựng đúng luồng đó với bốn khối, kèm ba chỗ hay làm luồng chết im lặng.

Đăng 06/10/2026Đọc khoảng 9 phútForm → Webhook → Telegram

Nhiều doanh nghiệp nhỏ có website, có form “để lại số điện thoại”, nhưng lead nằm trong hộp thư hoặc trong trang quản trị mà không ai mở. Khách để lại số lúc 9 giờ tối, sáng hôm sau mới có người gọi, lúc đó khách đã nói chuyện với bên khác. Luồng trong bài này làm một việc rất hẹp: mỗi lần form được gửi, một tin nhắn Telegram bay về điện thoại người phụ trách.

Tóm tắt nhanh

  • Cần: một tài khoản Telegram, một chỗ chạy n8n (n8n Cloud hoặc tự cài), quyền sửa mã form trên website.
  • Luồng gồm: Webhook nhận dữ liệu form, Telegram gửi tin. Thêm Respond to Webhook nếu muốn trả lời form cho đúng.
  • Ba bẫy: quên đổi từ đường dẫn thử sang đường dẫn thật, chat id sai, dán token vào ô chữ.
Form trên web gửi dữ liệu tới node Webhook của n8n, n8n gửi tin qua Telegram Form trên webfetch POST Webhook$json.body TelegramSend Message
Luồng tối thiểu: hai node trong n8n, một đoạn mã nhỏ trên website.

Bước 1: Tạo bot Telegram và lấy chat id

Telegram cho phép tạo bot miễn phí qua tài khoản chính thức tên @BotFather.

  1. Mở Telegram, tìm @BotFather (có dấu tích xanh), gõ /newbot.
  2. Đặt tên hiển thị, rồi đặt username cho bot, username phải kết thúc bằng chữ bot.
  3. BotFather trả về một chuỗi token dạng 123456789:ABC.... Đây là chìa khoá điều khiển bot, coi như mật khẩu. Chép tạm vào chỗ an toàn.
  4. Tìm bot vừa tạo, bấm Start và nhắn một câu bất kỳ. Bot không thể nhắn cho người chưa từng nhắn nó trước, nên bước này bắt buộc.

Để lấy chat id (mã số cuộc trò chuyện của anh chị với bot), mở trình duyệt và vào địa chỉ sau, thay phần trong ngoặc nhọn bằng token thật:

https://api.telegram.org/bot<TOKEN_BOT_CUA_ANH_CHI>/getUpdates

Trong kết quả, tìm đoạn "chat":{"id": ...}. Con số đó là chat id. Nếu muốn báo vào một nhóm, thêm bot vào nhóm, nhắn một câu trong nhóm rồi gọi lại địa chỉ trên; chat id của nhóm thường là số âm.

Bước 2: Dựng node Webhook trong n8n

Tạo workflow (luồng) mới, thêm node Webhook làm điểm bắt đầu và chỉnh:

Node Webhook hiển thị hai địa chỉ: Test URL (có đoạn /webhook-test/) và Production URL (có đoạn /webhook/). Hai địa chỉ này khác nhau về cách sống, và đây là bẫy số một ở cuối bài.

Dữ liệu form gửi lên sẽ nằm trong $json.body, không nằm thẳng ở $json. Node Webhook bọc dữ liệu người dùng gửi vào trường body, bên cạnh headers và query. Viết {{ $json.name }} sẽ ra rỗng; phải là {{ $json.body.name }}.

Bước 3: Nối node Telegram

  1. Thêm node Telegram sau Webhook, chọn thao tác gửi tin nhắn (Resource: Message, Operation: Send Message).
  2. Ở ô Credential, tạo mới, dán token bot vào. Token nằm trong kho credential của n8n, được mã hoá, không lộ ra khi anh chị xuất workflow ra file.
  3. Chat ID: dán chat id lấy ở bước 1.
  4. Text: chuyển sang chế độ Expression và soạn nội dung, ví dụ:
🔔 Lead mới từ website
Tên: {{ $json.body.name }}
SĐT: {{ $json.body.phone }}
Nhu cầu: {{ $json.body.note || '(không ghi)' }}
Trang: {{ $json.body.page }}
Lúc: {{ $now.setZone('Asia/Ho_Chi_Minh').toFormat('HH:mm dd/LL/yyyy') }}

$now là thời điểm hiện tại, dùng thư viện Luxon (thư viện xử lý ngày giờ mà n8n tích hợp sẵn). Đặt múi giờ rõ ràng để giờ trên tin nhắn không lệch 7 tiếng khi máy chủ đặt ở nước ngoài.

Bước 4: Sửa form trên website để gửi về n8n

Đoạn mã dưới đây gửi dữ liệu form bằng fetch (lệnh gửi yêu cầu HTTP của trình duyệt). Đổi địa chỉ thành Production URL của anh chị và tên trường cho khớp form thật:

// Đặt sau form có id="form-lead". Địa chỉ dưới là VÍ DỤ, thay bằng Production URL của anh chị.
const DIA_CHI = 'https://n8n.ten-mien-cua-anh-chi.vn/webhook/lead-form';
const f = document.getElementById('form-lead');
f.addEventListener('submit', async (ev) => {
  ev.preventDefault();
  if (f.website && f.website.value) return; // ô bẫy máy tự điền, người thật không thấy
  const du_lieu = {
    name: f.name.value.trim(),
    phone: f.phone.value.replace(/\s+/g, ''),
    note: f.note ? f.note.value.trim() : '',
    page: location.pathname
  };
  try {
    const r = await fetch(DIA_CHI, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(du_lieu)
    });
    if (!r.ok) throw new Error('HTTP ' + r.status);
    f.innerHTML = '<p>Đã nhận thông tin, chúng tôi sẽ gọi lại sớm.</p>';
  } catch (loi) {
    alert('Chưa gửi được, anh chị gọi trực tiếp số hotline giúp nhé.');
  }
});

Nếu website và n8n nằm ở hai tên miền khác nhau, trình duyệt sẽ áp luật CORS (chia sẻ tài nguyên giữa các nguồn khác nhau). Trong node Webhook có tuỳ chọn Allowed Origins (CORS), điền tên miền website vào đó. Tên tuỳ chọn có thể khác đôi chút theo phiên bản n8n.

Bước 5: Thử, rồi bật chạy thật

  1. Bấm nút thử luồng (Test workflow / Execute workflow) trong n8n. Lúc này Test URL mới bắt đầu nghe.
  2. Tạm đổi DIA_CHI sang Test URL, gửi form một lần. Telegram phải rung.
  3. Đổi lại về Production URL, rồi bật luồng chạy thật (công tắc Active, ở một số phiên bản mới là nút Publish).
  4. Gửi form thêm một lần nữa với tên TEST - bo qua và kiểm Telegram. Mở tab Executions để thấy lần chạy được ghi lại.

Ba bẫy làm luồng chết im lặng

BẫyDấu hiệuCách tránh
Form vẫn trỏ vào Test URLLúc thử thì báo, hôm sau im. Test URL chỉ sống khi đang bấm thử trong trình soạn.Tìm chữ webhook-test trong mã website. Có là sai.
Chat id sai hoặc chưa nhắn botExecutions báo lỗi “chat not found”.Nhắn cho bot trước, lấy lại chat id qua getUpdates.
Token dán thẳng vào ô chữLuồng chạy, nhưng ai xem file workflow cũng thấy token.Chỉ để token trong Credentials. Lỡ lộ thì /revoke ở BotFather.

Bẫy đầu tiên chúng tôi gặp ngay trong hệ thống của mình: một webhook vẫn trỏ về đường dẫn webhook-test sau khi đã thử xong, nên chỉ nhận dữ liệu những lúc có người đang mở trình soạn. Từ đó, việc đầu tiên khi rà một luồng là tìm chữ webhook-test.

Một lưu ý về CORS: nếu cấu hình CORS sai, trình duyệt có thể chặn việc đọc phản hồi trong khi máy chủ vẫn nhận dữ liệu. Form báo lỗi với khách, nhưng lead vẫn vào. Vì vậy khi thử, hãy xem cả Telegram lẫn Executions, đừng chỉ nhìn màn hình form.

Bước tiếp theo: Telegram chỉ là chuông báo. Lead cần một chỗ lưu để không mất khi tin nhắn trôi.

Đọc bài 2: Ghi mỗi lead thành một dòng Google Sheet

Câu hỏi thường gặp

Không có máy chủ riêng thì có dùng n8n được không?

Được. Có hai cách: dùng bản n8n Cloud do chính n8n vận hành (trả phí theo gói), hoặc tự cài n8n lên một máy chủ ảo. Luồng trong bài chạy giống nhau ở cả hai, chỉ khác địa chỉ của đường dẫn Webhook.

Vì sao form gửi được mà Telegram không báo gì?

Ba nguyên nhân hay gặp nhất: form đang gọi đường dẫn thử (có chữ webhook-test) thay vì đường dẫn chạy thật; luồng chưa được bật chạy thật; hoặc chat id sai vì anh chị chưa nhắn tin cho bot lần nào. Mở tab Executions trong n8n để xem luồng có được gọi không.

Có cần lưu lead vào đâu khác ngoài Telegram không?

Nên có. Telegram là kênh báo, không phải kho lưu. Tin nhắn có thể bị xoá, bị trôi, hoặc gửi lỗi khi Telegram chậm. Bài tiếp theo hướng dẫn ghi mỗi lead thành một dòng Google Sheet trước khi báo.

Token bot Telegram để ở đâu cho an toàn?

Để trong mục Credentials của n8n, không dán vào ô chữ của node, không đưa lên mã nguồn website. Nếu lỡ để lộ, vào BotFather dùng lệnh /revoke để thu hồi và lấy token mới.

Đọc tiếp