diff --git a/plugins/kapso/skills/integrate-whatsapp/SKILL.md b/plugins/kapso/skills/integrate-whatsapp/SKILL.md index d38dd09..c9ee1df 100644 --- a/plugins/kapso/skills/integrate-whatsapp/SKILL.md +++ b/plugins/kapso/skills/integrate-whatsapp/SKILL.md @@ -232,6 +232,16 @@ Send-time: Use Flows to build native WhatsApp forms. Read `references/whatsapp-flows-spec.md` before editing Flow JSON. +### Prerequisite: a connected number + +A Flow always belongs to a connected WhatsApp number, so confirm one exists **before** starting the builder: + +```bash +node scripts/list-platform-phone-numbers.mjs +``` + +If the list is empty, do **not** proceed into the Flow builder with an empty number selection — that is a dead end. Route the user to connect a number first via embedded signup (`kapso setup`, or generate a setup link with `POST /platform/v1/customers/:id/setup_links`), then return to create the Flow. See `references/getting-started.md` and `references/setup-links.md`. `create-flow.js` enforces this: called without `--phone-number-id`, it lists the connected numbers to pick from, or tells you to connect one first when none exist. + ### Create and publish a flow 1. Create flow: `node scripts/create-flow.js --phone-number-id --name ` diff --git a/plugins/kapso/skills/integrate-whatsapp/scripts/create-flow.js b/plugins/kapso/skills/integrate-whatsapp/scripts/create-flow.js index d894178..eaafad6 100644 --- a/plugins/kapso/skills/integrate-whatsapp/scripts/create-flow.js +++ b/plugins/kapso/skills/integrate-whatsapp/scripts/create-flow.js @@ -3,11 +3,62 @@ const { parseArgs, getStringFlag, getBooleanFlag, readFlagJson } = require('./li const { platformRequest } = require('./lib/http'); const { run } = require('./lib/run'); +function summarizeNumbers(response) { + const configs = response?.data; + if (!Array.isArray(configs)) return []; + return configs.map((config) => ({ + name: config.name, + display_phone_number: config.display_phone_number, + phone_number_id: config.phone_number_id || config.id, + business_account_id: config.business_account_id + })); +} + +// A Flow always belongs to a connected WhatsApp number. When the caller did not +// pass one, look at what is actually connected so we never dead-end the way an +// empty "WhatsApp number" picker would: route to embedded signup if nothing is +// connected, or list the choices if some are. +async function resolvePhoneNumberGuidance() { + let numbers; + try { + const response = await platformRequest({ + method: 'GET', + path: '/platform/v1/whatsapp/phone_numbers' + }); + numbers = summarizeNumbers(response); + } catch { + // Listing failed (auth/network); fall back to the plain requirement. + throw new Error( + 'Missing required flag --phone-number-id. Discover connected numbers with ' + + '`node scripts/list-platform-phone-numbers.mjs`; if none are connected, connect ' + + 'a WhatsApp number first via embedded signup (`kapso setup`) before creating a Flow.' + ); + } + + if (numbers.length === 0) { + throw new Error( + 'No WhatsApp numbers are connected, so a Flow cannot be created yet. ' + + 'Connect a WhatsApp number first via embedded signup (`kapso setup`, or generate a ' + + 'setup link with `POST /platform/v1/customers/:id/setup_links`), then re-run with ' + + '--phone-number-id . See references/getting-started.md and references/setup-links.md.' + ); + } + + const choices = numbers + .map((n) => `${n.display_phone_number || n.name || 'number'} -> --phone-number-id ${n.phone_number_id}`) + .join('\n '); + throw new Error( + 'Missing required flag --phone-number-id. Connected numbers:\n ' + + choices + + '\nRe-run create-flow.js with one of the phone_number_id values above.' + ); +} + run(async () => { const { flags } = parseArgs(process.argv.slice(2)); const phoneNumberId = getStringFlag(flags, 'phone-number-id') || getStringFlag(flags, 'phone_number_id'); if (!phoneNumberId) { - throw new Error('Missing required flag --phone-number-id'); + await resolvePhoneNumberGuidance(); } const name = getStringFlag(flags, 'name');