feat: Implement Akte webhook for EspoCRM to queue entity IDs for synchronization

fix: Refactor Akte sync logic to handle multiple Redis queues and improve logging
refactor: Enhance parameter flattening for EspoCRM API calls
This commit is contained in:
bsiggel
2026-03-26 09:48:46 +00:00
parent b4d35b1790
commit 3459b9342f
6 changed files with 278 additions and 127 deletions

View File

@@ -162,11 +162,33 @@ class EspoCRMAPI:
self._log(f"⚠️ Could not load entity def for {entity_type}: {e}", level='warn')
return {}
@staticmethod
def _flatten_params(data, prefix: str = '') -> list:
"""
Flatten nested dict/list into PHP-style repeated query params.
EspoCRM expects where[0][type]=equals&where[0][attribute]=x format.
"""
result = []
if isinstance(data, dict):
for k, v in data.items():
new_key = f"{prefix}[{k}]" if prefix else str(k)
result.extend(EspoCRMAPI._flatten_params(v, new_key))
elif isinstance(data, (list, tuple)):
for i, v in enumerate(data):
result.extend(EspoCRMAPI._flatten_params(v, f"{prefix}[{i}]"))
elif isinstance(data, bool):
result.append((prefix, 'true' if data else 'false'))
elif data is None:
result.append((prefix, ''))
else:
result.append((prefix, str(data)))
return result
async def api_call(
self,
endpoint: str,
method: str = 'GET',
params: Optional[Dict] = None,
params=None,
json_data: Optional[Dict] = None,
timeout_seconds: Optional[int] = None
) -> Any:
@@ -292,22 +314,22 @@ class EspoCRMAPI:
Returns:
Dict with 'list' and 'total' keys
"""
params = {
search_params: Dict[str, Any] = {
'offset': offset,
'maxSize': max_size
'maxSize': max_size,
}
if where:
import json
# EspoCRM expects JSON-encoded where clause
params['where'] = where if isinstance(where, str) else json.dumps(where)
search_params['where'] = where
if select:
params['select'] = select
search_params['select'] = select
if order_by:
params['orderBy'] = order_by
search_params['orderBy'] = order_by
self._log(f"Listing {entity_type} entities")
return await self.api_call(f"/{entity_type}", method='GET', params=params)
return await self.api_call(
f"/{entity_type}", method='GET',
params=self._flatten_params(search_params)
)
async def list_related(
self,
@@ -321,23 +343,24 @@ class EspoCRMAPI:
offset: int = 0,
max_size: int = 50
) -> Dict[str, Any]:
params = {
search_params: Dict[str, Any] = {
'offset': offset,
'maxSize': max_size
'maxSize': max_size,
}
if where:
import json
params['where'] = where if isinstance(where, str) else json.dumps(where)
search_params['where'] = where
if select:
params['select'] = select
search_params['select'] = select
if order_by:
params['orderBy'] = order_by
search_params['orderBy'] = order_by
if order:
params['order'] = order
search_params['order'] = order
self._log(f"Listing related {entity_type}/{entity_id}/{link}")
return await self.api_call(f"/{entity_type}/{entity_id}/{link}", method='GET', params=params)
return await self.api_call(
f"/{entity_type}/{entity_id}/{link}", method='GET',
params=self._flatten_params(search_params)
)
async def create_entity(
self,