MyBotBoxMyBotBox

Google Tasks

Trigger workflows on Google Tasks created, completed, or updated across one or more lists.

The Google Tasks trigger polls the Google Tasks API on a configurable cadence and fires the workflow for each changed task. It's the right trigger for to-do-driven automation — for example, sending a Slack message when a task is marked complete, or kicking off a provisioning workflow when a task is created in a specific list.

Built on the generic tasks_poller_state table, so future providers (Todoist, Microsoft To Do, Asana, Trello) slot into the same pattern without schema changes.

Setup

  1. Drop the Google Tasks block onto your workflow as the entry point.
  2. Select a Google account — OAuth scope requested is tasks.readonly. If you've already connected a Google account for Gmail or Calendar, the same credential works.
  3. Pick one or more lists — the dropdown populates from your Google Tasks lists (@default is always available).
  4. Choose eventstask_completed (fires only on the completion transition) and task_updated (fires on any change, including new tasks — Google Tasks' API doesn't distinguish creation from modification).
  5. Pick a cadence tier — 5m / 15m / 30m / 60m. Matches the Cloud Scheduler poll tiers.
  6. Save.

Google Tasks has no push/webhook API — this is poll-based. The 5m tier is the fastest available; typical latency from task change to workflow fire is cadence/2 + a few seconds.

Block outputs

Access via dot notation: <googletasks1.title>, <googletasks1.status>, etc.

OutputTypeDescription
taskIdstringGoogle Tasks task ID
titlestringTask title
statusstringneedsAction or completed
duestring | nullISO-8601 due date, or null
notesstringFree-form task notes
listIdstringSource list ID — useful for routing when watching multiple lists
listTitlestringHuman-readable list title
eventstringWhich event fired: task_completed or task_updated
updatedAtstringTask last-modified timestamp
taskobjectFull task resource from the Google Tasks API

How event types are classified

Google Tasks doesn't emit typed events — it only exposes a diff-since cursor, and the API doesn't let us distinguish task creation from other modifications without maintaining our own per-task seen-set. The trigger therefore exposes two events:

  • task_completed — task has status === 'completed' and a completed timestamp set. Fires on the completion transition.
  • task_updated — everything else (new tasks, title/notes edits, due-date changes, moves between lists). "Updated" here is a superset that includes creations.

If an edit changes both completion and title, the trigger fires once classified as task_completed (completion takes priority). Use <block.event> to route between the two.

Multi-list support

Select multiple lists in the Task lists dropdown. Each list is polled independently on its own cadence — one row per (trigger, list) in the backing state table. A single workflow run handles one task at a time; if 5 tasks change across 3 lists, the workflow fires 5 times (with <block.listId> identifying the source).

Good pattern: one trigger per workflow + multi-list when you want a single downstream fan-out. Use separate triggers per list when you want per-list logic (different cadences, different events).

Cadence and cost

TierUse caseAPI quota usage
5mResponsive automation (incidents, real-time assignment)High — 288 polls/day per list
15m (default)Most productivity workflowsModerate — 96 polls/day per list
30mDaily-digest, low-urgency syncLow
60mArchival, reportingLowest

Google Tasks API quota is generous (~50k reads/day default). Even at 5m × 10 lists that's ~2 880 reads/day — well under limit.

Idempotency

Cursor is the ISO-8601 updated timestamp of the latest task seen. The API returns only tasks with updated > cursor, so the platform never re-fires for an unchanged task. If a workflow run fails, the next poll picks the same task up again (the cursor advances only on successful poll-completion).

Failure handling

  • Consecutive auth failures (expired OAuth + no refresh token) surface as a red health dot on the block.
  • After 3 consecutive failures the block flags itself in the UI; fix by re-authorising the Google credential.
  • The poll row remains in tasks_poller_state with consecutive_failures incremented and last_error populated — visible in trigger admin views.

Verifying a poller

Google Tasks is poll-based — there's no inbound webhook URL. Force-run the dispatcher per apps/sat/tests/staging/triggers/pollers/README.md:

POLL_DISPATCH_SECRET=$(gcloud secrets versions access latest \
  --secret=poll-dispatch-secret --project=ystudio-core)

curl -X POST -H "x-scheduler-key: $POLL_DISPATCH_SECRET" \
  'https://mybotbox.com/api/webhooks/poll/dispatch?tier=15m'

Extending to other task providers

The trigger's storage (tasks_poller_state with a provider discriminator) and dispatcher (/api/webhooks/poll/dispatch) are provider-agnostic. Adding Todoist / Microsoft To Do / Asana later is a ~1-file change: drop a new adapter in apps/sat/lib/triggers/<provider>/poller-adapter.ts, register a run endpoint, and add a branch in the dispatcher's provider switch. No schema changes.

When Google Tasks isn't the right fit

  • Sub-5-minute latency — use a calendar-based trigger (Calendar event start), Pub/Sub push (Gmail), or an incoming webhook from a tool that posts directly.
  • Task-creation-only — not possible without extra state; filter on events: ['task_updated'] and dedupe on taskId downstream.
  • Assignee-specific logic — Google Tasks doesn't expose assignees; use a workflow with Google Calendar or a dedicated project management tool.