
Microsoft 365 MailReceivedTrigger
CertifiedTrigger on new Outlook mail
Microsoft 365 MailReceivedTrigger
Trigger on new Outlook mail
Polls a mailbox folder for new messages using Graph. Optional OData filter and attachment download to Kestra storage. Requires Microsoft Graph permission Mail.Read (application).
type: io.kestra.plugin.microsoft365.outlook.MailReceivedTriggerExamples
Wait for new emails in inbox and iterate through them
id: outlook_listen
namespace: company.team
tasks:
- id: each
type: io.kestra.plugin.core.flow.EachSequential
value: "{{ trigger.messages }}"
tasks:
- id: log
type: io.kestra.plugin.core.debug.Return
format: "New email: {{ taskrun.value.subject }}"
triggers:
- id: watch
type: io.kestra.plugin.microsoft365.outlook.MailReceivedTrigger
interval: PT5M
tenantId: "{{ secret('AZURE_TENANT_ID') }}"
clientId: "{{ secret('AZURE_CLIENT_ID') }}"
clientSecret: "{{ secret('AZURE_CLIENT_SECRET') }}"
userEmail: "user@example.com"
folderId: "inbox"
Wait for emails with attachments and process them
id: outlook_with_attachments
namespace: company.team
tasks:
- id: each
type: io.kestra.plugin.core.flow.EachSequential
value: "{{ trigger.messages }}"
tasks:
- id: process
type: io.kestra.plugin.core.debug.Return
format: "Processing {{ taskrun.value.subject }} with {{ taskrun.value.attachments | length }} attachments"
- id: each_attachment
type: io.kestra.plugin.core.flow.EachSequential
values: "{{ taskrun.value.attachments }}"
tasks:
- id: log_attachment
type: io.kestra.plugin.core.log.Log
message: "Attachment: {{ taskrun.value.name }} stored at {{ taskrun.value.uri }}"
triggers:
- id: watch
type: io.kestra.plugin.microsoft365.outlook.MailReceivedTrigger
interval: PT2M
tenantId: "{{ secret('AZURE_TENANT_ID') }}"
clientId: "{{ secret('AZURE_CLIENT_ID') }}"
clientSecret: "{{ secret('AZURE_CLIENT_SECRET') }}"
userEmail: "invoices@company.com"
folderId: "inbox"
filter: "hasAttachments eq true"
includeAttachments: true
Wait for emails from specific sender
id: outlook_filtered_sender
namespace: company.team
tasks:
- id: process
type: io.kestra.plugin.core.log.Log
message: "Received {{ trigger.count }} email(s) from important sender"
triggers:
- id: watch
type: io.kestra.plugin.microsoft365.outlook.MailReceivedTrigger
interval: PT1M
tenantId: "{{ secret('AZURE_TENANT_ID') }}"
clientId: "{{ secret('AZURE_CLIENT_ID') }}"
clientSecret: "{{ secret('AZURE_CLIENT_SECRET') }}"
userEmail: "user@example.com"
filter: "from/emailAddress/address eq 'boss@company.com'"
stateTtl: P30D
Properties
clientId *Requiredstring
Azure client ID
Application (client) ID of the Graph app registration
clientSecret *Requiredstring
Azure client secret
Client secret for the app registration; required for client-credentials flow
tenantId *Requiredstring
Azure tenant ID
Entra tenant (directory) ID used for Graph auth
allowConcurrent Non-dynamicboolean
falseSpecifies whether a trigger is allowed to start a new execution even if a previous run is still in progress.
filter string
OData filter
Graph OData filter, e.g., from/emailAddress/address eq sender@example.com or hasAttachments eq true
folderId string
inboxFolder ID or name
Mailbox folder to monitor (e.g., inbox, drafts, sentitems, deleteditems, or folder ID)
includeAttachments booleanstring
falseInclude attachments
If true, downloads file attachments to Kestra internal storage
interval Non-dynamicstring
PT5MdurationPolling interval
ISO-8601 duration between polls; default PT5M
maxMessages integerstring
10Max messages per poll
Maximum messages processed each poll
scopes string
https://graph.microsoft.com/.defaultScopes
Space-separated Graph scopes; default uses .default application permissions
stateKey string
State key
Custom key for persisted state; defaults to trigger ID
stateTtl string
State TTL
TTL for state entries (e.g., PT24H, P30D); after expiry messages may retrigger
stopAfter Non-dynamicarray
CREATEDSUBMITTEDRUNNINGPAUSEDRESTARTEDKILLINGSUCCESSWARNINGFAILEDKILLEDCANCELLEDQUEUEDRETRYINGRETRIEDSKIPPEDBREAKPOINTRESUBMITTEDList of execution states after which a trigger should be stopped (a.k.a. disabled).
userEmail string
User email
Mailbox to monitor; if not specified, uses the authenticated user's mailbox.
userPrincipalName string
User principal name
Mailbox UPN/email to act on; defaults to app context when omitted
when string
trueA condition that determines whether the trigger should run.
A Pebble expression evaluated at trigger time. The trigger fires only when the expression evaluates to a truthy value (true, a non-empty string, a non-zero number). Use this to gate trigger execution on dynamic runtime values such as execution labels, flow variables, or environment conditions.
Outputs
count integer
Number of new messages
folderId string
The folder that was monitored
messages array
List of new messages that triggered the flow
io.kestra.plugin.microsoft365.outlook.MailReceivedTrigger-EmailMessage
List of attachments with URIs to stored files in Kestra
io.kestra.plugin.microsoft365.outlook.MailReceivedTrigger-AttachmentData
Content type
Attachment ID
Whether the attachment is inline
Attachment name
Size in bytes
uriURI to the downloaded attachment in Kestra's internal storage
Full message body content
Body content type (Text or HTML)
Preview of the message body
CC recipients
Sender email address
Sender name
Whether the message has attachments
Message ID
Message importance (Low, Normal, High)
Whether the message has been read
date-timeDate and time the message was received
date-timeDate and time the message was sent
Email subject
To recipients