Skip to content

Add wolt plugin (Wolt food/grocery delivery — Israel + global consumer account) - #44

Open
amitayks wants to merge 3 commits into
Michaelliv:mainfrom
amitayks:add-wolt-plugin
Open

amitayks wants to merge 3 commits into
Michaelliv:mainfrom
amitayks:add-wolt-plugin

Conversation

@amitayks

@amitayks amitayks commented Aug 8, 2026

Copy link
Copy Markdown

Adds a wolt plugin: search venues, read menus, price and place/track/cancel real food & grocery orders on the owner's own Wolt account (Israel + global).

Shape (follows the repo conventions)

  • Single self-contained packages/runline-plugins/wolt/src/index.ts, direct fetch, no external deps.
  • Object-literal inputSchema/setConnectionSchema like the other plugins.
  • Refresh-token + saved-card rotation persisted via ctx.updateConnection (same pattern as gmail/googleCalendar).
  • access on every action + an ACCESS_CHECKLIST.md row + icon + README table row.

Actions (12)

Reads (anonymous): search, nearby, venue, menu (with normalised option groups — required flags, choices, prices), item, estimate, plus authed whoami, addresses, order_status
Writes: connect (owner login — see below), order_create, order_cancel

Onboarding (connect)

Headless, covers every Wolt account type: email code, email magic link, and the phone-merge path that reaches Google/social/phone-only accounts. Each email/SMS send is fronted by a passive hCaptcha token (captcha/vnCaptcha/smsCaptcha) minted in a real browser on a wolt.com origin; redeeming a link is the only send-free step. After success, the rotating refresh token drives everything.

Safety

Purchase-eligible by design — placing an order spends real money. order_create returns a priced preview + requiresConfirmation and only places a real order when the connection sets allowOrdering: true and the caller passes confirm: true. order_cancel is self-service only before the venue accepts (else Wolt returns error_code 4051). Payment is the account's saved card; Google Pay is not replayable headless. Prices are integer minor units (agorot in ISR). Single-tenant: one account per connection.

Verification

  • bun --filter runline build passes; tsc --noEmit clean for the plugin.
  • Anonymous reads verified live via the SDK (search "sushi" → venues; menu → 210 items / 25 categories).
  • The full authenticated connect → order → track → cancel cycle mirrors the reference connector proven live against a real account.

Amitay Keisar and others added 3 commits August 8, 2026 21:14
…r account)

Self-contained plugin for the owner's Wolt account. Reads are anonymous
against Wolt's public JSON surface; ordering is authenticated and gated.

- anonymous reads: search, nearby, venue, menu (normalised option groups),
  item, estimate
- headless connect: every account type (email code, email magic link, and
  the phone-merge path that reaches Google/social/phone-only accounts). Each
  email/SMS send carries a passive hCaptcha token; refresh token + saved card
  persisted via ctx.updateConnection
- gated ordering: order_create (priced preview -> confirm places a real order
  on the saved card), order_status (track), order_cancel — behind
  allowOrdering + confirm:true
- access annotations on all 12 actions + ACCESS_CHECKLIST row + icon + README
- refresh() forces a token rotation so the rotating refresh token never lapses
- connect() returns a keepalive hint { every: '12h', prompt: 'call wolt.refresh()' }
  for the onboarding agent to wire a recurring schedule
- Wolt's refresh needs no live access token, so a slow cadence suffices
normPhone() prepended 972 only when the number didn't already start with 972,
mishandling 00-prefixed international (00972...) and bare-local input. Normalize
via the 00-exit / national-0 / bare-local branches so every form yields +972XXXXXXXXX.
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