Microsoft 365 MailReceivedTrigger

Microsoft 365 MailReceivedTrigger

Certified

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).

yaml
type: io.kestra.plugin.microsoft365.outlook.MailReceivedTrigger

Wait for new emails in inbox and iterate through them

yaml
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

yaml
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

yaml
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

Azure client ID

Application (client) ID of the Graph app registration

Azure client secret

Client secret for the app registration; required for client-credentials flow

Azure tenant ID

Entra tenant (directory) ID used for Graph auth

Defaultfalse

Specifies whether a trigger is allowed to start a new execution even if a previous run is still in progress.

OData filter

Graph OData filter, e.g., from/emailAddress/address eq sender@example.com or hasAttachments eq true

Defaultinbox

Folder ID or name

Mailbox folder to monitor (e.g., inbox, drafts, sentitems, deleteditems, or folder ID)

Defaultfalse

Include attachments

If true, downloads file attachments to Kestra internal storage

DefaultPT5M
Formatduration

Polling interval

ISO-8601 duration between polls; default PT5M

Default10

Max messages per poll

Maximum messages processed each poll

Defaulthttps://graph.microsoft.com/.default

Scopes

Space-separated Graph scopes; default uses .default application permissions

State key

Custom key for persisted state; defaults to trigger ID

State TTL

TTL for state entries (e.g., PT24H, P30D); after expiry messages may retrigger

SubTypestring
Possible Values
CREATEDSUBMITTEDRUNNINGPAUSEDRESTARTEDKILLINGSUCCESSWARNINGFAILEDKILLEDCANCELLEDQUEUEDRETRYINGRETRIEDSKIPPEDBREAKPOINTRESUBMITTED

List of execution states after which a trigger should be stopped (a.k.a. disabled).

User email

Mailbox to monitor; if not specified, uses the authenticated user's mailbox.

User principal name

Mailbox UPN/email to act on; defaults to app context when omitted

Defaulttrue

A 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.

Number of new messages

The folder that was monitored

List of new messages that triggered the flow

Definitions
attachmentsarray

List of attachments with URIs to stored files in Kestra

contentTypestring

Content type

idstring

Attachment ID

isInlineboolean

Whether the attachment is inline

namestring

Attachment name

sizeinteger

Size in bytes

uristring
Formaturi

URI to the downloaded attachment in Kestra's internal storage

bodystring

Full message body content

bodyContentTypestring

Body content type (Text or HTML)

bodyPreviewstring

Preview of the message body

ccRecipientsarray
SubTypestring

CC recipients

fromstring

Sender email address

fromNamestring

Sender name

hasAttachmentsboolean

Whether the message has attachments

idstring

Message ID

importancestring

Message importance (Low, Normal, High)

isReadboolean

Whether the message has been read

receivedDateTimestring
Formatdate-time

Date and time the message was received

sentDateTimestring
Formatdate-time

Date and time the message was sent

subjectstring

Email subject

toRecipientsarray
SubTypestring

To recipients