Este artigo está atualmente disponível apenas em inglês. Tradução em breve.
By the end of this recipe, your Odoo 19 CRM will send WhatsApp messages — both pre-approved templates (for outbound marketing) and free-form replies (within a 24-hour customer-initiated session) — through Meta's WhatsApp Business Cloud API. Inbound messages create CRM leads automatically, and customer opt-in is tracked per-contact for compliance. Skill required: Odoo developer with Meta Business Suite access. Time required: 4 hours setup, 2 hours testing across template, session, and webhook flows. ECOSIRE uses this internally on wa.me/ecosire and the recipe below is the playbook we ship.
The reason most WhatsApp-Odoo integrations fail compliance: they send promotional messages outside the 24-hour customer-initiated window without using approved templates. Meta penalizes the phone number with a quality drop, then a ban. The recipe below structures the flow so all outbound is template-gated and all inbound resets the 24-hour session correctly.
What you will need
- Meta Business Suite account with admin access to a verified business.
- WhatsApp Business Account (WABA) registered to your business.
- Phone number dedicated to WhatsApp Business — once registered, it cannot be used for personal WhatsApp.
- System User access token with
whatsapp_business_messaging,whatsapp_business_managementscopes (long-lived). - Public HTTPS endpoint for webhook receiving.
- Odoo version: 17, 18, or 19. The native
whatsappmodule landed in v17 Enterprise; for Community we build a small custom module. - Time: 4 hours setup, 2 hours testing. Add 24 to 72 hours for Meta to approve your first message templates.
Step-by-step
1. Provision the WhatsApp Business phone number
In Meta Business Suite > WhatsApp Manager > Phone Numbers > Add Phone Number. Verify via SMS or voice call. Choose a display name (e.g., "ECOSIRE"). Save the Phone Number ID and WABA ID — you'll paste them into Odoo.
Verification: the phone number shows status "Connected" and quality rating "Green".
2. Create the system user and get a long-lived token
Meta Business Suite > Business Settings > System Users > Create. Generate a token with whatsapp_business_messaging and whatsapp_business_management scopes, set as "Never expires". Copy and store securely. Verification: a curl to https://graph.facebook.com/v18.0/me?access_token=YOUR_TOKEN returns the system user JSON.
3. Create your first message template
In WhatsApp Manager > Message Templates > Create. Pick category (Marketing, Utility, or Authentication). Marketing templates require user opt-in. For a quote-follow-up template:
- Name:
quote_followup_v1 - Category: Utility
- Language: English
- Body:
Hi {{1}}, your quote {{2}} from ECOSIRE is ready. Total: {{3}}. Reply YES to approve or call us at {{4}}.
Submit for approval. Meta reviews in 1 to 24 hours. Verification: template status moves from "Pending" to "Approved".
4. Configure the WhatsApp backend in Odoo
Install the whatsapp module. Go to Settings > WhatsApp > Configuration > Create:
- Name: ECOSIRE Main
- Phone Number ID: from step 1
- WABA ID: from step 1
- Access Token: from step 2
- Webhook Verify Token: a random string you'll use in step 5
Verification: click "Test Connection" — green check mark.
5. Configure the webhook
In Meta Business Suite > WhatsApp > Configuration > Webhooks. Set Callback URL = https://your-odoo.com/whatsapp/webhook, Verify Token = the one you configured in Odoo. Subscribe to fields: messages, message_status, message_template_status_update.
from odoo import http
from odoo.http import request
import hashlib
import hmac
class WhatsAppWebhookController(http.Controller):
@http.route('/whatsapp/webhook', auth='public', csrf=False, methods=['GET', 'POST'])
def webhook(self, **kwargs):
if request.httprequest.method == 'GET':
# Webhook verification handshake
mode = kwargs.get('hub.mode')
token = kwargs.get('hub.verify_token')
challenge = kwargs.get('hub.challenge')
backend = request.env['whatsapp.account'].sudo().search([], limit=1)
if mode == 'subscribe' and token == backend.webhook_verify_token:
return request.make_response(challenge, status=200)
return request.make_response('Forbidden', status=403)
# POST: actual message
body = request.httprequest.get_data()
signature = request.httprequest.headers.get('X-Hub-Signature-256', '')
backend = request.env['whatsapp.account'].sudo().search([], limit=1)
digest = 'sha256=' + hmac.new(backend.app_secret.encode(), body, hashlib.sha256).hexdigest()
if not hmac.compare_digest(digest, signature):
return request.make_response('Bad signature', status=401)
payload = request.jsonrequest
for entry in payload.get('entry', []):
for change in entry.get('changes', []):
if change['field'] == 'messages':
request.env['whatsapp.account'].sudo()._process_inbound(change['value'])
return request.make_response('OK', status=200)
Verification: in Meta's webhook config, click "Test" — Odoo's log shows the verification request and response.
6. Send a template message
Use the Cloud API endpoint to send the template:
def _send_template(self, recipient, template_name, params):
payload = {
'messaging_product': 'whatsapp',
'to': recipient,
'type': 'template',
'template': {
'name': template_name,
'language': {'code': 'en'},
'components': [{
'type': 'body',
'parameters': [{'type': 'text', 'text': p} for p in params],
}],
},
}
resp = requests.post(
f"https://graph.facebook.com/v18.0/{self.phone_number_id}/messages",
json=payload,
headers={'Authorization': f'Bearer {self.access_token}'},
timeout=30,
)
resp.raise_for_status()
return resp.json()['messages'][0]['id']
Wire it to a server action on crm.lead: "Send Quote Follow-up". The action grabs the lead's phone, the latest quote number and total, and calls _send_template('quote_followup_v1', [name, quote_no, total, hotline]).
Verification: trigger the action on a test lead with your phone number; you receive the message within 5 seconds.
7. Handle inbound messages and create leads
Inbound messages arrive via the webhook in step 5. Process them:
def _process_inbound(self, value):
for msg in value.get('messages', []):
if msg['type'] != 'text':
continue # extend for image, audio, document
phone = msg['from']
text = msg['text']['body']
partner = self.env['res.partner'].search([
('phone', '=ilike', f'%{phone[-10:]}'), # match last 10 digits
], limit=1)
if not partner:
partner = self.env['res.partner'].create({
'name': f'WhatsApp {phone}',
'phone': phone,
'whatsapp_optin': True,
})
# Log on existing lead or create new
lead = self.env['crm.lead'].search([
('partner_id', '=', partner.id),
('stage_id.is_won', '=', False),
], limit=1)
if not lead:
lead = self.env['crm.lead'].create({
'name': f'WhatsApp lead from {partner.name}',
'partner_id': partner.id,
'description': text,
'source_id': self.env.ref('utm.utm_source_whatsapp').id,
})
else:
lead.message_post(body=f"WhatsApp inbound: {text}")
Verification: send a test inbound from your personal WhatsApp; a CRM lead appears in Odoo with the message.
8. Track opt-in and message status
Add a boolean whatsapp_optin on res.partner. Set it to True only when the user explicitly initiates a conversation or signs up to receive messages on a website form. For each outbound, check this flag — refuse to send if False.
Subscribe to message_status webhook events to track sent/delivered/read/failed:
def _process_status(self, value):
for status in value.get('statuses', []):
msg = self.env['mail.message'].search([
('whatsapp_message_id', '=', status['id']),
], limit=1)
if msg:
msg.whatsapp_status = status['status'] # sent, delivered, read, failed
Verification: send a template to your phone, mark it read, and the Odoo message record updates to read within 30 seconds.
Common mistakes
- Sending promotional messages without an approved template. Meta drops the number's quality rating instantly.
- Sending to users who haven't opted in. EU GDPR and most regions require explicit consent. Track it.
- Skipping HMAC signature verification. Anyone can fake webhook payloads.
- Treating WhatsApp as SMS. The 24-hour customer-initiated session is a hard rule. Outside it, only templates are allowed.
- Forgetting to handle media messages. Customers send images, voice notes, PDFs. Process them or at least log them; ignoring breaks customer trust.
Going further
Multi-agent inbox: extend the mail.channel model so multiple sales reps can pick up incoming WhatsApp threads from a shared queue.
Bot reply with AI: route inbound text through Claude or GPT for first-touch qualification, escalating to human only for complex queries.
Click-to-WhatsApp ads: link Meta Ads Manager to your WABA so ad clicks open a WhatsApp conversation pre-filled with a tracking parameter, attributing the lead source.
Order status updates: send a Utility template every time a Sales Order moves through pick > pack > ship > delivered. Customers love the proactive updates.
For full WhatsApp + Odoo integration including multi-agent inbox, AI qualification, and broadcast campaigns, ECOSIRE Odoo customization ships fixed-price engagements. We have built this for clients in retail, services, and B2B SaaS. Pair this with how to integrate Twilio SMS with Odoo for an SMS fallback when WhatsApp is unavailable.
Frequently Asked Questions
What does WhatsApp Business API cost?
Meta charges per conversation, not per message. A conversation is initiated by your business (Marketing, Utility, Authentication categories at different rates) or by the user (free for the first 1,000 user-initiated conversations per month, then per-conversation). Rates vary by country: US Marketing is around $0.025, India is $0.005, UK is $0.0625.
Can I use the WhatsApp Web QR code instead?
No. Meta explicitly forbids automating WhatsApp Web for business; accounts get banned. Always use the official Cloud API.
How long does template approval take?
Most templates are approved within 1 hour. Marketing templates with promotional language sometimes take up to 24 hours. Pre-write templates so they're ready before launch.
What if my phone number gets banned?
Quality drops can happen if you send too many marketing messages without engagement. The fix is to slow down outbound, increase customer-initiated traffic, and let the rating recover over 1 to 2 weeks. ECOSIRE's wa.me/ecosire has been Green-rated for over 2 years on a steady drip of utility messages.
For a fully managed WhatsApp deployment including template library, AI bot, and multi-agent inbox, ECOSIRE custom Odoo development builds the complete stack. Or read how to set up an Odoo discount and loyalty program for the customer-engagement layer that pairs well with WhatsApp.
Escrito por
ECOSIRE TeamTechnical Writing
The ECOSIRE technical writing team covers Odoo ERP, Shopify eCommerce, AI agents, Power BI analytics, GoHighLevel automation, and enterprise software best practices. Our guides help businesses make informed technology decisions.
ECOSIRE
Transforme seu negócio com o Odoo ERP
Implementação, personalização e suporte especializado do Odoo para agilizar suas operações.
Artigos Relacionados
Como adicionar um botão personalizado a uma visualização de formulário Odoo (2026)
Adicione botões de ação personalizados às visualizações de formulário do Odoo 19: método de ação Python, herança de visualização, visibilidade condicional, caixas de diálogo de confirmação. Testado em produção.
Como adicionar um campo personalizado no Odoo sem Studio (2026)
Adicione campos personalizados por meio de módulo personalizado no Odoo 19: herança de modelo, extensão de visualização, campos computados, decisões de loja/não loja. Código primeiro, controlado por versão.
Como adicionar um relatório personalizado no Odoo usando layout externo
Crie um relatório PDF de marca no Odoo 19 usando web.external_layout: modelo QWeb, formato de papel, vinculação de ação. Com logotipo impresso + substituições de rodapé.