Build WhatsApp automations with Kapso workflows: configure WhatsApp triggers, edit workflow graphs, manage executions, deploy functions, search workflow Logs, and debug automation behavior. Use when automating WhatsApp conversations and event handling.
npx skills add https://github.com/gokapso/agent-skills --skill automate-whatsapp
Use this skill to build and run WhatsApp automations: workflow CRUD, graph edits, WhatsApp and Project Event triggers, Project Event emissions, executions, function management, webhook tools, and MCP tools.
Preferred path:
kapso login)kapso link, kapso pull, kapso build, and kapso push@kapso/workflows and export a Workflow instance from workflow.js or workflow.tsFallback path:
Env vars:
KAPSO_API_BASE_URL (host only, no /platform/v1)KAPSO_API_KEYUse this path first when the user is working in, or can create, a local repo.
npm install -g @kapso/cli
npm install --save-dev @kapso/workflows
kapso login
kapso link --project <project-id>
kapso pull
Edit workflows/<workflow-slug>/workflow.js or workflow.ts with @kapso/workflows:
import { START, Workflow } from "@kapso/workflows";
const workflow = new Workflow("inbound-support", {
name: "Inbound Support",
status: "draft",
});
workflow.addTrigger({
type: "inbound_message",
phoneNumberId: "<phone-number-id>",
});
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:
kapso build
kapso push --dry-run
kapso push workflow <workflow-slug>
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.
Preferred path:
kapso statuskapso whatsapp numbers list --output jsonkapso whatsapp numbers resolve --phone-number "<display-number>" --output jsonFallback path:
node scripts/list-whatsapp-phone-numbers.jsPrefer local source sync for workflow edits. Use these scripts as a fallback for debugging, direct graph inspection, or API-only environments.
node scripts/get-graph.js <workflow_id> (note the lock_version)node scripts/validate-graph.js --definition-file <path>node scripts/update-graph.js <workflow_id> --expected-lock-version <n> --definition-file <path>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.
node scripts/list-triggers.js <workflow_id>node scripts/create-trigger.js <workflow_id> --trigger-type <type> --phone-number-id <id>node scripts/update-trigger.js --trigger-id <id> --active true|falsenode scripts/delete-trigger.js --trigger-id <id>For inbound_message triggers, prefer kapso whatsapp numbers resolve --phone-number "<display-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.
For project_event triggers, register or update the Project Event definition first when the user is defining an event type/schema:
node scripts/project-event-definitions.js create \
--name conversation.csat_scored \
--description "Customer satisfaction score for a conversation" \
--property-schema '{"score":{"type":"number"},"reason":{"type":"string"}}'
Then create the trigger:
node scripts/create-trigger.js <workflow_id> \
--trigger-type project_event \
--triggerable-attributes '{"event_name":"conversation.csat_scored","property_key":"score","operator":"gte","property_value":4}'
Definitions are metadata only. Do not emit a sample event just to register a name unless the user explicitly accepts that side effect.
Use definitions for event names, descriptions, and flat scalar property schemas. Emitted events are separate records created by POST /platform/v1/events, emit_event nodes, Function node project_events, or Agent node emit_event.
node scripts/project-event-definitions.js listnode scripts/project-event-definitions.js create --name <event.name> [--description <text>] [--property-schema <json>]node scripts/project-event-definitions.js update --definition-id <id> [--name <event.name>] [--description <text>] [--property-schema <json>]Use this checklist when a workflow needs to remember or react to durable business facts:
project_event triggers when a workflow should react to an emitted event.emit_event node for deterministic workflow-step emission.project_events when emission depends on function code output.emit_event only when the agent should decide whether/when to record the fact. Enable the emit_event default tool and configure allowed event definitions before relying on it.Project-event-triggered workflows are observers and cannot emit Project Events. Do not add event emission to a workflow that starts from a Project Event trigger.
kapso logs search --query "<execution-id>" --source flow_event --filter flow_execution_id=<execution-id> --period 7d --limit 20 --output jsonnode scripts/list-executions.js <workflow_id>node scripts/get-execution.js <execution-id>node scripts/get-context-value.js <execution-id> --variable-path vars.foonode scripts/list-execution-events.js <execution-id>node scripts/create-function.js --name <name> --code-file <path> [--public-endpoint true]node scripts/deploy-function.js --function-id <id>node scripts/get-function.js --function-id <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.
Use this when the agent needs a remote ephemeral workspace to inspect or modify repository files during a workflow run.
references/agent-remote-sandbox.md for the execution model and field rulesnode scripts/list-provider-models.jsassets/agent-remote-sandbox-github-repo-example.json as a starting point, or edit the agent node under data.configsandbox_enabled: truesandbox_network_mode to allow_all or allow_listallow_list, add extra outbound hosts in sandbox_allowed_outbound_hostsflow_agent_resources with:resource_type: "github_repository"repo_urlbranchpat/workspace/repos/<repo-slug> before making changesNotes:
sandbox_enabled controls whether the remote workspace and sandbox tools are availabletree/... URL/workspace/repos/<repo-slug> inside the remote sandboxreferences/agent-remote-sandbox.md and references/node-types.md for the exact shapeid = start{node_type}_{timestamp_ms} for new node IDsnext edgeconditions[].labelsource/target/label (not from/to)For full schema details, see references/graph-contract.md.
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" }));
}
export, export default, or arrow functionsResponse objectAlways use this structure:
vars - user-defined variablessystem - system variablescontext - channel datametadata - request metadata| 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 |
| 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 |
| 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 |
| Script | Purpose |
|--------|---------|
| project-event-definitions.js | List, create, or update Project Event definitions |
| 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 |
| 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 |
| Script | Purpose |
|--------|---------|
| openapi-explore.mjs | Explore OpenAPI (search/op/schema/where) |
Install deps (once):
npm i
Examples:
node scripts/openapi-explore.mjs --spec workflows search "variables"
node scripts/openapi-explore.mjs --spec workflows op getWorkflowVariables
--definition-file, --code-file)observe-whatsapp for cross-source Logs search when debugging a workflow alongside API calls, Meta events, or webhook deliveries.variables-set.js, variables-delete.js) is blocked - Platform API doesn't support itRead before editing:
@kapso/workflowsOther references:
| 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 |
integrate-whatsapp - Onboarding, webhooks, messaging, templates, flowsobserve-whatsapp - Debugging, logs, health checks<!-- FILEMAP:BEGIN -->
[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,project-event-definitions.js,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}
<!-- FILEMAP:END -->
Guide for creating high-quality MCP (Model Context Protocol) servers that enable LLMs to interact with external services through well-designed tools. Use when building MCP servers to integrate external APIs or services, whether in Python (FastMCP) or Node/TypeScript (MCP SDK).
Automatically creates user-facing changelogs from git commits by analyzing commit history, categorizing changes, and transforming technical commits into clear, customer-friendly release notes. Turns hours of manual changelog writing into minutes of automated generation.
Use when implementation is complete, all tests pass, and you need to decide how to integrate the work - guides completion of development work by presenting structured options for merge, PR, or cleanup
Guide for creating high-quality MCP (Model Context Protocol) servers that enable LLMs to interact with external services through well-designed tools. Use when building MCP servers to integrate external APIs or services, whether in Python (FastMCP) or Node/TypeScript (MCP SDK).
React Native and Expo best practices for building performant mobile apps. Use when building React Native components, optimizing list performance, implementing animations, or working with native modules. Triggers on tasks involving React Native, Expo, mobile performance, or native platform APIs.
React and Next.js performance optimization guidelines from Vercel Engineering. This skill should be used when writing, reviewing, or refactoring React/Next.js code to ensure optimal performance patterns. Triggers on tasks involving React components, Next.js pages, data fetching, bundle optimization, or performance improvements.
Next.js best practices - file conventions, RSC boundaries, data patterns, async APIs, metadata, error handling, route handlers, image/font optimization, bundling
Use when starting feature work that needs isolation from current workspace or before executing implementation plans - creates isolated git worktrees with smart directory selection and safety verification
Take gokapso/automate-whatsapp from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.
The instructions reference npm.
Without those the skill loads but fails at the first command.