--- name: automate-whatsapp description: "Build WhatsApp automations with Kapso workflows: configure WhatsApp triggers, edit workflow graphs, manage executions, deploy functions, and debug automation behavior. Use when automating WhatsApp conversations and event handling." --- # Automate WhatsApp ## When to use Use this skill to build and run WhatsApp automations: workflow CRUD, graph edits, triggers, executions, function management, webhook tools, and MCP tools. ## Setup Preferred path: - Kapso CLI installed and authenticated (`kapso login`) - For workflow and function edits, use source-controlled projects with `kapso link`, `kapso pull`, `kapso build`, and `kapso push` - For workflow code, use `@kapso/workflows` and export a `Workflow` instance from `workflow.js` or `workflow.ts` Fallback path: Env vars: - `KAPSO_API_BASE_URL` (host only, no `/platform/v1`) - `KAPSO_API_KEY` ## How to ### Edit workflows locally Use this path first when the user is working in, or can create, a local repo. ```bash npm install -g @kapso/cli npm install --save-dev @kapso/workflows kapso login kapso link --project kapso pull ``` Edit `workflows//workflow.js` or `workflow.ts` with `@kapso/workflows`: ```ts import { START, Workflow } from "@kapso/workflows"; const workflow = new Workflow("inbound-support", { name: "Inbound Support", status: "draft", }); workflow.addTrigger({ type: "inbound_message", phoneNumberId: "", }); workflow.addNode(START, { position: { x: 100, y: 100 }, }); workflow.addNode("reply", { type: "send_text", message: "Thanks for reaching out.", }); workflow.addEdge(START, "reply"); export default workflow; ``` Build and push: ```bash kapso build kapso push --dry-run kapso push workflow ``` Use `kapso push` to push every local function and workflow. See `references/local-workflow-source.md` for repo layout, source-file behavior, and JSON-only editing. ### Discover phone numbers first Preferred path: 1. Check project state: `kapso status` 2. List connected numbers: `kapso whatsapp numbers list --output json` 3. Resolve a display number when needed: `kapso whatsapp numbers resolve --phone-number "" --output json` Fallback path: 1. List number configs for triggers: `node scripts/list-whatsapp-phone-numbers.js` ### Edit a workflow graph through API scripts Prefer local source sync for workflow edits. Use these scripts as a fallback for debugging, direct graph inspection, or API-only environments. 1. Fetch graph: `node scripts/get-graph.js ` (note the `lock_version`) 2. Edit the JSON (see graph rules below) 3. Validate: `node scripts/validate-graph.js --definition-file ` 4. Update: `node scripts/update-graph.js --expected-lock-version --definition-file ` 5. Re-fetch to confirm For small edits, use `edit-graph.js` with `--old-file` and `--new-file` instead. If you get a lock_version conflict: re-fetch, re-apply changes, retry with new lock_version. ### Manage triggers 1. List: `node scripts/list-triggers.js ` 2. Create: `node scripts/create-trigger.js --trigger-type --phone-number-id ` 3. Toggle: `node scripts/update-trigger.js --trigger-id --active true|false` 4. Delete: `node scripts/delete-trigger.js --trigger-id ` For inbound_message triggers, prefer `kapso whatsapp numbers resolve --phone-number "" --output json` to get the exact `phone_number_id`. Fall back to `node scripts/list-whatsapp-phone-numbers.js` when the CLI is unavailable. ### Debug executions 1. List: `node scripts/list-executions.js ` 2. Inspect: `node scripts/get-execution.js ` 3. Get value: `node scripts/get-context-value.js --variable-path vars.foo` 4. Events: `node scripts/list-execution-events.js ` ### Create and deploy a function 1. Write code with handler signature (see function rules below) 2. Create: `node scripts/create-function.js --name --code-file [--public-endpoint true]` 3. Deploy: `node scripts/deploy-function.js --function-id ` 4. Verify: `node scripts/get-function.js --function-id ` Use `--public-endpoint true` when the function should be callable without `X-API-Key` via the Kapso-hosted invoke URL. This is only supported for Cloudflare functions. New functions default to `invoke_response_mode=passthrough`, which returns the function body directly on successful invoke. Legacy wrapped functions can be migrated later with `update-function.js`. ### Set up agent node with remote sandbox repositories Use this when the agent needs a remote ephemeral workspace to inspect or modify repository files during a workflow run. 1. Read `references/agent-remote-sandbox.md` for the execution model and field rules 2. Find model: `node scripts/list-provider-models.js` 3. Copy `assets/agent-remote-sandbox-github-repo-example.json` as a starting point, or edit the agent node under `data.config` 4. Set `sandbox_enabled: true` 5. Set `sandbox_network_mode` to `allow_all` or `allow_list` 6. If using `allow_list`, add extra outbound hosts in `sandbox_allowed_outbound_hosts` 7. Add GitHub repositories to `flow_agent_resources` with: - `resource_type: "github_repository"` - `repo_url` - `branch` - `pat` 8. Write the system prompt so it explicitly reads from `/workspace/repos/` before making changes 9. Validate and update the graph Notes: - Remote sandbox is beta and free during the beta - `sandbox_enabled` controls whether the remote workspace and sandbox tools are available - Repository resources stay configured even if sandbox access is turned off later - v1 supports GitHub repositories only - Use a repository root URL, not a GitHub file URL or `tree/...` URL - Repositories are mounted into `/workspace/repos/` inside the remote sandbox - Use `references/agent-remote-sandbox.md` and `references/node-types.md` for the exact shape ## Graph rules - Exactly one start node with `id` = `start` - Never change existing node IDs - Use `{node_type}_{timestamp_ms}` for new node IDs - Non-decide nodes have 0 or 1 outgoing `next` edge - Decide edge labels must match `conditions[].label` - Edge keys are `source`/`target`/`label` (not `from`/`to`) For full schema details, see `references/graph-contract.md`. ## Function rules ```js async function handler(request, env) { // Parse input const body = await request.json(); // Use env.KV and secrets as needed return new Response(JSON.stringify({ result: "ok" })); } ``` - Do NOT use `export`, `export default`, or arrow functions - Return a `Response` object ## Execution context Always use this structure: - `vars` - user-defined variables - `system` - system variables - `context` - channel data - `metadata` - request metadata ## Scripts ### Workflows | Script | Purpose | |--------|---------| | `list-workflows.js` | List workflows (metadata only) | | `get-workflow.js` | Get workflow metadata | | `create-workflow.js` | Create a workflow | | `update-workflow-settings.js` | Update workflow settings | ### Graph | Script | Purpose | |--------|---------| | `get-graph.js` | Get workflow graph + lock_version | | `edit-graph.js` | Patch graph via string replacement | | `update-graph.js` | Replace entire graph | | `validate-graph.js` | Validate graph structure locally | ### Triggers | Script | Purpose | |--------|---------| | `list-triggers.js` | List triggers for a workflow | | `create-trigger.js` | Create a trigger | | `update-trigger.js` | Enable/disable a trigger | | `delete-trigger.js` | Delete a trigger | | `list-whatsapp-phone-numbers.js` | List phone numbers for trigger setup | ### Executions | Script | Purpose | |--------|---------| | `list-executions.js` | List executions | | `get-execution.js` | Get execution details | | `get-context-value.js` | Read value from execution context | | `update-execution-status.js` | Force execution state | | `resume-execution.js` | Resume waiting execution | | `list-execution-events.js` | List execution events | ### Functions | Script | Purpose | |--------|---------| | `list-functions.js` | List project functions | | `get-function.js` | Get function details + code | | `create-function.js` | Create a function, optionally with a public invoke endpoint | | `update-function.js` | Update function code, public endpoint setting, or migrate a legacy wrapped function to passthrough | | `deploy-function.js` | Deploy function to runtime | | `invoke-function.js` | Invoke function with payload | | `list-function-invocations.js` | List function invocations | ### OpenAPI | Script | Purpose | |--------|---------| | `openapi-explore.mjs` | Explore OpenAPI (search/op/schema/where) | Install deps (once): ```bash npm i ``` Examples: ```bash node scripts/openapi-explore.mjs --spec workflows search "variables" node scripts/openapi-explore.mjs --spec workflows op getWorkflowVariables ``` ## Notes - Prefer file paths over inline JSON (`--definition-file`, `--code-file`) - Variable CRUD (`variables-set.js`, `variables-delete.js`) is blocked - Platform API doesn't support it ## References Read before editing: - [references/local-workflow-source.md](references/local-workflow-source.md) - CLI source sync, repo layout, and `@kapso/workflows` - [references/graph-contract.md](references/graph-contract.md) - Graph schema, computed vs editable fields, lock_version - [references/node-types.md](references/node-types.md) - Node types and config shapes - [references/workflow-overview.md](references/workflow-overview.md) - Execution flow and states Other references: - [references/execution-context.md](references/execution-context.md) - Context structure and variable substitution - [references/triggers.md](references/triggers.md) - Trigger types and setup - [references/agent-remote-sandbox.md](references/agent-remote-sandbox.md) - Remote sandbox behavior, repo resources, mounted paths - [references/functions-reference.md](references/functions-reference.md) - Function management - [references/functions-payloads.md](references/functions-payloads.md) - Payload shapes for functions ## Assets | File | Description | |------|-------------| | `workflow-linear.json` | Minimal linear workflow | | `workflow-decision.json` | Minimal branching workflow | | `workflow-agent-simple.json` | Minimal agent workflow | | `workflow-customer-support-intake-agent.json` | Customer support intake | | `workflow-interactive-buttons-decide-function.json` | Interactive buttons + decide (function) | | `workflow-interactive-buttons-decide-ai.json` | Interactive buttons + decide (AI) | | `workflow-api-template-wait-agent.json` | API trigger + template + agent | | `function-decide-route-interactive-buttons.json` | Function for button routing | | `agent-remote-sandbox-github-repo-example.json` | Agent node with remote sandbox + GitHub repo resource | ## Related skills - `integrate-whatsapp` - Onboarding, webhooks, messaging, templates, flows - `observe-whatsapp` - Debugging, logs, health checks ```text [automate-whatsapp file map]|root: . |.:{package.json,SKILL.md} |assets:{agent-remote-sandbox-github-repo-example.json,function-decide-route-interactive-buttons.json,functions-example.json,workflow-agent-simple.json,workflow-api-template-wait-agent.json,workflow-customer-support-intake-agent.json,workflow-decision.json,workflow-interactive-buttons-decide-ai.json,workflow-interactive-buttons-decide-function.json,workflow-linear.json} |references:{agent-remote-sandbox.md,execution-context.md,function-contracts.md,functions-payloads.md,functions-reference.md,graph-contract.md,local-workflow-source.md,node-types.md,triggers.md,workflow-overview.md,workflow-reference.md} |scripts:{create-function.js,create-trigger.js,create-workflow.js,delete-trigger.js,deploy-function.js,edit-graph.js,get-context-value.js,get-execution-event.js,get-execution.js,get-function.js,get-graph.js,get-workflow.js,invoke-function.js,list-execution-events.js,list-executions.js,list-function-invocations.js,list-functions.js,list-provider-models.js,list-triggers.js,list-whatsapp-phone-numbers.js,list-workflows.js,openapi-explore.mjs,resume-execution.js,update-execution-status.js,update-function.js,update-graph.js,update-trigger.js,update-workflow-settings.js,validate-graph.js,variables-delete.js,variables-list.js,variables-set.js} |scripts/lib/functions:{args.js,kapso-api.js} |scripts/lib/workflows:{args.js,kapso-api.js,result.js} ```