Skip to Content
splashify CLIIntegrations

Integrations

The integrations command mirrors the /integrations page and the per-slug detail pages it links to. Backend integrations are split into three coupled surfaces:

SurfacePurpose
configsPer-slug behavior — which template fires on which event, with what variable mappings
accountsOAuth connections to third-party platforms (Pipedream-style)
logsWebhook events received from the third party, with replay/inspection

Backed by /api/v1/app/integrations/*.

Quick start

# 1. See what's wired up splashify integrations # configs (default view) splashify integrations accounts # OAuth connections # 2. Save a Shopify config splashify integrations config shopify save \ --enabled true \ --template <template_id> \ --template-name "order_shipped" \ --template-language en \ --vars '{"{{1}}":"contact.first_name","{{2}}":"event.order_id"}' \ --phone-field "customer.phone" \ --config '{"webhook_secret":"shpss_…"}' # 3. Watch incoming webhooks splashify integrations logs --slug shopify --limit 50

Command tree

integrations list per-slug configs (default) integrations configs same integrations config <slug> show one config integrations config <slug> save … update/create integrations config <slug> delete remove the config (the slug stays available) integrations accounts list OAuth connections integrations account <id> show one integrations account <id> disconnect revoke integrations token mint a connect-token for OAuth callbacks integrations logs [--limit] [--slug] webhook event feed integrations log <log_id> show one event

Per-slug configs

A config tells the backend: when a webhook event from this slug arrives, which WhatsApp template do I fire and what variables do I substitute?

# Show one splashify integrations config shopify # Save (creates if absent, updates if present — PUT semantics) splashify integrations config shopify save \ --enabled true \ --template <template_id> # Delete splashify integrations config shopify delete
Backed byPUT /api/v1/app/integrations/configs/:slug
DELETE /api/v1/app/integrations/configs/:slug

The endpoint is gated by your plan’s allowed_integrations list — if the slug isn’t included, the backend refuses with the standard plan_required error. An empty list on the plan means all available.

Save flags

FlagWhat it sets
--enabledtrue to make the integration active
--templatetemplate_id of the fallback WhatsApp template
--template-nametemplate name (display only)
--template-languageBCP-47 language for the template
--configJSON object of provider secrets — e.g. '{"api_key":"…","webhook_secret":"…"}'
--varsJSON object mapping template variables to webhook payload paths — '{"{{1}}":"contact.first_name"}'
--phone-fieldwebhook payload field that holds the phone number
--eventsnested JSON: per-event template overrides — see below

Per-event automations

--events lets you bind specific webhook events to different templates, e.g. send order_shipped for order.shipped but payment_failed for payment.failed. The value is a JSON object keyed by event name:

splashify integrations config shopify save \ --events '{ "order.shipped": { "template_id": "<shipped_template_id>", "template_name": "order_shipped", "variable_mappings": {"{{1}}":"customer.first_name","{{2}}":"order.tracking_url"}, "phone_field": "customer.phone" }, "payment.failed": { "template_id": "<failed_template_id>", "template_name": "payment_failed", "variable_mappings": {"{{1}}":"customer.first_name","{{2}}":"order.id"}, "phone_field": "customer.phone" } }'

Per-event mappings override the top-level --template / --vars / --phone-field when the incoming event matches.

OAuth connections (accounts)

Some integrations connect via OAuth instead of webhook secret. Those mint account records on success.

splashify integrations accounts # list all splashify integrations account <account_id> # show one splashify integrations account <account_id> disconnect # revoke
Backed byGET /api/v1/app/integrations/accounts
DELETE /api/v1/app/integrations/accounts/:account_id

Connect tokens

Some OAuth flows hand a short-lived connect-token to the third party so the redirect can attribute the connection back to your account.

splashify integrations token
Backed byPOST /api/v1/app/integrations/token

Returns a one-shot token you pass to the third party’s OAuth URL as state or equivalent.

Webhook logs

Every incoming webhook is recorded for inspection + replay.

splashify integrations logs # newest first, server default splashify integrations logs --limit 200 splashify integrations logs --slug shopify # filter to one integration splashify integrations log <log_id> # one event in detail
Backed byGET /api/v1/app/integrations/logs[?limit=&slug=]
GET /api/v1/app/integrations/logs/:log_id

Each log row carries the raw payload, the event type, the slug, the template that fired (if any), and the resulting send status. Use this to debug “why didn’t my Shopify webhook send a WhatsApp?”

Common workflows

Audit which integrations fired in the last hour

CUTOFF=$(date -u -v-1H '+%Y-%m-%dT%H:%M:%SZ') # macOS # CUTOFF=$(date -u -d '1 hour ago' '+%Y-%m-%dT%H:%M:%SZ') # linux splashify integrations logs --limit 500 | \ jq --arg c "$CUTOFF" '.logs[] | select(.created_at > $c) | {created_at, slug, event_type, status}'

Find the most-recent failed delivery for a slug

splashify integrations logs --slug shopify --limit 200 | \ jq '[.logs[] | select(.status == "failed")] | first | {log_id, event_type, error, raw_payload}'

Disable every integration at once (emergency stop)

splashify integrations configs | \ jq -r '.configs[] | select(.enabled) | .slug' | \ xargs -I{} splashify integrations config {} save --enabled false

Backup all configs before a change

splashify integrations configs > integrations.backup.json # Restore one slug from the backup: SLUG=shopify jq -c --arg s "$SLUG" '.configs[] | select(.slug == $s)' integrations.backup.json # Then translate to a save command…

Disconnect every Pipedream account

splashify integrations accounts | \ jq -r '.accounts[] | select(.provider == "pipedream") | .account_id' | \ xargs -I{} splashify integrations account {} disconnect

Troubleshooting

plan_required on config <slug> save — the slug isn’t in your plan’s allowed_integrations list. Check splashify subscription for add-on options.

config save returns 200 but webhook doesn’t fire a WhatsApp — likely a mapping problem. Check splashify integrations logs --slug <slug> for the raw payload, then verify each --vars path resolves against it. Most common cause: --phone-field pointing at the wrong property.

Webhook URL — the per-slug receiver is at /webhooks/integrations/:user_id/:slug (public, no auth — it’s gated by signature/secret verification against the webhook_secret you set in --config). Provider docs should point there.

account disconnect 200 but the connection still works — some providers cache tokens client-side for a few minutes. The next webhook event from them will fail (no matching account record), so deliveries stop within ~minutes.

See also