Release v4928.1.4.2 stable

This commit is contained in:
2026-06-09 22:55:58 +01:00
commit 6445044ac6
280 changed files with 41775 additions and 0 deletions

94
app/chatwoot_client.py Normal file
View File

@@ -0,0 +1,94 @@
from typing import Dict
import httpx
from app.config import settings
from app.posting_policy import can_post_private_note
from app.schemas import ActionResult
import os
def build_private_note(action_result: ActionResult) -> str:
return f"""🤖 ClientFlow
Ação:
{action_result.action}
Resumo:
{action_result.note}
"""
async def add_private_note(
conversation_id: str,
action_result: ActionResult,
) -> Dict:
if os.getenv("CLIENTFLOW_DISABLE_CHATWOOT_PRIVATE_NOTES", "true").lower() in {"1", "true", "yes", "sim"}:
return {
"enabled": False,
"status": "disabled_by_env",
"reason": "CLIENTFLOW_DISABLE_CHATWOOT_PRIVATE_NOTES=true",
}
if not settings.chatwoot_write_enabled:
return {
"enabled": False,
"status": "skipped",
"reason": "CHATWOOT_WRITE_ENABLED=false",
"action_result": action_result.model_dump(),
}
if not can_post_private_note(action_result):
return {
"enabled": True,
"status": "skipped",
"reason": "posting_policy_blocked",
"action_result": action_result.model_dump(),
}
if not settings.chatwoot_base_url or not settings.chatwoot_account_id or not settings.chatwoot_api_token:
return {
"enabled": True,
"status": "skipped",
"reason": "missing Chatwoot config",
"action_result": action_result.model_dump(),
}
url = (
settings.chatwoot_base_url.rstrip("/")
+ f"/api/v1/accounts/{settings.chatwoot_account_id}"
+ f"/conversations/{conversation_id}/messages"
)
payload = {
"content": build_private_note(action_result),
"message_type": "outgoing",
"private": True,
"content_type": "text",
"content_attributes": {},
}
headers = {
"Content-Type": "application/json",
"api_access_token": settings.chatwoot_api_token,
}
async with httpx.AsyncClient(timeout=30) as client:
response = await client.post(url, headers=headers, json=payload)
if response.status_code >= 400:
return {
"enabled": True,
"status": "failed",
"status_code": response.status_code,
"body": response.text,
"action_result": action_result.model_dump(),
}
return {
"enabled": True,
"status": "sent",
"status_code": response.status_code,
"response": response.json(),
"action_result": action_result.model_dump(),
}