feat: Major WhatsApp integration update with Odoo and pause/resume
## Frontend - Add media display (images, audio, video, docs) in Inbox - Add pause/resume functionality for WhatsApp accounts - Fix media URLs to use nginx proxy (relative URLs) ## API Gateway - Add /accounts/:id/pause and /accounts/:id/resume endpoints - Fix media URL handling for browser access ## WhatsApp Core - Add pauseSession() - disconnect without logout - Add resumeSession() - reconnect using saved credentials - Add media download and storage for incoming messages - Serve media files via /media/ static route ## Odoo Module (odoo_whatsapp_hub) - Add Chat Hub interface with DOLLARS theme (dark, 3-column layout) - Add WhatsApp/DRRR theme switcher for chat view - Add "ABRIR CHAT" button in conversation form - Add send_message_from_chat() method - Add security/ir.model.access.csv - Fix CSS scoping to avoid breaking Odoo UI - Update webhook to handle message events properly ## Documentation - Add docs/CONTEXTO_DESARROLLO.md with complete project context ## Infrastructure - Add whatsapp_media Docker volume - Configure nginx proxy for /media/ route - Update .gitignore to track src/sessions/ source files Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -8,14 +8,15 @@ _logger = logging.getLogger(__name__)
|
||||
|
||||
class WhatsAppWebhookController(http.Controller):
|
||||
|
||||
@http.route('/whatsapp/webhook', type='json', auth='public', methods=['POST'], csrf=False)
|
||||
@http.route('/whatsapp/webhook', type='http', auth='public', methods=['POST'], csrf=False)
|
||||
def webhook(self, **kwargs):
|
||||
"""
|
||||
Receive webhooks from WhatsApp Central.
|
||||
Events: message, status_update, conversation_update
|
||||
"""
|
||||
try:
|
||||
data = request.jsonrequest
|
||||
# Parse JSON from request body
|
||||
data = json.loads(request.httprequest.data.decode('utf-8'))
|
||||
event_type = data.get('type')
|
||||
|
||||
_logger.info(f'WhatsApp webhook received: {event_type}')
|
||||
@@ -29,13 +30,14 @@ class WhatsAppWebhookController(http.Controller):
|
||||
|
||||
handler = handlers.get(event_type)
|
||||
if handler:
|
||||
return handler(data)
|
||||
result = handler(data)
|
||||
return request.make_json_response(result)
|
||||
|
||||
return {'status': 'ignored', 'reason': f'Unknown event type: {event_type}'}
|
||||
return request.make_json_response({'status': 'ignored', 'reason': f'Unknown event type: {event_type}'})
|
||||
|
||||
except Exception as e:
|
||||
_logger.error(f'WhatsApp webhook error: {e}')
|
||||
return {'status': 'error', 'message': str(e)}
|
||||
return request.make_json_response({'status': 'error', 'message': str(e)})
|
||||
|
||||
def _handle_message(self, data):
|
||||
"""Handle incoming message"""
|
||||
@@ -64,23 +66,25 @@ class WhatsAppWebhookController(http.Controller):
|
||||
'status': 'bot',
|
||||
})
|
||||
|
||||
# Try to find partner by phone
|
||||
partner = request.env['res.partner'].sudo().search([
|
||||
'|',
|
||||
('phone', 'ilike', phone[-10:]),
|
||||
('mobile', 'ilike', phone[-10:]),
|
||||
], limit=1)
|
||||
|
||||
if partner:
|
||||
conversation.partner_id = partner
|
||||
|
||||
# Get direction from webhook data (inbound or outbound)
|
||||
direction = msg_data.get('direction', 'inbound')
|
||||
|
||||
request.env['whatsapp.message'].sudo().create({
|
||||
'external_id': msg_data.get('id'),
|
||||
'conversation_id': conversation.id,
|
||||
'direction': 'inbound',
|
||||
'direction': direction,
|
||||
'message_type': msg_data.get('type', 'text'),
|
||||
'content': msg_data.get('content'),
|
||||
'media_url': msg_data.get('media_url'),
|
||||
'status': 'delivered',
|
||||
'status': 'delivered' if direction == 'inbound' else 'sent',
|
||||
})
|
||||
|
||||
return {'status': 'ok'}
|
||||
@@ -137,4 +141,4 @@ class WhatsAppWebhookController(http.Controller):
|
||||
@http.route('/whatsapp/webhook/test', type='http', auth='public', methods=['GET'])
|
||||
def webhook_test(self):
|
||||
"""Test endpoint to verify webhook connectivity"""
|
||||
return json.dumps({'status': 'ok', 'message': 'WhatsApp webhook is active'})
|
||||
return request.make_json_response({'status': 'ok', 'message': 'WhatsApp webhook is active'})
|
||||
|
||||
Reference in New Issue
Block a user