+
+
Messages
+
WhatsApp broadcast
+
Sends a marketing template through Meta’s marketing endpoint. Chat replies stay on the WhatsApp page.
+
+
+ {!loading && accounts.length > 0 && (
+
+ )}
+
+ {error &&
{error}
}
+ {loading &&
Loading accounts…
}
+
+ {!loading && accounts.length === 0 && (
+
+ Connect a WhatsApp number before sending a broadcast.
+ Add a WhatsApp token
+
+ )}
+
+ {!loading && accounts.length > 0 && (
+
+ )}
+
+ {result && (
+
+ {result.sent} sent, {result.failed} failed
+
+ {result.results.map((item) => (
+ -
+ {item.to}
+ {item.status === 'sent' ? 'Sent' : item.error || 'Failed'}
+
+ ))}
+
+
+ )}
+
+ )
+}
diff --git a/frontend/src/index.css b/frontend/src/index.css
index 3146890..dab6e99 100644
--- a/frontend/src/index.css
+++ b/frontend/src/index.css
@@ -1848,6 +1848,9 @@ main { padding: 30px clamp(20px, 3vw, 44px) 50px; }
.wa-token-form { display: grid; gap: 12px; margin-top: 16px; }
.wa-token-form .primary-button { justify-self: start; display: inline-flex; align-items: center; gap: 8px; }
.wa-token-page { max-width: 720px; }
+.wa-broadcast-steps { margin: 0; padding-left: 18px; display: grid; gap: 6px; }
+.wa-broadcast-results { display: grid; gap: 8px; margin-top: 12px; }
+.wa-broadcast-results li { display: flex; justify-content: space-between; gap: 12px; }
.wa-token-result { margin-top: 16px; }
.wa-token-result .primary-button { margin-top: 8px; text-decoration: none; display: inline-flex; }
.wa-biz-heading h1 { margin: 6px 0; }
diff --git a/frontend/src/lib/api.ts b/frontend/src/lib/api.ts
index 2d3bbf6..1c6cbdc 100644
--- a/frontend/src/lib/api.ts
+++ b/frontend/src/lib/api.ts
@@ -1290,6 +1290,11 @@ export const whatsappApi = {
method: 'POST',
body: JSON.stringify({ pin: pin || null }),
}),
+ enableDelivery: (accountId: string, appSecret: string) =>
+ jsonRequest