Skip to content

feat(triggers): Activepieces polling triggers — poll loop, sidecar protocol, CRUD#68

Merged
ovasylenko merged 1 commit into
mainfrom
feat/activepieces-polling-triggers
Jun 10, 2026
Merged

feat(triggers): Activepieces polling triggers — poll loop, sidecar protocol, CRUD#68
ovasylenko merged 1 commit into
mainfrom
feat/activepieces-polling-triggers

Conversation

@ovasylenko

Copy link
Copy Markdown
Contributor

Summary

Item #8 from docs/FEATURE_OPPORTUNITIES.md: event-driven workflows from the Activepieces catalog — "when a Stripe payment fails → start a durable sequence." Polling-based per the doc's explicit scoping (webhook triggers deliberately deferred).

  • New TriggerType::ActivepiecesPoll rides the existing triggers table + 15s sync loop (same listener model as NATS/file-watch). Config: piece, trigger, auth, props, interval_secs XOR cron (default 60s, 1s floor).
  • Sidecar gains POST /poll (same envelope as /execute): loads the piece, seeds a TriggerContext.store from the opaque cursor, calls trigger.run(), returns {items, state} — matching AP's pollingHelper contract so real pieces dedupe correctly without the AP platform DB. Webhook-strategy triggers rejected 422.
  • Engine poll loop: credentials:// resolved on every poll (rotation-safe), one instance per item via the same path as POST /triggers/{slug}/fire, cursor persisted only after all items create instances (at-least-once). Failures: last_error + consecutive_failures on a separate trigger_poll_state row (no lost-update race with API edits), loop never exits, metrics orch8_ap_poll_{items,errors}_total.
  • Migration 044_trigger_poll_state.sql + sqlite schema; both backends + encrypting wrapper; GET /triggers/{slug} surfaces poll_state; create validates poll configs (400 with reason). activepieces/README.md documents the feature.

What's real vs stubbed

The full mechanism is end-to-end real; tests use stub pieces. A real piece needs only npm install @activepieces/piece-<name> into the sidecar — same operational story as actions today.

Tests

14 engine (dep-free TCP mock sidecar: items→instances, cursor round-trip, failure bookkeeping, credential resolution, loop survival), 6 API integration, storage round-trips, 17 sidecar tests (155 total, tsc clean). cargo test across 4 crates: 3224 passed. fmt/clippy/doc gates clean.

🤖 Generated with Claude Code

…otocol, CRUD

Adds polling-based triggers for ActivePieces pieces: a tenant-scoped
trigger registration (trigger_type: activepieces_poll) whose config names
a piece, a piece trigger, auth/props (credentials:// resolved per poll),
and a schedule (interval_secs or cron). The engine's trigger sync loop
spawns a poll listener per registration that asks the Node sidecar's new
POST /poll endpoint to run the piece trigger headlessly; each returned
item creates one durable instance, and the trigger's store contents are
persisted as an opaque dedupe cursor (trigger_poll_state table) and sent
back on the next poll. Failed polls record last_error and bump
consecutive_failures (surfaced on GET /triggers/{slug}) without ever
stopping the loop.

- orch8-types: TriggerType::ActivepiecesPoll + TriggerPollState
- orch8-storage: trigger_poll_state table (migration 044 + sqlite schema),
  get/upsert poll-state on AdminStore (sqlite, postgres, encrypting)
- orch8-engine: ap_poll module (config parsing, poll loop, failure
  bookkeeping), trigger sync wiring, cron::next_fire_from_expr, metrics
- orch8-api: config validation on create, poll_state on GET, OpenAPI
- sidecar: POST /poll op, findTrigger, buildTriggerContext with seeded
  store; webhook-strategy triggers rejected as permanent
- tests: engine poll loop vs dep-free TCP mock sidecar, API CRUD/tenant
  isolation, storage round-trips, sidecar stub-piece polling suite

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@ovasylenko ovasylenko merged commit b8f9686 into main Jun 10, 2026
14 checks passed
@ovasylenko ovasylenko deleted the feat/activepieces-polling-triggers branch June 10, 2026 10:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant