This commit is contained in:
debu-2 2026-10-02 22:39:04 +05:30
parent d272ae0bd3
commit ff01efe4bb
17 changed files with 1378 additions and 21 deletions

View file

@ -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.",
],
}