diff options
| author | Miqdad <ahmadmiqdad27@gmail.com> | 2025-06-09 17:35:22 +0700 |
|---|---|---|
| committer | Miqdad <ahmadmiqdad27@gmail.com> | 2025-06-09 17:35:22 +0700 |
| commit | 5f5753dbec8af518dd34821820462cd6340a2a08 (patch) | |
| tree | 09c2bd8a52124700e74a4b512267d215c2e23421 | |
| parent | 1bd3a91889f8616d7042c0d15315c2f25c974ed3 (diff) | |
<miqdad> wati leads
| -rw-r--r-- | indoteknik_api/controllers/api_v1/wati.py | 171 | ||||
| -rw-r--r-- | indoteknik_custom/models/wati.py | 166 |
2 files changed, 332 insertions, 5 deletions
diff --git a/indoteknik_api/controllers/api_v1/wati.py b/indoteknik_api/controllers/api_v1/wati.py index 68ff1640..d60cd160 100644 --- a/indoteknik_api/controllers/api_v1/wati.py +++ b/indoteknik_api/controllers/api_v1/wati.py @@ -2,19 +2,182 @@ from .. import controller from odoo import http from odoo.http import request import json +import logging +_logger = logging.getLogger(__name__) -class Wati(controller.Controller): + +# class Wati(controller.Controller): +# prefix = '/api/v1/' +# +# @http.route(prefix + 'wati/notification', auth='none', type='json', csrf=False, cors='*', methods=['POST', 'OPTIONS']) +# def notification(self, **kw): +# json_raw = json.loads(request.httprequest.data) +# json_dump = json.dumps(json_raw, indent=4, sort_keys=True) +# +# request.env['wati.notification'].create([{ +# 'json_raw': json_dump, +# 'is_lead': False +# }]) +# +# return + +# REPLACE webhook controller yang sudah ada dengan ini: + +class Wati(http.Controller): prefix = '/api/v1/' - @http.route(prefix + 'wati/notification', auth='none', type='json', csrf=False, cors='*', methods=['POST', 'OPTIONS']) + @http.route(prefix + 'wati/notification', auth='none', type='json', csrf=False, cors='*', + methods=['POST', 'OPTIONS']) def notification(self, **kw): json_raw = json.loads(request.httprequest.data) json_dump = json.dumps(json_raw, indent=4, sort_keys=True) - request.env['wati.notification'].create([{ + # Create notification record (existing) + notification = request.env['wati.notification'].create([{ 'json_raw': json_dump, 'is_lead': False }]) - return + # NEW: Immediate tags check + phone = json_raw.get('waId') or json_raw.get('from') + + if phone: + lead_id = self._check_tags_immediate(phone, notification[0]) + + if lead_id: + notification.write({'is_lead': True, 'lead_id': lead_id}) + _logger.info('🚀 Lead created immediately via webhook: %s' % lead_id) + + return {'status': 'success'} + + def _check_tags_immediate(self, phone, notification): + """Check tags untuk specific phone - immediate""" + try: + _logger.info('📱 Immediate tags check for: %s' % phone) + + # Get contact dari WATI untuk phone ini + wati_api = request.env['wati.api'] + + params = { + 'pageSize': 1, + 'pageNumber': 1, + 'attribute': json.dumps([ + {'name': "phone", 'operator': "contain", 'value': phone} + ]), + } + + result = wati_api.http_get('/api/v1/getContacts', params) + + if isinstance(result, dict) and result.get('result') == 'success': + contact_list = result.get('contact_list', []) + + if contact_list: + contact = contact_list[0] + + # Check if has tags=leads + if self._contact_has_tags_leads(contact): + # Check existing lead + existing_lead = request.env['crm.lead'].search([('phone', '=', phone)], limit=1) + + if existing_lead: + _logger.info('✅ Lead already exists for %s' % phone) + return existing_lead.id + + # Create new lead + lead_id = self._create_lead_from_webhook(contact) + if lead_id: + _logger.info('🎯 Created new lead %s from webhook tags' % lead_id) + return lead_id + + return None + + except Exception as e: + _logger.error('❌ Error in immediate tags check: %s' % str(e)) + return None + + def _contact_has_tags_leads(self, contact): + """Check if contact has tags=leads""" + custom_params = contact.get('customParams', []) + + for param in custom_params: + if (param.get('name', '').lower() == 'tags' and + param.get('value', '').lower() == 'leads'): + return True + + return False + + def _create_lead_from_webhook(self, contact): + """Create lead dari webhook data""" + try: + phone = contact.get('phone', '') + + # Extract data dari customParams + custom_params = contact.get('customParams', []) + contact_data = {} + + for param in custom_params: + param_name = param.get('name', '').lower() + param_value = param.get('value', '').strip() + + if param_name == 'perusahaan': + contact_data['perusahaan'] = param_value + elif param_name == 'name': + contact_data['name'] = param_value + elif param_name == 'email': + contact_data['email'] = param_value + elif param_name == 'sales': + contact_data['sales'] = param_value + elif param_name == 'notes': + contact_data['notes'] = param_value + + # Generate lead name + company_name = contact_data.get('perusahaan', '') + contact_name = contact_data.get('name', '') or contact.get('name', '') + + if company_name: + lead_name = 'WATI Lead (Webhook) - %s' % company_name + elif contact_name: + lead_name = 'WATI Lead (Webhook) - %s' % contact_name + else: + lead_name = 'WATI Lead (Webhook) - %s' % phone + + # Get salesperson + sales_name = contact_data.get('sales', '') + user_id = 2 # Default + + if sales_name: + user = request.env['res.users'].search([('name', 'ilike', sales_name)], limit=1) + if user: + user_id = user.id + + # Create lead + lead_vals = { + 'name': lead_name, + 'phone': phone, + 'contact_name': contact_name, + 'partner_name': company_name, + 'email_from': contact_data.get('email', ''), + 'description': contact_data.get('notes', 'Lead created from WATI webhook (real-time)'), + 'type': 'lead', + 'user_id': user_id, + } + + new_lead = request.env['crm.lead'].create(lead_vals) + + # Create activity untuk follow up + request.env['mail.activity'].create({ + 'activity_type_id': request.env.ref('mail.mail_activity_data_todo').id, + 'summary': '🚨 URGENT: New WATI Lead (Real-time)', + 'note': 'Lead created instantly from WATI webhook when tags=leads was added. Immediate follow up required!', + 'res_id': new_lead.id, + 'res_model_id': request.env.ref('crm.model_crm_lead').id, + 'user_id': user_id, + 'date_deadline': fields.Date.today(), + }) + + return new_lead.id + + except Exception as e: + _logger.error('❌ Error creating lead from webhook: %s' % str(e)) + return None
\ No newline at end of file diff --git a/indoteknik_custom/models/wati.py b/indoteknik_custom/models/wati.py index a0619f83..18517502 100644 --- a/indoteknik_custom/models/wati.py +++ b/indoteknik_custom/models/wati.py @@ -201,6 +201,170 @@ class WatiNotification(models.Model): wati.is_lead = True wati.lead_id = current_lead.id + # FINAL CODE - Sesuai dengan mapping table Anda + + def check_wati_tags_leads(self): + """Check tags 'leads' di WATI dan create leads di Odoo - Final Version""" + _logger.info('=== Starting WATI Tags Check (Final) ===') + + wati_api = self.env['wati.api'] + total_leads_created = 0 + + try: + # Get WATI contacts + wati_contacts = wati_api.http_get('/api/v1/getContacts', {'pageSize': 100, 'pageNumber': 1}) + + if isinstance(wati_contacts, dict) and wati_contacts.get('result') == 'success': + contact_list = wati_contacts.get('contact_list', []) + + for contact in contact_list: + if self._create_lead_if_tagged(contact): + total_leads_created += 1 + + _logger.info('WATI check completed: %s leads created' % total_leads_created) + return {'leads_created': total_leads_created} + + except Exception as e: + _logger.error('Error in WATI tags check: %s' % str(e)) + return {'leads_created': 0, 'error': str(e)} + + def _create_lead_if_tagged(self, contact): + """Create lead jika contact punya tags=leads - Sesuai Mapping Table""" + try: + # Check tags leads + if not self._has_tags_leads(contact): + return False + + phone = contact.get('phone', '') + if not phone: + return False + + # Check existing lead by phone + existing_lead = self.env['crm.lead'].search([('phone', '=', phone)], limit=1) + if existing_lead: + _logger.info('Lead already exists for phone %s' % phone) + return False + + # Extract data dari customParams sesuai mapping table + custom_params = contact.get('customParams', []) + contact_data = self._extract_contact_data(custom_params) + + # Create lead dengan field mapping yang sesuai + lead_vals = { + 'name': self._generate_lead_name(contact_data, contact), + 'phone': phone, # Phone Number → Mobile + 'contact_name': contact_data.get('name', ''), # Name → Contact Name + 'partner_name': contact_data.get('perusahaan', ''), # Perusahaan → Company Name + 'email_from': contact_data.get('email', ''), # Email → Email + 'description': contact_data.get('notes', ''), # Notes → Internal Notes + 'type': 'lead', + 'user_id': self._get_salesperson_id(contact_data.get('sales', '')), # Sales → Salesperson + } + + new_lead = self.env['crm.lead'].create(lead_vals) + _logger.info('Created WATI lead %s for %s (%s)' % (new_lead.id, contact_data.get('name', 'Unknown'), phone)) + return True + + except Exception as e: + _logger.error('Error creating lead: %s' % str(e)) + return False + + def _extract_contact_data(self, custom_params): + """Extract data dari customParams sesuai mapping table""" + contact_data = {} + + for param in custom_params: + param_name = param.get('name', '').lower() + param_value = param.get('value', '').strip() + + # Mapping sesuai table: + if param_name == 'perusahaan': # Perusahaan → Company Name + contact_data['perusahaan'] = param_value + elif param_name == 'name': # Name → Contact Name + contact_data['name'] = param_value + elif param_name == 'email': # Email → Email + contact_data['email'] = param_value + elif param_name == 'sales': # Sales → Salesperson + contact_data['sales'] = param_value + elif param_name == 'notes': # Notes → Internal Notes + contact_data['notes'] = param_value + # Phone Number sudah diambil dari contact.phone + + return contact_data + + def _generate_lead_name(self, contact_data, contact): + """Generate lead name sesuai mapping: Judul Leads berdasarkan company/contact""" + company_name = contact_data.get('perusahaan', '') + contact_name = contact_data.get('name', '') or contact.get('name', '') + + if company_name: + return 'WATI Lead - %s' % company_name + elif contact_name: + return 'WATI Lead - %s' % contact_name + else: + return 'WATI Lead - %s' % contact.get('phone', 'Unknown') + + def _get_salesperson_id(self, sales_name): + """Get salesperson ID dari nama - Sales → Salesperson""" + if not sales_name: + return 2 # Default Sales (ID 2) + + # Try find user by name + user = self.env['res.users'].search([ + ('name', 'ilike', sales_name) + ], limit=1) + + if user: + return user.id + else: + # Fallback ke default Sales + return 2 + + def _has_tags_leads(self, contact): + """Check apakah ada tags untuk tajik ke odoo => Leads""" + custom_params = contact.get('customParams', []) + + for param in custom_params: + param_name = param.get('name', '').lower() + param_value = param.get('value', '').lower() + + # Check: "Judul Tags untuk tajik ke odoo => Leads" + if param_name == 'tags' and param_value == 'leads': + return True + + return False + + def manual_check_tags(self): + """Manual trigger untuk testing""" + result = self.check_wati_tags_leads() + + message = 'WATI Tags Check Completed!\n\n' + message += 'Leads Created: %s\n\n' % result.get('leads_created', 0) + message += 'Field Mapping:\n' + message += '• Perusahaan → Company Name\n' + message += '• Name → Contact Name\n' + message += '• Email → Email\n' + message += '• Sales → Salesperson\n' + message += '• Phone Number → Mobile\n' + message += '• Notes → Internal Notes\n' + message += '• Tags=leads → Trigger Lead Creation' + + if result.get('error'): + message += '\n\nError: %s' % result['error'] + message_type = 'warning' + else: + message_type = 'success' + + return { + 'type': 'ir.actions.client', + 'tag': 'display_notification', + 'params': { + 'title': 'WATI Tags Check', + 'message': message, + 'type': message_type, + 'sticky': True, + } + } class WatiHistory(models.Model): _name = 'wati.history' @@ -319,4 +483,4 @@ class WatiHistoryLine(models.Model): ticket_id = fields.Char(string='Ticket ID') type = fields.Char(string='Type') wa_id = fields.Char(string='WA ID') - date_wati = fields.Datetime(string='Date WATI') + date_wati = fields.Datetime(string='Date WATI')
\ No newline at end of file |
