この記事は現在英語版のみです。翻訳は近日公開予定です。
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.
執筆者
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.
関連記事
Odoo フォーム ビューにカスタム ボタンを追加する方法 (2026)
Odoo 19 フォーム ビューにカスタム アクション ボタンを追加します: Python アクション メソッド、ビューの継承、条件付き可視性、確認ダイアログ。製造テスト済み。
Studio を使用せずに Odoo にカスタムフィールドを追加する方法 (2026)
Odoo 19 のカスタム モジュールを介してカスタム フィールドを追加します: モデル継承、ビュー拡張、計算フィールド、ストア/非ストアの決定。コードファースト、バージョン管理。
外部レイアウトを使用して Odoo にカスタム レポートを追加する方法
web.external_layout: QWeb テンプレート、paperformat、アクション バインディングを使用して、Odoo 19 でブランド化された PDF レポートを構築します。印刷ロゴ + フッターのオーバーライド付き。