Conversation
There was a problem hiding this comment.
Pull Request Overview
This PR adds CRM lead management functionality that extracts contact information from audio transcripts and creates leads in an Odoo CRM system. The implementation includes detailed contact field extraction using LLM-based parsing, Odoo XML-RPC client integration, and API endpoints for managing CRM lead data.
- Implements an advanced contact information extraction system using Ollama LLM with detailed prompts and fallback regex patterns
- Adds Odoo CRM client integration with lead creation, contact management, and address handling capabilities
- Introduces API endpoints for uploading CRM audio files and retrieving CRM lead data with Next.js backend integration
Reviewed Changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 6 comments.
| File | Description |
|---|---|
| service/summarizer.py | Adds comprehensive contact extraction function with LLM-based parsing and regex fallbacks |
| service/main.py | Implements CRM audio upload endpoint and CRM lead management API routes |
| service/crm_client.py | Creates new Odoo XML-RPC client for CRM operations |
| service/config.py | Adds Odoo configuration variables and updates default Ollama host |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
service/summarizer.py
Outdated
| return { | ||
| "name": extracted_name, | ||
| "phone": re.search(r'(\d{3}[-\.\s]?\d{3}[-\.\s]?\d{4})', text).group(1).replace('-', '') if re.search(r'(\d{3}[-\.\s]?\d{3}[-\.\s]?\d{4})', text) else None, |
There was a problem hiding this comment.
The regex pattern is compiled and executed twice. Store the match result in a variable to avoid duplicate regex operations: phone_match = re.search(r'(\d{3}[-\.\s]?\d{3}[-\.\s]?\d{4})', text) then use phone_match.group(1).replace('-', '') if phone_match else None.
| return { | |
| "name": extracted_name, | |
| "phone": re.search(r'(\d{3}[-\.\s]?\d{3}[-\.\s]?\d{4})', text).group(1).replace('-', '') if re.search(r'(\d{3}[-\.\s]?\d{3}[-\.\s]?\d{4})', text) else None, | |
| phone_match = re.search(r'(\d{3}[-\.\s]?\d{3}[-\.\s]?\d{4})', text) | |
| return { | |
| "name": extracted_name, | |
| "phone": phone_match.group(1).replace('-', '') if phone_match else None, |
service/main.py
Outdated
| response = requests.post( | ||
| f"{api_base_url}/api/crm-leads", | ||
| json=crm_lead_data, | ||
| headers={"Content-Type": "application/json"} |
There was a problem hiding this comment.
Missing timeout parameter for the HTTP request. Add a timeout to prevent the request from hanging indefinitely: requests.post(..., timeout=30).
| headers={"Content-Type": "application/json"} | |
| headers={"Content-Type": "application/json"}, | |
| timeout=30 |
| response = requests.get( | ||
| f"{api_base_url}/api/crm-leads/default", | ||
| headers={"Content-Type": "application/json"} | ||
| ) |
There was a problem hiding this comment.
Missing timeout parameter for the HTTP request. Add a timeout to prevent the request from hanging indefinitely: requests.get(..., timeout=30).
service/main.py
Outdated
|
|
||
| response = requests.get( | ||
| simple_url, | ||
| headers={"Content-Type": "application/json"} |
There was a problem hiding this comment.
Missing timeout parameter for the HTTP request. Add a timeout to prevent the request from hanging indefinitely: requests.get(..., timeout=30).
| headers={"Content-Type": "application/json"} | |
| headers={"Content-Type": "application/json"}, | |
| timeout=30 |
| self.common = xmlrpc.client.ServerProxy(f"{url}/xmlrpc/2/common", allow_none=True) | ||
| self.uid = self.common.authenticate(db, username, password, {}) | ||
| if not self.uid: | ||
| raise Exception("Authentication failed. Check credentials or DB name.") | ||
| self.models = xmlrpc.client.ServerProxy(f"{url}/xmlrpc/2/object", allow_none=True) |
There was a problem hiding this comment.
The authentication credentials are passed in plain text and stored in instance variables. Consider implementing secure credential handling and avoid storing sensitive data in class attributes.
service/crm_client.py
Outdated
| self.common = xmlrpc.client.ServerProxy(f"{url}/xmlrpc/2/common", allow_none=True) | ||
| self.uid = self.common.authenticate(db, username, password, {}) | ||
| if not self.uid: | ||
| raise Exception("Authentication failed. Check credentials or DB name.") |
There was a problem hiding this comment.
Generic Exception should be replaced with a more specific exception type, such as AuthenticationError or ConnectionError, to provide better error handling context.
Summary by Bito
This pull request introduces new features for managing CRM leads through the Odoo client, including the OdooCRMClient class for lead management, enhanced service integration, and improved contact extraction capabilities using a language model. It also updates the configuration for Odoo connection parameters and adds endpoints for lead retrieval and audio file uploads.