whatsapp fixes
This commit is contained in:
parent
ff01efe4bb
commit
248acba741
5 changed files with 425 additions and 38 deletions
|
|
@ -24,6 +24,7 @@ class SendAgentMessagePayload(BaseModel):
|
||||||
customer_name: str = Field(min_length=1, max_length=120)
|
customer_name: str = Field(min_length=1, max_length=120)
|
||||||
report_group: str = Field(min_length=3, max_length=50)
|
report_group: str = Field(min_length=3, max_length=50)
|
||||||
report_id: str | None = Field(default=None, max_length=120)
|
report_id: str | None = Field(default=None, max_length=120)
|
||||||
|
report_url: str | None = Field(default=None, max_length=500)
|
||||||
|
|
||||||
|
|
||||||
def serialize_agent_template(template: AgentMessageTemplate, *, subscribed: bool = False) -> dict:
|
def serialize_agent_template(template: AgentMessageTemplate, *, subscribed: bool = False) -> dict:
|
||||||
|
|
@ -97,31 +98,46 @@ def _validate_report_id(report_id: str) -> str:
|
||||||
return cleaned
|
return cleaned
|
||||||
|
|
||||||
|
|
||||||
|
def _build_report_url(
|
||||||
|
template: AgentMessageTemplate,
|
||||||
|
report_group: str,
|
||||||
|
report_id: str,
|
||||||
|
override: str | None = None,
|
||||||
|
) -> str:
|
||||||
|
if override:
|
||||||
|
return override.strip()
|
||||||
|
base = (template.button_url_base or "https://urmiai.com/reports/").rstrip("/")
|
||||||
|
return f"{base}/{report_group}/{report_id}"
|
||||||
|
|
||||||
|
|
||||||
def _build_template_components(
|
def _build_template_components(
|
||||||
template: AgentMessageTemplate,
|
template: AgentMessageTemplate,
|
||||||
customer_name: str,
|
customer_name: str,
|
||||||
report_group: str,
|
report_url: str,
|
||||||
report_id: str,
|
|
||||||
) -> list[dict]:
|
) -> list[dict]:
|
||||||
|
"""Build Meta template components using positional variables.
|
||||||
|
|
||||||
|
agent_run_completion uses:
|
||||||
|
body {{1}} -> customer name
|
||||||
|
button {{1}} -> report URL path suffix OR full URL depending on Meta template config.
|
||||||
|
We pass the full hosted report URL for the button so the View Report link resolves correctly.
|
||||||
|
"""
|
||||||
components: list[dict] = [
|
components: list[dict] = [
|
||||||
{
|
{
|
||||||
"type": "body",
|
"type": "body",
|
||||||
"parameters": [
|
"parameters": [{"type": "text", "text": customer_name.strip()}],
|
||||||
{
|
|
||||||
"type": "text",
|
|
||||||
"parameter_name": "customer_name",
|
|
||||||
"text": customer_name.strip(),
|
|
||||||
}
|
|
||||||
],
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
if template.button_label and template.button_url_base:
|
if template.button_label and template.button_url_base:
|
||||||
|
# Meta URL button: pass path suffix relative to button_url_base (e.g. desi-clans-test/2026-10-03)
|
||||||
|
base = template.button_url_base.rstrip("/")
|
||||||
|
button_param = report_url[len(base) + 1 :] if report_url.startswith(f"{base}/") else report_url
|
||||||
components.append(
|
components.append(
|
||||||
{
|
{
|
||||||
"type": "button",
|
"type": "button",
|
||||||
"sub_type": "url",
|
"sub_type": "url",
|
||||||
"index": "0",
|
"index": "0",
|
||||||
"parameters": [{"type": "text", "text": f"{report_group}/{report_id}"}],
|
"parameters": [{"type": "text", "text": button_param}],
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
return components
|
return components
|
||||||
|
|
@ -148,7 +164,8 @@ async def send_agent_template_message(
|
||||||
|
|
||||||
report_group = _validate_report_group(payload.report_group)
|
report_group = _validate_report_group(payload.report_group)
|
||||||
report_id = _validate_report_id(payload.report_id or f"run-{secrets.token_hex(3)}")
|
report_id = _validate_report_id(payload.report_id or f"run-{secrets.token_hex(3)}")
|
||||||
components = _build_template_components(template, payload.customer_name, report_group, report_id)
|
report_url = _build_report_url(template, report_group, report_id, payload.report_url)
|
||||||
|
components = _build_template_components(template, payload.customer_name, report_url)
|
||||||
|
|
||||||
client = _whatsapp_client(db)
|
client = _whatsapp_client(db)
|
||||||
try:
|
try:
|
||||||
|
|
@ -170,6 +187,7 @@ async def send_agent_template_message(
|
||||||
"customer_name": payload.customer_name.strip(),
|
"customer_name": payload.customer_name.strip(),
|
||||||
"report_group": report_group,
|
"report_group": report_group,
|
||||||
"report_id": report_id,
|
"report_id": report_id,
|
||||||
|
"report_url": report_url,
|
||||||
},
|
},
|
||||||
wa_message_id=wa_message_id,
|
wa_message_id=wa_message_id,
|
||||||
status="sent",
|
status="sent",
|
||||||
|
|
@ -179,11 +197,6 @@ async def send_agent_template_message(
|
||||||
db.commit()
|
db.commit()
|
||||||
db.refresh(log)
|
db.refresh(log)
|
||||||
|
|
||||||
report_url = (
|
|
||||||
f"{template.button_url_base.rstrip('/')}/{report_group}/{report_id}"
|
|
||||||
if template.button_url_base
|
|
||||||
else None
|
|
||||||
)
|
|
||||||
return {
|
return {
|
||||||
"success": True,
|
"success": True,
|
||||||
"template": template.slug,
|
"template": template.slug,
|
||||||
|
|
@ -279,22 +292,24 @@ def build_agent_message_docs(template: AgentMessageTemplate) -> dict:
|
||||||
"customer_name": "Recipient name inserted into the template body",
|
"customer_name": "Recipient name inserted into the template body",
|
||||||
"report_group": "Urmiport report group slug used in the hosted report URL",
|
"report_group": "Urmiport report group slug used in the hosted report URL",
|
||||||
"report_id": "Optional report postfix; auto-generated when omitted",
|
"report_id": "Optional report postfix; auto-generated when omitted",
|
||||||
|
"report_url": "Optional full report URL override for the WhatsApp button (auto-built when omitted)",
|
||||||
},
|
},
|
||||||
"example": {
|
"example": {
|
||||||
"template": template.slug,
|
"template": template.slug,
|
||||||
"to": "919149154337",
|
"to": "919149154337",
|
||||||
"customer_name": "Suyash",
|
"customer_name": "Suyash",
|
||||||
"report_group": "acme-agent-runs",
|
"report_group": "desi-clans-test",
|
||||||
"report_id": "run-abc123",
|
"report_id": "2026-10-03",
|
||||||
|
"report_url": "https://urmiai.com/reports/desi-clans-test/2026-10-03",
|
||||||
},
|
},
|
||||||
"response_example": {
|
"response_example": {
|
||||||
"success": True,
|
"success": True,
|
||||||
"template": template.slug,
|
"template": template.slug,
|
||||||
"to": "919149154337",
|
"to": "919149154337",
|
||||||
"customer_name": "Suyash",
|
"customer_name": "Suyash",
|
||||||
"report_group": "acme-agent-runs",
|
"report_group": "desi-clans-test",
|
||||||
"report_id": "run-abc123",
|
"report_id": "2026-10-03",
|
||||||
"report_url": f"{template.button_url_base or ''}acme-agent-runs/run-abc123",
|
"report_url": "https://urmiai.com/reports/desi-clans-test/2026-10-03",
|
||||||
"wa_message_id": "wamid.HBg...",
|
"wa_message_id": "wamid.HBg...",
|
||||||
"dispatch_id": "00000000-0000-0000-0000-000000000001",
|
"dispatch_id": "00000000-0000-0000-0000-000000000001",
|
||||||
},
|
},
|
||||||
|
|
@ -304,5 +319,6 @@ def build_agent_message_docs(template: AgentMessageTemplate) -> dict:
|
||||||
"Messages are sent from the Urmi AI WhatsApp business number on your behalf.",
|
"Messages are sent from the Urmi AI WhatsApp business number on your behalf.",
|
||||||
"Create the report group in Console → Agent → Urmiport before sending.",
|
"Create the report group in Console → Agent → Urmiport before sending.",
|
||||||
"If report_id is omitted, Urmi generates a unique postfix automatically.",
|
"If report_id is omitted, Urmi generates a unique postfix automatically.",
|
||||||
|
"The WhatsApp button uses positional template variables: body {{1}} = customer_name, button suffix = report_group/report_id.",
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,25 +22,18 @@ DEFAULT_AGENT_TEMPLATES = [
|
||||||
"category": "utility",
|
"category": "utility",
|
||||||
"parameters": [
|
"parameters": [
|
||||||
{
|
{
|
||||||
"name": "customer_name",
|
"name": "{{1}}",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"required": True,
|
"required": True,
|
||||||
"description": "Recipient display name shown in the greeting",
|
"description": "Positional body variable — recipient display name",
|
||||||
"example": "Suyash",
|
"example": "Suyash",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "report_group",
|
"name": "{{2}}",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"required": True,
|
"required": True,
|
||||||
"description": "Urmiport report group slug used in the hosted report URL",
|
"description": "Positional button variable — report path suffix (report_group/report_id)",
|
||||||
"example": "acme-agent-runs",
|
"example": "desi-clans-test/2026-10-03",
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "report_id",
|
|
||||||
"type": "string",
|
|
||||||
"required": True,
|
|
||||||
"description": "Report postfix appended after the report group in the View Report button URL",
|
|
||||||
"example": "run-abc123",
|
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
"button_label": "View Report",
|
"button_label": "View Report",
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,13 @@ def _explorer_doc_for_template(template: AgentMessageTemplate) -> dict:
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"required": False,
|
"required": False,
|
||||||
"description": "Report postfix; auto-generated when omitted",
|
"description": "Report postfix; auto-generated when omitted",
|
||||||
"example": "run-abc123",
|
"example": "2026-10-03",
|
||||||
|
},
|
||||||
|
"report_url": {
|
||||||
|
"type": "string",
|
||||||
|
"required": False,
|
||||||
|
"description": "Full hosted report URL for the WhatsApp button; auto-built when omitted",
|
||||||
|
"example": "https://urmiai.com/reports/desi-clans-test/2026-10-03",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"responses": {
|
"responses": {
|
||||||
|
|
@ -66,9 +72,9 @@ def _explorer_doc_for_template(template: AgentMessageTemplate) -> dict:
|
||||||
"template": template.slug,
|
"template": template.slug,
|
||||||
"to": "919149154337",
|
"to": "919149154337",
|
||||||
"customer_name": "Suyash",
|
"customer_name": "Suyash",
|
||||||
"report_group": "acme-agent-runs",
|
"report_group": "desi-clans-test",
|
||||||
"report_id": "run-abc123",
|
"report_id": "2026-10-03",
|
||||||
"report_url": f"{template.button_url_base or ''}acme-agent-runs/run-abc123",
|
"report_url": "https://urmiai.com/reports/desi-clans-test/2026-10-03",
|
||||||
"wa_message_id": "wamid.HBg...",
|
"wa_message_id": "wamid.HBg...",
|
||||||
"dispatch_id": "00000000-0000-0000-0000-000000000001",
|
"dispatch_id": "00000000-0000-0000-0000-000000000001",
|
||||||
},
|
},
|
||||||
|
|
|
||||||
365
docs/URMIPORT_AND_WHATSAPP_APIS.md
Normal file
365
docs/URMIPORT_AND_WHATSAPP_APIS.md
Normal file
|
|
@ -0,0 +1,365 @@
|
||||||
|
# Urmiport & Agent WhatsApp APIs
|
||||||
|
|
||||||
|
This document describes the two APIs used together to **host an HTML report** and **notify a user on WhatsApp** with a link to that report.
|
||||||
|
|
||||||
|
| API | Purpose |
|
||||||
|
|-----|---------|
|
||||||
|
| **Urmiport — Publish report** | Create or update a hosted HTML report |
|
||||||
|
| **Agent messages — Send WhatsApp** | Send an approved WhatsApp template with a dynamic View Report button |
|
||||||
|
|
||||||
|
**Base URL:** `https://urmiai.com`
|
||||||
|
|
||||||
|
**Authentication:** Urmi API key in every request
|
||||||
|
|
||||||
|
```http
|
||||||
|
Authorization: Bearer urmi_live_<your_api_key>
|
||||||
|
```
|
||||||
|
|
||||||
|
Alternate header: `X-Api-Key: urmi_live_<your_api_key>`
|
||||||
|
|
||||||
|
Create API keys in the Urmi console: **Develop → API Keys**.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## End-to-end flow
|
||||||
|
|
||||||
|
```text
|
||||||
|
1. Console → Agent → Urmiport
|
||||||
|
Create a report group (e.g. desi-clans-test)
|
||||||
|
|
||||||
|
2. Console → Agent → UrmiAI
|
||||||
|
Subscribe to the agent_run_completion template
|
||||||
|
|
||||||
|
3. POST /api/v1/urmiport/reports
|
||||||
|
Publish HTML for report_group + report_id
|
||||||
|
|
||||||
|
4. POST /api/v1/agent/messages/send
|
||||||
|
Send WhatsApp message; button links to the hosted report
|
||||||
|
|
||||||
|
5. User opens
|
||||||
|
https://urmiai.com/reports/{report_group}/{report_id}
|
||||||
|
```
|
||||||
|
|
||||||
|
Typical order: **publish the report first**, then **send the WhatsApp message** so the link is live when the user taps View Report.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Prerequisites (console setup)
|
||||||
|
|
||||||
|
### 1. Create a report group
|
||||||
|
|
||||||
|
**Console → Agent → Urmiport → New report group**
|
||||||
|
|
||||||
|
| Setting | Description |
|
||||||
|
|---------|-------------|
|
||||||
|
| **Report group** | URL slug, 3–50 chars, lowercase letters, numbers, hyphens (e.g. `desi-clans-test`) |
|
||||||
|
| **Default access** | `public` or `password` |
|
||||||
|
| **Report ID mode** | `auto` — Urmi generates `report_id` when omitted; `manual` — you must send `report_id` in the API |
|
||||||
|
|
||||||
|
Hosted URL pattern:
|
||||||
|
|
||||||
|
```text
|
||||||
|
https://urmiai.com/reports/{report_group}/{report_id}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Subscribe to the WhatsApp template
|
||||||
|
|
||||||
|
**Console → Agent → UrmiAI**
|
||||||
|
|
||||||
|
Subscribe to **`agent_run_completion`** (display name: *Agent Run Success*).
|
||||||
|
|
||||||
|
Messages are sent from the Urmi AI WhatsApp Business number on your behalf.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## API 1 — Publish Urmiport HTML report
|
||||||
|
|
||||||
|
Create or update a hosted HTML report. The public page renders **only your HTML** — no Urmi branding or chrome.
|
||||||
|
|
||||||
|
### Endpoint
|
||||||
|
|
||||||
|
```http
|
||||||
|
POST /api/v1/urmiport/reports
|
||||||
|
Content-Type: application/json
|
||||||
|
Authorization: Bearer urmi_live_<your_api_key>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Request body
|
||||||
|
|
||||||
|
| Field | Required | Type | Description |
|
||||||
|
|-------|----------|------|-------------|
|
||||||
|
| `report_group` | Yes | string | Report group slug created in Urmiport (e.g. `desi-clans-test`) |
|
||||||
|
| `body` | Yes | string | Full HTML document or fragment (email-style HTML is supported) |
|
||||||
|
| `report_id` | Conditional | string | Report postfix. **Required** when the group uses manual ID mode; optional for auto groups |
|
||||||
|
| `access` | No | string | `public` (default) or `password` |
|
||||||
|
| `password` | Conditional | string | Required when `access` is `password`, unless the group already has a default password |
|
||||||
|
|
||||||
|
### Validation rules
|
||||||
|
|
||||||
|
- **report_group:** 3–50 chars, lowercase `a-z`, `0-9`, hyphens; must already exist in your account
|
||||||
|
- **report_id:** letters, numbers, dots, underscores, hyphens; max 120 chars
|
||||||
|
- **Upsert:** same `report_group` + `report_id` updates the existing HTML body
|
||||||
|
|
||||||
|
### Example — public report (manual report ID)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X POST 'https://urmiai.com/api/v1/urmiport/reports' \
|
||||||
|
-H 'Authorization: Bearer urmi_live_<your_api_key>' \
|
||||||
|
-H 'Content-Type: application/json' \
|
||||||
|
-d '{
|
||||||
|
"report_group": "desi-clans-test",
|
||||||
|
"report_id": "desi-clans-demo-v1",
|
||||||
|
"access": "public",
|
||||||
|
"body": "<html><body><h1>Agent run complete</h1><p>All checks passed.</p></body></html>"
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
|
||||||
|
### Example — password-protected report
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X POST 'https://urmiai.com/api/v1/urmiport/reports' \
|
||||||
|
-H 'Authorization: Bearer urmi_live_<your_api_key>' \
|
||||||
|
-H 'Content-Type: application/json' \
|
||||||
|
-d '{
|
||||||
|
"report_group": "desi-clans-test",
|
||||||
|
"report_id": "run-confidential-001",
|
||||||
|
"access": "password",
|
||||||
|
"password": "my-secret-pass",
|
||||||
|
"body": "<html><body><h1>Confidential report</h1></body></html>"
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
|
||||||
|
### Example — auto-generated report ID
|
||||||
|
|
||||||
|
When the report group uses **auto** ID mode, omit `report_id`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X POST 'https://urmiai.com/api/v1/urmiport/reports' \
|
||||||
|
-H 'Authorization: Bearer urmi_live_<your_api_key>' \
|
||||||
|
-H 'Content-Type: application/json' \
|
||||||
|
-d '{
|
||||||
|
"report_group": "acme-agent-runs",
|
||||||
|
"access": "public",
|
||||||
|
"body": "<html><body><h1>Run complete</h1></body></html>"
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
|
||||||
|
Urmi returns a generated `report_id` such as `run-a1b2c3`.
|
||||||
|
|
||||||
|
### Success response `200 OK`
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"success": true,
|
||||||
|
"id": "11926afa-c648-48f2-909e-67434f878232",
|
||||||
|
"report_group": "desi-clans-test",
|
||||||
|
"report_id": "desi-clans-demo-v1",
|
||||||
|
"access": "public",
|
||||||
|
"password_protected": false,
|
||||||
|
"url": "https://urmiai.com/reports/desi-clans-test/desi-clans-demo-v1",
|
||||||
|
"created_at": "2026-10-02T17:13:32.468390Z",
|
||||||
|
"updated_at": "2026-10-02T17:13:32.468390Z"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Error responses
|
||||||
|
|
||||||
|
| Status | Meaning |
|
||||||
|
|--------|---------|
|
||||||
|
| `401` | Missing or invalid API key |
|
||||||
|
| `404` | Report group not found — create it in Console → Agent → Urmiport |
|
||||||
|
| `422` | Validation error (invalid slug, missing `report_id` for manual groups, missing password, etc.) |
|
||||||
|
|
||||||
|
### Public viewing
|
||||||
|
|
||||||
|
| Access | Behaviour |
|
||||||
|
|--------|-----------|
|
||||||
|
| **Public** | `GET https://urmiai.com/reports/{report_group}/{report_id}` renders HTML directly |
|
||||||
|
| **Password** | User sees a password gate; after unlock, only your HTML is shown |
|
||||||
|
|
||||||
|
Internal metadata endpoint (no auth):
|
||||||
|
|
||||||
|
```http
|
||||||
|
GET /api/v1/urmiport/view/{report_group}/{report_id}
|
||||||
|
POST /api/v1/urmiport/view/{report_group}/{report_id}/unlock
|
||||||
|
```
|
||||||
|
|
||||||
|
### HTML capabilities
|
||||||
|
|
||||||
|
Reports support plain **HTML, CSS, and JavaScript** — including charts, tables, branding, and client-side animations. Complex dashboards (canvas charts, live counters, responsive layouts) are supported.
|
||||||
|
|
||||||
|
### Machine-readable docs
|
||||||
|
|
||||||
|
```http
|
||||||
|
GET /api/v1/urmiport/docs
|
||||||
|
GET /api/v1/urmiport/reports/docs
|
||||||
|
```
|
||||||
|
|
||||||
|
Also available in the console: **Agent → Urmiport** and **Develop → API Explorer**.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## API 2 — Send WhatsApp report notification
|
||||||
|
|
||||||
|
Send an approved agent WhatsApp template. The template includes a **View Report** button whose URL is built from `report_group` and `report_id`.
|
||||||
|
|
||||||
|
### Endpoint
|
||||||
|
|
||||||
|
```http
|
||||||
|
POST /api/v1/agent/messages/send
|
||||||
|
Content-Type: application/json
|
||||||
|
Authorization: Bearer urmi_live_<your_api_key>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Request body
|
||||||
|
|
||||||
|
| Field | Required | Type | Description |
|
||||||
|
|-------|----------|------|-------------|
|
||||||
|
| `template` | Yes | string | Subscribed template slug. Use `agent_run_completion` |
|
||||||
|
| `to` | Yes | string | Recipient WhatsApp number with country code, no `+` (e.g. `919149154337`) |
|
||||||
|
| `customer_name` | Yes | string | Name inserted into the template body greeting |
|
||||||
|
| `report_group` | Yes | string | Urmiport report group slug (same as in publish API) |
|
||||||
|
| `report_id` | No | string | Report postfix. If omitted, Urmi auto-generates one (e.g. `run-a1b2c3`) |
|
||||||
|
| `report_url` | No | string | Full hosted report URL override. Auto-built as `https://urmiai.com/reports/{report_group}/{report_id}` when omitted |
|
||||||
|
|
||||||
|
### Template details — `agent_run_completion`
|
||||||
|
|
||||||
|
| Property | Value |
|
||||||
|
|----------|-------|
|
||||||
|
| **Slug** | `agent_run_completion` |
|
||||||
|
| **Meta template name** | `agent_run_completion` |
|
||||||
|
| **Header** | Agent Run Complete |
|
||||||
|
| **Body** | Hello {{1}}, your agent run is complete… |
|
||||||
|
| **Button** | View Report → `https://urmiai.com/reports/{{1}}` |
|
||||||
|
|
||||||
|
The Meta template uses **positional** variables (not named):
|
||||||
|
|
||||||
|
| Variable | Maps to API field | Example |
|
||||||
|
|----------|-------------------|---------|
|
||||||
|
| `{{1}}` (body) | `customer_name` | `Suyash` |
|
||||||
|
| `{{1}}` (button) | `report_group`/`report_id` path suffix | `desi-clans-test/2026-10-03` |
|
||||||
|
|
||||||
|
Urmi sends the button suffix `desi-clans-test/2026-10-03` so the final link is:
|
||||||
|
|
||||||
|
`https://urmiai.com/reports/desi-clans-test/2026-10-03`
|
||||||
|
|
||||||
|
> **Common bug:** If body parameters are sent as named (`parameter_name`) instead of positional, Meta leaves `{{1}}` literal in the URL, producing broken links like `https://urmiai.com/reports/%7B%7B1%7D%7Ddesi-clans-test/2026-10-03`.
|
||||||
|
|
||||||
|
### Example
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X POST 'https://urmiai.com/api/v1/agent/messages/send' \
|
||||||
|
-H 'Authorization: Bearer urmi_live_<your_api_key>' \
|
||||||
|
-H 'Content-Type: application/json' \
|
||||||
|
-d '{
|
||||||
|
"template": "agent_run_completion",
|
||||||
|
"to": "919149154337",
|
||||||
|
"customer_name": "Suyash",
|
||||||
|
"report_group": "desi-clans-test",
|
||||||
|
"report_id": "desi-clans-demo-v1"
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
|
||||||
|
### Success response `200 OK`
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"success": true,
|
||||||
|
"template": "agent_run_completion",
|
||||||
|
"to": "919149154337",
|
||||||
|
"customer_name": "Suyash",
|
||||||
|
"report_group": "desi-clans-test",
|
||||||
|
"report_id": "2026-10-03",
|
||||||
|
"report_url": "https://urmiai.com/reports/desi-clans-test/2026-10-03",
|
||||||
|
"wa_message_id": "wamid.HBg...",
|
||||||
|
"dispatch_id": "00000000-0000-0000-0000-000000000001"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Error responses
|
||||||
|
|
||||||
|
| Status | Meaning |
|
||||||
|
|--------|---------|
|
||||||
|
| `401` | Missing or invalid API key |
|
||||||
|
| `403` | Template not subscribed — subscribe in Console → Agent → UrmiAI |
|
||||||
|
| `422` | Invalid phone number, `report_group`, or `report_id` format |
|
||||||
|
| `502` | Meta WhatsApp API error (template mismatch, WABA issue, etc.) |
|
||||||
|
|
||||||
|
### Machine-readable docs
|
||||||
|
|
||||||
|
```http
|
||||||
|
GET /api/v1/agent/messages/docs/send
|
||||||
|
```
|
||||||
|
|
||||||
|
Per-template docs (console session required):
|
||||||
|
|
||||||
|
```http
|
||||||
|
GET /api/v1/agent-templates/agent_run_completion/docs
|
||||||
|
```
|
||||||
|
|
||||||
|
Also available in the console: **Agent → UrmiAI → API docs** and **Develop → API Explorer**.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Complete integration example
|
||||||
|
|
||||||
|
Publish a report, then notify the user on WhatsApp with the same `report_group` and `report_id`.
|
||||||
|
|
||||||
|
### Step 1 — Publish report
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X POST 'https://urmiai.com/api/v1/urmiport/reports' \
|
||||||
|
-H 'Authorization: Bearer urmi_live_<your_api_key>' \
|
||||||
|
-H 'Content-Type: application/json' \
|
||||||
|
-d '{
|
||||||
|
"report_group": "desi-clans-test",
|
||||||
|
"report_id": "desi-clans-demo-v1",
|
||||||
|
"access": "public",
|
||||||
|
"body": "<html><head><style>body{font-family:sans-serif;background:#0b1020;color:#fff;padding:24px}</style></head><body><h1>Desi Clans — Run complete</h1><p>All systems operational.</p></body></html>"
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
|
||||||
|
Report URL: `https://urmiai.com/reports/desi-clans-test/desi-clans-demo-v1`
|
||||||
|
|
||||||
|
### Step 2 — Send WhatsApp notification
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X POST 'https://urmiai.com/api/v1/agent/messages/send' \
|
||||||
|
-H 'Authorization: Bearer urmi_live_<your_api_key>' \
|
||||||
|
-H 'Content-Type: application/json' \
|
||||||
|
-d '{
|
||||||
|
"template": "agent_run_completion",
|
||||||
|
"to": "919149154337",
|
||||||
|
"customer_name": "Suyash",
|
||||||
|
"report_group": "desi-clans-test",
|
||||||
|
"report_id": "desi-clans-demo-v1"
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
|
||||||
|
The recipient receives a WhatsApp message with a **View Report** button pointing to the hosted report.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Quick reference
|
||||||
|
|
||||||
|
| Item | Value |
|
||||||
|
|------|-------|
|
||||||
|
| Base URL | `https://urmiai.com` |
|
||||||
|
| Publish report | `POST /api/v1/urmiport/reports` |
|
||||||
|
| Send WhatsApp | `POST /api/v1/agent/messages/send` |
|
||||||
|
| Report URL | `https://urmiai.com/reports/{report_group}/{report_id}` |
|
||||||
|
| Template slug | `agent_run_completion` |
|
||||||
|
| Auth header | `Authorization: Bearer urmi_live_<key>` |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Console links
|
||||||
|
|
||||||
|
| Task | Location |
|
||||||
|
|------|----------|
|
||||||
|
| Create report groups | Console → Agent → Urmiport |
|
||||||
|
| Subscribe WhatsApp template | Console → Agent → UrmiAI |
|
||||||
|
| Create API keys | Console → Develop → API Keys |
|
||||||
|
| Try APIs interactively | Console → Develop → API Explorer |
|
||||||
|
|
||||||
|
urmi_live_a9d92e7be1584e24aa361cb09075794a_FWsjx04IW3Z2Enqx4Lg0EybTqCYsa0Dk
|
||||||
|
|
@ -523,7 +523,14 @@ export const agentMessagesApi = {
|
||||||
docs: () => jsonRequest<AgentMessageApiDoc>('/api/v1/agent/messages/docs/send'),
|
docs: () => jsonRequest<AgentMessageApiDoc>('/api/v1/agent/messages/docs/send'),
|
||||||
send: (
|
send: (
|
||||||
apiKey: string,
|
apiKey: string,
|
||||||
payload: { template: string; to: string; customer_name: string; report_group: string; report_id?: string },
|
payload: {
|
||||||
|
template: string
|
||||||
|
to: string
|
||||||
|
customer_name: string
|
||||||
|
report_group: string
|
||||||
|
report_id?: string
|
||||||
|
report_url?: string
|
||||||
|
},
|
||||||
) =>
|
) =>
|
||||||
fetch(`${API_BASE_URL}/api/v1/agent/messages/send`, {
|
fetch(`${API_BASE_URL}/api/v1/agent/messages/send`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue