reports
This commit is contained in:
parent
d272ae0bd3
commit
ff01efe4bb
17 changed files with 1378 additions and 21 deletions
|
|
@ -22,6 +22,7 @@ class SendAgentMessagePayload(BaseModel):
|
|||
template: str = Field(min_length=2, max_length=64)
|
||||
to: str = Field(min_length=10, max_length=20)
|
||||
customer_name: str = Field(min_length=1, max_length=120)
|
||||
report_group: str = Field(min_length=3, max_length=50)
|
||||
report_id: str | None = Field(default=None, max_length=120)
|
||||
|
||||
|
||||
|
|
@ -72,6 +73,18 @@ def require_subscription(db: Session, user: UserAccount, template: AgentMessageT
|
|||
return subscription
|
||||
|
||||
|
||||
def _validate_report_group(report_group: str) -> str:
|
||||
cleaned = report_group.strip().lower()
|
||||
if not cleaned or len(cleaned) > 50:
|
||||
raise HTTPException(status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail="Invalid report_group")
|
||||
if not re.fullmatch(r"[a-z][a-z0-9-]{1,48}[a-z0-9]", cleaned) or "--" in cleaned:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
|
||||
detail="report_group must be 3-50 chars: lowercase letters, numbers, hyphens",
|
||||
)
|
||||
return cleaned
|
||||
|
||||
|
||||
def _validate_report_id(report_id: str) -> str:
|
||||
cleaned = report_id.strip()
|
||||
if not cleaned or len(cleaned) > 120:
|
||||
|
|
@ -84,7 +97,12 @@ def _validate_report_id(report_id: str) -> str:
|
|||
return cleaned
|
||||
|
||||
|
||||
def _build_template_components(template: AgentMessageTemplate, customer_name: str, report_id: str) -> list[dict]:
|
||||
def _build_template_components(
|
||||
template: AgentMessageTemplate,
|
||||
customer_name: str,
|
||||
report_group: str,
|
||||
report_id: str,
|
||||
) -> list[dict]:
|
||||
components: list[dict] = [
|
||||
{
|
||||
"type": "body",
|
||||
|
|
@ -103,7 +121,7 @@ def _build_template_components(template: AgentMessageTemplate, customer_name: st
|
|||
"type": "button",
|
||||
"sub_type": "url",
|
||||
"index": "0",
|
||||
"parameters": [{"type": "text", "text": report_id}],
|
||||
"parameters": [{"type": "text", "text": f"{report_group}/{report_id}"}],
|
||||
}
|
||||
)
|
||||
return components
|
||||
|
|
@ -128,8 +146,9 @@ async def send_agent_template_message(
|
|||
except ValueError as exc:
|
||||
raise HTTPException(status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail=str(exc)) from exc
|
||||
|
||||
report_group = _validate_report_group(payload.report_group)
|
||||
report_id = _validate_report_id(payload.report_id or f"run-{secrets.token_hex(3)}")
|
||||
components = _build_template_components(template, payload.customer_name, report_id)
|
||||
components = _build_template_components(template, payload.customer_name, report_group, report_id)
|
||||
|
||||
client = _whatsapp_client(db)
|
||||
try:
|
||||
|
|
@ -149,6 +168,7 @@ async def send_agent_template_message(
|
|||
recipient=recipient,
|
||||
parameters={
|
||||
"customer_name": payload.customer_name.strip(),
|
||||
"report_group": report_group,
|
||||
"report_id": report_id,
|
||||
},
|
||||
wa_message_id=wa_message_id,
|
||||
|
|
@ -159,12 +179,17 @@ async def send_agent_template_message(
|
|||
db.commit()
|
||||
db.refresh(log)
|
||||
|
||||
report_url = f"{template.button_url_base.rstrip('/')}/{report_id}" if template.button_url_base else None
|
||||
report_url = (
|
||||
f"{template.button_url_base.rstrip('/')}/{report_group}/{report_id}"
|
||||
if template.button_url_base
|
||||
else None
|
||||
)
|
||||
return {
|
||||
"success": True,
|
||||
"template": template.slug,
|
||||
"to": recipient,
|
||||
"customer_name": payload.customer_name.strip(),
|
||||
"report_group": report_group,
|
||||
"report_id": report_id,
|
||||
"report_url": report_url,
|
||||
"wa_message_id": wa_message_id,
|
||||
|
|
@ -201,6 +226,7 @@ async def run_console_template_test(
|
|||
*,
|
||||
to: str,
|
||||
customer_name: str,
|
||||
report_group: str,
|
||||
report_id: str | None = None,
|
||||
) -> dict:
|
||||
require_subscription(db, user, template)
|
||||
|
|
@ -215,6 +241,7 @@ async def run_console_template_test(
|
|||
template=template.slug,
|
||||
to=to,
|
||||
customer_name=customer_name,
|
||||
report_group=report_group,
|
||||
report_id=report_id,
|
||||
)
|
||||
result = await send_agent_template_message(db, user, payload, source="console_test")
|
||||
|
|
@ -250,12 +277,14 @@ def build_agent_message_docs(template: AgentMessageTemplate) -> dict:
|
|||
"template": f"Template slug. Use `{template.slug}`.",
|
||||
"to": "Recipient WhatsApp number with country code, e.g. 919149154337",
|
||||
"customer_name": "Recipient name inserted into the template body",
|
||||
"report_id": "Optional unique report id for the View Report button URL suffix",
|
||||
"report_group": "Urmiport report group slug used in the hosted report URL",
|
||||
"report_id": "Optional report postfix; auto-generated when omitted",
|
||||
},
|
||||
"example": {
|
||||
"template": template.slug,
|
||||
"to": "919149154337",
|
||||
"customer_name": "Suyash",
|
||||
"report_group": "acme-agent-runs",
|
||||
"report_id": "run-abc123",
|
||||
},
|
||||
"response_example": {
|
||||
|
|
@ -263,8 +292,9 @@ def build_agent_message_docs(template: AgentMessageTemplate) -> dict:
|
|||
"template": template.slug,
|
||||
"to": "919149154337",
|
||||
"customer_name": "Suyash",
|
||||
"report_group": "acme-agent-runs",
|
||||
"report_id": "run-abc123",
|
||||
"report_url": f"{template.button_url_base or ''}run-abc123",
|
||||
"report_url": f"{template.button_url_base or ''}acme-agent-runs/run-abc123",
|
||||
"wa_message_id": "wamid.HBg...",
|
||||
"dispatch_id": "00000000-0000-0000-0000-000000000001",
|
||||
},
|
||||
|
|
@ -272,6 +302,7 @@ def build_agent_message_docs(template: AgentMessageTemplate) -> dict:
|
|||
"notes": [
|
||||
"Subscribe to the template in the Urmi console before calling this API.",
|
||||
"Messages are sent from the Urmi AI WhatsApp business number on your behalf.",
|
||||
"If report_id is omitted, Urmi generates a unique id automatically.",
|
||||
"Create the report group in Console → Agent → Urmiport before sending.",
|
||||
"If report_id is omitted, Urmi generates a unique postfix automatically.",
|
||||
],
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue