Skip to main content

FromMicrosoftGraphEmailNodeConfiguration

Namespace: Meshmakers.Octo.MeshAdapter.Nodes.Trigger

Configuration for polling an Office 365 mailbox folder via Microsoft Graph API. Processes every message in the configured folder (the folder is the work queue — no unread filtering) and optionally moves successfully processed messages to a different folder.

public record FromMicrosoftGraphEmailNodeConfiguration : TriggerNodeConfiguration, INodeConfiguration, IEquatable<NodeConfiguration>, ITriggerNodeConfiguration, IEquatable<TriggerNodeConfiguration>, IEquatable<FromMicrosoftGraphEmailNodeConfiguration>

Inheritance Object → NodeConfiguration → TriggerNodeConfiguration → FromMicrosoftGraphEmailNodeConfiguration
Implements INodeConfiguration, IEquatable<NodeConfiguration>, ITriggerNodeConfiguration, IEquatable<TriggerNodeConfiguration>, IEquatable<FromMicrosoftGraphEmailNodeConfiguration>

Properties​

ServerConfiguration​

The global configuration key for the Microsoft Graph OAuth2 settings (references a MicrosoftGraphConfiguration entity by WellKnownName)

public string ServerConfiguration { get; set; }

Property Value​

String

PollingIntervalSeconds​

Polling interval in seconds to check for new messages

public int PollingIntervalSeconds { get; set; }

Property Value​

Int32

Mailbox​

The mailbox to poll (user principal name, e.g. user@company.com). Optional when FromMicrosoftGraphEmailNodeConfiguration.SettingsConfiguration supplies it — a value read from the settings configuration takes precedence over this one, so the mailbox need not (and should not) be hard-coded in the pipeline definition.

public string Mailbox { get; set; }

Property Value​

String

FolderPath​

Path of the mail folder to poll, segments separated by '/' (e.g. "Archive/Invoices/ToDo"). The path is resolved relative to the mailbox root — the pipeline never looks at the inbox unless the path points there. A folder whose own name contains a slash is written with \/ — "Inbox/02_Steuern / Finanzen" addresses the folder "02_Steuern / Finanzen" below the inbox (AB#5385) — and a backslash with \\; any other backslash is literal. The same escapes work in FromMicrosoftGraphEmailNodeConfiguration.MoveToFolderPathOnSuccess and FromMicrosoftGraphEmailNodeConfiguration.MoveToFolderPathOnFailure, and ListMailFolders@1 emits paths in exactly this form (AB#5370). Optional when FromMicrosoftGraphEmailNodeConfiguration.SettingsConfiguration supplies it (the settings value takes precedence).

public string FolderPath { get; set; }

Property Value​

String

MoveToFolderPathOnSuccess​

Optional folder path the message is moved to after the pipeline run for that message completed successfully (e.g. "Archive/Invoices/Done"). The leaf folder is created if it does not exist yet (its parent path must exist). Messages whose pipeline run failed stay in the source folder. Same syntax as FromMicrosoftGraphEmailNodeConfiguration.FolderPath (a slash inside a name is \/). A value from FromMicrosoftGraphEmailNodeConfiguration.SettingsConfiguration takes precedence.

public string MoveToFolderPathOnSuccess { get; set; }

Property Value​

String

MoveToFolderPathOnFailure​

Optional folder path a message is moved to once it failed FromMicrosoftGraphEmailNodeConfiguration.MaxAttemptsPerMessage times (e.g. "Archive/Invoices/Failed"). The leaf folder is created if it does not exist yet (its parent path must exist). Without it, exhausted messages stay in the source folder and are skipped. Attempts are tracked on the message itself (an Outlook category marker), so the count survives adapter restarts — including runs that kill the process (e.g. an OOM) and therefore never report a failure.

public string MoveToFolderPathOnFailure { get; set; }

Property Value​

String

Remarks:

Set this wherever the import matters: it is not only where poison mails are parked, it is also the only user-facing way back. A parked message is marked OctoMesh-Import-Failed, and moving it back into FromMicrosoftGraphEmailNodeConfiguration.FolderPath clears every import marker and imports it again with a full attempt budget — no Graph access, no category editing, no adapter restart (AB#5260). Without a failure folder there is nowhere to move a message back from, and an exhausted message sits in the source folder unnoticed. A path that cannot be resolved degrades to "skip exhausted messages" and is logged; it never stops the import as a whole.

SettingsConfiguration​

Optional well-known name of a configuration entity that carries the runtime mailbox / folder settings, so they live in configuration instead of the pipeline definition (a redeploy then never overwrites what an operator set, and nothing tenant-specific leaks into the seed). The configuration must be reachable from the pipeline through a System.Communication/Uses association. The node stays domain-agnostic: the attribute names it reads are given by FromMicrosoftGraphEmailNodeConfiguration.MailboxAttribute / FromMicrosoftGraphEmailNodeConfiguration.SourceFolderAttribute / FromMicrosoftGraphEmailNodeConfiguration.DoneFolderAttribute (and optionally FromMicrosoftGraphEmailNodeConfiguration.PollingSecondsAttribute). Values found here override the corresponding node properties above; a name that resolves to nothing falls back to the node property.

public string SettingsConfiguration { get; set; }

Property Value​

String

MailboxAttribute​

Attribute name on FromMicrosoftGraphEmailNodeConfiguration.SettingsConfiguration holding the mailbox (case-insensitive).

public string MailboxAttribute { get; set; }

Property Value​

String

SourceFolderAttribute​

Attribute name on FromMicrosoftGraphEmailNodeConfiguration.SettingsConfiguration holding the source folder path.

public string SourceFolderAttribute { get; set; }

Property Value​

String

DoneFolderAttribute​

Attribute name on FromMicrosoftGraphEmailNodeConfiguration.SettingsConfiguration holding the move-to-on-success folder path.

public string DoneFolderAttribute { get; set; }

Property Value​

String

PollingSecondsAttribute​

Optional attribute name on FromMicrosoftGraphEmailNodeConfiguration.SettingsConfiguration holding the poll interval in seconds. When present and a positive integer it overrides FromMicrosoftGraphEmailNodeConfiguration.PollingIntervalSeconds.

public string PollingSecondsAttribute { get; set; }

Property Value​

String

FailedFolderAttribute​

Optional attribute name on FromMicrosoftGraphEmailNodeConfiguration.SettingsConfiguration holding the move-to-on-failure folder path (overrides FromMicrosoftGraphEmailNodeConfiguration.MoveToFolderPathOnFailure when present, AB#5142).

public string FailedFolderAttribute { get; set; }

Property Value​

String

MaxMessagesPerPoll​

Maximum number of messages fetched per polling cycle (oldest first)

public int MaxMessagesPerPoll { get; set; }

Property Value​

Int32

SenderFilter​

Optional filter for the sender address (contains match)

public string SenderFilter { get; set; }

Property Value​

String

MaxAttemptsPerMessage​

Number of times a failing message is tried (one attempt per polling cycle) before it is skipped — or moved to FromMicrosoftGraphEmailNodeConfiguration.MoveToFolderPathOnFailure when that is configured. The attempt count is stamped on the message as an Outlook category before each run, so it survives adapter restarts and counts runs that never returned (process death).

public int MaxAttemptsPerMessage { get; set; }

Property Value​

Int32

Remarks:

The markers (OctoMesh-Import-Attempt-N and OctoMesh-Import-Failed) are registered in the mailbox's master category list on first use so Outlook and OWA actually render them — a category the mailbox does not know is invisible in the UI. That registration needs the MailboxSettings.ReadWrite Graph scope; without it the markers still count, they are merely invisible, and the node logs one warning. Removing a marker by hand resets the message on the next poll (AB#5260).

IncludeInternetMessageHeaders​

Fetches the mail's internet message headers and surfaces the ones named in FromMicrosoftGraphEmailNodeConfiguration.InternetMessageHeaderNames on EmailData.Headers, plus the parsed SPF/DKIM/DMARC verdicts on EmailData.Authentication. AB#5011.

public bool IncludeInternetMessageHeaders { get; set; }

Property Value​

Boolean

Remarks:

Off by default and inert when off: an existing pipeline sees exactly the shape it saw before. Turn it on where the pipeline acts on the sender address — a sender gate, a per-vendor rule, anything that turns a mail into a document — because From: alone is a field anybody can write, and Authentication-Results is the only part of the mail that says whether the claimed sender really sent it.

Microsoft Graph does not return internetMessageHeaders unless it is selected explicitly, which is why the header was simply absent before this flag existed. Selecting it makes the per-message response noticeably larger (the full Received chain and the DKIM signatures come with it), which is why only the named headers are surfaced.

InternetMessageHeaderNames​

Header names surfaced on EmailData.Headers when FromMicrosoftGraphEmailNodeConfiguration.IncludeInternetMessageHeaders is on. Case insensitive. Leave unset for the authentication-relevant default set (Authentication-Results, Authentication-Results-Original, Received-SPF, ARC-Authentication-Results).

public String[] InternetMessageHeaderNames { get; set; }

Property Value​

String[]

Remarks:

A filter rather than "everything", because the headers land in the pipeline data context: the full set is several kilobytes of Received chain and base64 signatures per message, echoed into every debug view and persisted by SetPipelineExecutionResult@1. Authentication-Results is always fetched regardless of this list — it is what EmailData.Authentication is parsed from, and a list that omitted it would silently turn the verdicts off while the flag says they are on.

PostProcessingMode​

Post-processing applied to a message once its pipeline run confirmed the import (AB#5345) — the same three modes the IMAP channel offers, so a settings page can present ONE choice for both. Overrides FromMicrosoftGraphEmailNodeConfiguration.MoveToFolderPathOnSuccess / FromMicrosoftGraphEmailNodeConfiguration.MoveToFolderPathOnFailure when set.

⚠️ UNSET is the migration path and means "keep doing what this pipeline already did": the mode is then DERIVED — a configured done or failed folder ⇒ MailPostProcessingMode.MoveToFolders, which is byte for byte what this node did before.

🔴 No folder at all is a configuration error rather than a mode (AB#5372): the trigger start FAILS naming the three valid modes. None = 0 existed until then — "leave it in the source folder" — and was a defect. Nothing in OctoMesh records which mail was already processed, the mailbox IS the bookkeeping, and the three modes work precisely because each takes the message out of what the next poll reads. Leaving it there re-reads the same FromMicrosoftGraphEmailNodeConfiguration.MaxMessagesPerPoll messages for ever and never reaches the mail behind the cap, so the import runs for ever, reports success and imports nothing new (AB#5336).

Still nullable and still only read through ResolveEffectivePostProcessingMode, never directly: the pipeline definition deserializer is YamlDotNet, where a key that is PRESENT and null overwrites a property initializer. On a non-nullable enum that would yield the zero value, which is now no member at all; nullable, such a key reads as "unset" and the derivation above decides.

The attempt parking (OctoMesh-Import-Attempt-N / OctoMesh-Import-Failed categories, FromMicrosoftGraphEmailNodeConfiguration.MaxAttemptsPerMessage) belongs to MailPostProcessingMode.MoveToFolders and stays GRAPH-ONLY: it needs a per-message marker the mailbox persists across a process death, which is an Outlook category here and has no IMAP counterpart this node could rely on across servers. Under MailPostProcessingMode.Delete and MailPostProcessingMode.MarkAsRead there is nowhere to park a message, so the attempts are still counted and an exhausted message is skipped rather than moved.

public Nullable<MailPostProcessingMode> PostProcessingMode { get; set; }

Property Value​

Nullable<MailPostProcessingMode>

SuccessPath​

Path into the pipeline's result data that CONFIRMS the message was imported (AB#5345, the same contract FromEmail@1 has carried since AB#5337). The post-processing configured above happens only when it resolves to the boolean true; anything else — absent, null, false, a string, a number — leaves the message exactly where it is.

🔴 Why this exists: this node used to decide done-or-failed on "ExecuteAsync did not throw", and that is not a statement about the import. A pipeline ends normally while a node reported an error and stopped its branch — MakeHttpRequest@1's LogAndStop is defined to do that ("leaving the execution successful") — and no per-node status reaches a trigger. A mail could therefore be filed under "Done" with nothing in the inbox to show for it.

⚠️ UNSET keeps the pre-AB#5345 behaviour exactly: a run that came back post-processes its message. A stricter default would make every deployed FromMicrosoftGraphEmail@1 stop moving anything and re-offer its whole source folder on every poll. What is NEVER traded is the run that threw: that one leaves the mailbox untouched whatever this is set to.

Write the flag as the LAST step of the import branch (e.g. SetPrimitiveValue@1 targetPath: $.importCompleted, value: true, valueType: Boolean) — placed there, a branch that stopped early never reaches it.

Syntax: a plain path from the pipeline data root, optionally with the $. prefix ($.importCompleted, result.ok). Array indexes, wildcards and filters are rejected when the trigger starts — a confirmation must name exactly one value.

public string SuccessPath { get; set; }

Property Value​

String

PostProcessingModeAttribute​

Attribute on FromMicrosoftGraphEmailNodeConfiguration.SettingsConfiguration holding the post-processing mode NAME (MailPostProcessingMode). Names only — a number there is ignored, see ConfigurationSettingsReader.ReadEnum.

⚠️ An unknown name means "not configured" and hands the decision back to FromMicrosoftGraphEmailNodeConfiguration.PostProcessingMode — with ONE exception: a stored None FAILS the trigger start (AB#5372), because reading a removed mode as "not configured" would silently replace it with the derived one.

public string PostProcessingModeAttribute { get; set; }

Property Value​

String

MaxMessagesPerPollAttribute​

Attribute holding the per-poll batch cap (FromMicrosoftGraphEmailNodeConfiguration.MaxMessagesPerPoll).

public string MaxMessagesPerPollAttribute { get; set; }

Property Value​

String

SenderFilterAttribute​

Attribute holding the sender filter (FromMicrosoftGraphEmailNodeConfiguration.SenderFilter).

public string SenderFilterAttribute { get; set; }

Property Value​

String

SuccessPathAttribute​

Attribute holding the import confirmation path (FromMicrosoftGraphEmailNodeConfiguration.SuccessPath). Rarely worth configuring — the path is a contract between this trigger and the pipeline it starts, both of which ship together — but it is a setting like the others and behaves like them.

public string SuccessPathAttribute { get; set; }

Property Value​

String

CallerBinding​

public CallerBindingMode CallerBinding { get; set; }

Property Value​

CallerBindingMode

Description​

public string Description { get; set; }

Property Value​

String

Constructors​

FromMicrosoftGraphEmailNodeConfiguration()​

public FromMicrosoftGraphEmailNodeConfiguration()