Skip to content

Website Lead Notification

The Website Lead Notification workflow instantly notifies admins on Telegram as soon as a visitor fills out the Odoo contact form. The CRM opportunity is created automatically on the Odoo side, and N8N sends a formatted message with the prospect’s details.

StepComponentAction
1Odoo formVisitor submits the contactus form
2Odoo CRMAutomatically creates an opportunity
3Automated ActionDetects the new lead (medium=Website)
4Odoo webhookSends data to N8N (internal network)
5N8N workflowFormats and routes to Telegram

ProblemWithout this workflowWith this workflow
Response timeLead discovered the next dayInstant notification
Missed leadsForget to check the CRMPush to mobile
Lost contextGo back into Odoo to see detailsAll info inside Telegram
ApproachAdvantageDrawback
Internal webhook (Docker)Secure, no auth neededOnly for Docker services
Polling Odoo APISimpler to set upLatency, server load
External webhookReachable everywhereRequires auth + TLS

Odoo web form · contactus

crm.lead created · Create Opportunity

Automated Action · medium_id = Website

Odoo Webhook · HTTP POST

N8N Webhook /odoo/website-lead · internal only

Notification Hub

Telegram admins

AspectConfiguration
Internal URLhttp://n8n:5678/webhook/odoo/website-lead
External accessBlocked by Caddy (403 Forbidden)
AuthenticationNone (internal Docker traffic)

Caddy configuration:

@internal_webhooks {
path /webhook/notify/*
path /webhook/prometheus/*
path /webhook/odoo/*
}
handle @internal_webhooks {
respond "Forbidden" 403
}

Menu: Settings → Technical → Automation → Automated Actions

FieldValue
NameN8N: Notify on Website Lead
ModelLead/opportunity (crm.lead)
TriggerOn save
Apply on[('medium_id.name', '=', 'Website')]
ActionSend a webhook notification
URLhttp://n8n:5678/webhook/odoo/website-lead

Sent fields:

  • name — Opportunity name
  • contact_name — Contact name
  • email_from — Email
  • phone — Phone
  • partner_name — Company name
  • description — Form message

Format Lead Node (Code):

const lead = $json.body;
const message = `👤 Contact: ${lead.contact_name || lead.name || 'Not provided'}
🏢 Company: ${lead.partner_name || 'Not provided'}
📧 Email: ${lead.email_from || 'Not provided'}
📱 Phone: ${lead.phone || lead.mobile || 'Not provided'}
💬 Message:
${lead.description ? lead.description.substring(0, 500) : 'No description'}
📋 https://odoo.guigpap.com/odoo/crm/${lead._id}`;
return {
json: {
source: "odoo_website_form",
type: "new_lead",
severity: "info",
title: `🌐 New opportunity: ${lead.contact_name || lead.name}`,
message: message,
timestamp: new Date().toISOString(),
hasCallback: false
}
};
Fenêtre de terminal
# Test the webhook from Odoo
docker exec odoo curl -s -X POST \
"http://n8n:5678/webhook/odoo/website-lead" \
-H "Content-Type: application/json" \
-d '{
"_id": 999,
"_model": "crm.lead",
"name": "Test Lead",
"contact_name": "Jean Dupont",
"email_from": "jean@test.com",
"phone": "+33 6 12 34 56 78",
"partner_name": "Test Company",
"description": "Test message"
}'
# Expected: {"status": "ok"} + Telegram notification
# Check Docker connectivity
docker exec odoo curl -s http://n8n:5678/healthz

LimitImpactMitigation
Unidirectional webhookNo read-receiptLink to Odoo in the message
No Telegram replyManual return to OdooPlanned: action buttons
N8N dependencyNo notification if N8N is downN8N container monitoring

If you need to reply from Telegram:

  • Add inline buttons (Assign, Qualify, Call)
  • Callback to Odoo to update the lead
  • Confirmation notification

If lead volume grows:

  • Filter by lead score
  • Rotate assignments
  • Hourly digest instead of instant push

If multi-channel is needed:

  • Add ntfy as backup
  • Email notification for VIP leads
  • Slack integration if a team is involved
ProblemCheck
No notificationN8N: workflow active? Notification Hub executed?
Webhook timeoutdocker exec odoo curl http://n8n:5678/healthz
Missing dataCheck selected fields in the Odoo webhook
Quiet hoursNotification deferred if 22:00-07:00 (except severity=critical)