MyBotBoxMyBotBox

Outlook

Trigger workflows on new emails received in Outlook (Microsoft Graph polling).

The Outlook trigger polls a Microsoft 365 / Outlook.com mailbox at a configurable cadence and fires the workflow once per new message. Like Gmail, Outlook supports change notifications, but the renewal limit (max 4230 minutes ≈ 70h) makes them brittle for long-lived workflows — the platform polls instead for predictability.

How to configure

  1. Connect a Microsoft credential first. Open Workspace → Credentials → Add Microsoft account and complete the OAuth consent. Required Microsoft Graph scopes: Mail.Read (and Mail.ReadWrite if you toggle Mark as read). Personal accounts (outlook.com / hotmail.com) and Microsoft 365 work tenants are both supported.
  2. Microsoft Graph supports change-notification subscriptions, but their renewal limit (max 4230 minutes ≈ 70 hours) makes them brittle for long-lived workflows — so the platform polls instead. The scheduler hits GET /me/mailFolders/<folder>/messages?$filter=receivedDateTime gt <cursor> at the configured cadence (5/15/30/60 minutes) and dedupes on the message ID.
  3. Each new message fires once. Downstream blocks read <outlook1.email.subject>, <outlook1.email.from>, <outlook1.email.bodyText>, <outlook1.email.hasAttachments>. Folder defaults to Inbox; pick a different folder if you want to watch a specific category. Attachments are fetched via GET /messages/<id>/attachments only when you enable the include-attachments toggle.
  4. Verify by sending a test email from another address. Expect a fire within one cadence interval. To force an immediate poll, use the dispatcher per the triggers runbook:
curl -X POST -H "x-scheduler-key: $POLL_DISPATCH_SECRET" \
  'https://mybotbox.com/api/webhooks/poll/dispatch?tier=5m'

Authentication

OAuth-only via your connected Microsoft credential. Required Microsoft Graph scopes:

ScopeWhy
Mail.ReadList + read messages from mailFolders
Mail.ReadWriteMark messages as read after firing (optional toggle)

Both personal Microsoft accounts (outlook.com / hotmail.com) and tenant work accounts are supported via the common endpoint.

Sample payload

{
  "email": {
    "id": "AAMkAGI2NGFhMjY3LWMzM2YtNDk5MS04MzIzLWY3OWM2YzEzZDg2NwBGAAAAAAA=",
    "conversationId": "AAQkAGI2NGFhMjY3LWMzM2YtNDk5MS04MzIzLWY3OWM2YzEzZDg2NwAQAA==",
    "subject": "Q2 board prep — agenda draft",
    "from": "chair@example.com",
    "to": "alex@example.com",
    "cc": "cfo@example.com",
    "date": "2026-04-26T20:45:00.000Z",
    "bodyText": "Sharing the draft agenda for the May board meeting. Comments by Friday please.",
    "bodyHtml": "<p>Sharing the draft agenda for the May board meeting. <strong>Comments by Friday please.</strong></p>",
    "hasAttachments": true,
    "isRead": false,
    "folderId": "AQMkAGI2NGFhMjY3LWMzM2YtNDk5MS04MzIzLWY3OWM2YzEzZDg2NwAuAAADAQAAAA==",
    "messageId": "<AS1PR0MB1234.namprd00.prod.outlook.com>",
    "threadId": "AAQkAGI2NGFhMjY3LWMzM2YtNDk5MS04MzIzLWY3OWM2YzEzZDg2NwAQAA=="
  },
  "timestamp": "2026-04-26T20:45:08.456Z"
}

Verifying a poller

There is no inbound webhook URL — pollers are driven by the internal dispatcher. See apps/sat/tests/staging/triggers/pollers/README.md. To force an immediate poll across all due Outlook triggers:

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=5m'

Troubleshooting

  • Trigger never fires — confirm the Microsoft credential has Mail.Read granted (work tenants sometimes require admin consent for app-level scopes).
  • consecutive_failures rising in mailbox_poller_state — usually a Microsoft Graph 401 from refresh-token expiry. Re-authorize the credential.
  • Folder not found — the folderId you typed doesn't match a Graph mailbox folder. Use the literal Inbox or fetch IDs via GET /me/mailFolders once and paste the actual ID.
  • Attachments missing — toggle Include attachments on. Without the toggle, Graph only returns message metadata; attachments are not fetched (saves quota).