diff --git a/app/src/components/composio/ComposioConnectModal.tsx b/app/src/components/composio/ComposioConnectModal.tsx
index 846c5072b..8ae03d4bd 100644
--- a/app/src/components/composio/ComposioConnectModal.tsx
+++ b/app/src/components/composio/ComposioConnectModal.tsx
@@ -13,7 +13,7 @@
* keep the Skills page badge in sync too, so the card reflects the new
* state as soon as the modal closes.
*/
-import { useCallback, useEffect, useRef, useState } from 'react';
+import { type ChangeEvent, useCallback, useEffect, useRef, useState } from 'react';
import { createPortal } from 'react-dom';
import {
@@ -73,6 +73,9 @@ export default function ComposioConnectModal({
);
const [error, setError] = useState(null);
const [connectUrl, setConnectUrl] = useState(null);
+ // WhatsApp Business requires a WABA ID before the OAuth flow can start.
+ const [wabaId, setWabaId] = useState('');
+ const needsWabaId = toolkit.slug === 'whatsapp';
const [activeConnection, setActiveConnection] = useState(
connection
);
@@ -188,11 +191,16 @@ export default function ComposioConnectModal({
}, []);
const handleConnect = useCallback(async () => {
+ if (needsWabaId && !wabaId.trim()) {
+ setError('Please enter your WhatsApp Business Account ID (WABA ID) to continue.');
+ return;
+ }
setPhase('authorizing');
setError(null);
setConnectUrl(null);
try {
- const resp = await authorize(toolkit.slug);
+ const extraParams = needsWabaId ? { waba_id: wabaId.trim() } : undefined;
+ const resp = await authorize(toolkit.slug, extraParams);
setConnectUrl(resp.connectUrl);
await openUrl(resp.connectUrl);
setPhase('waiting');
@@ -202,7 +210,7 @@ export default function ComposioConnectModal({
setPhase('error');
setError(`Authorization failed: ${msg}`);
}
- }, [startPolling, toolkit.slug]);
+ }, [needsWabaId, startPolling, toolkit.slug, wabaId]);
// Fetch the stored scope pref whenever the modal lands in the
// 'connected' phase. Re-fetching each time we transition (rather
@@ -360,6 +368,35 @@ export default function ComposioConnectModal({
admin toggles.
+ {needsWabaId && (
+
+
+
) => {
+ setWabaId(e.target.value);
+ if (error) setError(null);
+ }}
+ placeholder="e.g. 123456789012345"
+ className="w-full rounded-xl border border-stone-200 bg-white px-3 py-2 text-sm text-stone-900 placeholder:text-stone-400 focus:border-primary-400 focus:outline-none focus:ring-2 focus:ring-primary-100"
+ />
+
+ Find it via GET /me/businesses then{' '}
+
+ GET /{business_id}/owned_whatsapp_business_accounts
+ {' '}
+ using your Meta access token.
+
+
+ )}
+ {error && phase === 'idle' && {error}
}