FromEmailNodeConfiguration
Namespace: Meshmakers.Octo.MeshAdapter.Nodes.Trigger
Configuration for node FromEmail
public record FromEmailNodeConfiguration : TriggerNodeConfiguration, INodeConfiguration, IEquatable<NodeConfiguration>, ITriggerNodeConfiguration, IEquatable<TriggerNodeConfiguration>, IEquatable<FromEmailNodeConfiguration>
Inheritance Object → NodeConfiguration → TriggerNodeConfiguration → FromEmailNodeConfiguration
Implements INodeConfiguration, IEquatable<NodeConfiguration>, ITriggerNodeConfiguration, IEquatable<TriggerNodeConfiguration>, IEquatable<FromEmailNodeConfiguration>
Fields
DefaultMaxMessagesPerPoll
Default for FromEmailNodeConfiguration.MaxMessagesPerPoll, resolved where the value is read.
public static int DefaultMaxMessagesPerPoll;
Properties
ServerConfiguration
The global configuration key for the email server settings
public string ServerConfiguration { get; set; }
Property Value
PollingIntervalSeconds
Polling interval in seconds to check for new emails
public int PollingIntervalSeconds { get; set; }
Property Value
MaxMessagesPerPoll
Maximum number of messages fetched and dispatched in a single polling pass (AB#5336). Each message is downloaded in full and its attachments are base64-encoded into the batch, so an unbounded result set is an out-of-memory failure on any mailbox with history. A backlog is drained over consecutive polls instead. Values <= 0 mean "no limit" and are not recommended.
Nullable with the default resolved at the call site on purpose: the pipeline definition deserializer is YamlDotNet, where a key that is PRESENT and null overwrites a property initializer. On a non-nullable int that yields 0 — which this node reads as the deliberate "no limit" opt-out, so an explicit null would silently switch the OOM protection back off.
public Nullable<int> MaxMessagesPerPoll { get; set; }
Property Value
OnlyUnread
Whether to only process unread emails
public bool OnlyUnread { get; set; }
Property Value
MarkAsRead
Whether to mark emails as read after a CONFIRMED import.
public bool MarkAsRead { get; set; }
Property Value
Remarks:
Superseded by FromEmailNodeConfiguration.PostProcessingMode (AB#5345) and read only while no mode is
set, where it derives MailPostProcessingMode.MarkAsRead. Kept — rather than
removed — because every deployed FromEmail@1 names it, and a property a released
node stops honouring turns other tenants' pipelines into silent behaviour changes.
DeleteAfterProcessing
Whether to delete emails after a CONFIRMED import.
public bool DeleteAfterProcessing { get; set; }
Property Value
Remarks:
Superseded by FromEmailNodeConfiguration.PostProcessingMode (AB#5345) and read only while no mode is set, where it derives MailPostProcessingMode.Delete and wins over FromEmailNodeConfiguration.MarkAsRead.
SuccessPath
Path into the pipeline's result data that CONFIRMS the batch was imported (AB#5337).
\Seen / \Deleted are written back only when it resolves to the boolean
true; anything else — absent, null, false, a string, a number — leaves the
mails exactly as the server has them, so a later restart offers them again.
🔴 Why this exists: a pipeline can end perfectly normally while a node reported an error and
stopped its branch — that is what MakeHttpRequest@1's LogAndStop is defined to
do ("leaving the execution successful") — and the platform surfaces no per-node status to a
trigger: the execution status is Completed unless something threw, and
ExecuteAsync returns the pipeline's data root, nothing else. Without a confirmation
the trigger cannot see such a branch, so this is the only way to make the write-back
conditional on the import itself.
⚠️ UNSET keeps the pre-AB#5337 behaviour: a run that came back flags its mails. A stricter
default would stop every deployed FromEmail@1 from marking anything read and re-offer
its whole SINCE window on every adapter restart — a certain fleet-wide regression
traded for one edge case. What is NEVER traded is the run that threw: that one leaves the
mailbox untouched whatever this is set to.
AB#5345 built on exactly this hook: the flag the pipeline writes here is now the BUSINESS
success criterion — "at least one inbox item was created" — and it gates every one of the
three FromEmailNodeConfiguration.PostProcessingModes, on this channel and on the Microsoft Graph one.
The evaluation itself moved to MailSuccessPath, which both triggers share.
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
SenderFilter
Optional filter for sender email address (contains match)
public string SenderFilter { get; set; }
Property Value
SubjectFilter
Optional filter for email subject (contains match)
public string SubjectFilter { get; set; }
Property Value
SinceDate
Only consider messages delivered on or after this date (AB#5340). Maps to the IMAP SINCE key,
which the server evaluates on the message's INTERNALDATE with date granularity and inclusive bounds.
Takes precedence over FromEmailNodeConfiguration.SinceDaysBack.
public Nullable<DateTime> SinceDate { get; set; }
Property Value
SinceDaysBack
Only consider messages delivered within the last N days (AB#5340). Relative alternative to FromEmailNodeConfiguration.SinceDate, which wins when both are configured. Values <= 0 are ignored.
public Nullable<int> SinceDaysBack { get; set; }
Property Value
WindowOpen
Whether this trigger currently has an import window at all (AB#5341). false means the
window is EMPTY and the trigger fetches nothing: it skips the whole polling pass — no search,
no download, no pipeline run — and picks up again by itself as soon as the value flips back.
This exists because "no cut-off" cannot express "import nothing". An absent
FromEmailNodeConfiguration.SinceDate / FromEmailNodeConfiguration.SinceDaysBack means "no date filter", which with
FromEmailNodeConfiguration.OnlyUnread switched off is the unbounded SearchQuery.All that killed the
adapter on prod-1 with 1697 mails (AB#5336) — the exact opposite of what an empty window has
to do. The accounting channel derives both values from the OPEN fiscal years, and "no fiscal
year is open" has to mean nothing is imported, not everything.
Deliberately NOT the operator's System/Enabled switch: that one is owned by whoever
configures the channel, and flipping it from a computation would both fight the operator and
require a DATA FLOW deploy to take effect (a disabled pipeline is dropped by
DeployDataFlow), which restarts every sibling trigger. This value rides on the settings
configuration instead, so a single-pipeline DeployPipeline@1 delivers it.
Nullable with the default resolved at the call site, for the YamlDotNet reason documented on
FromEmailNodeConfiguration.MaxMessagesPerPoll: a key that is PRESENT and null overwrites a property
initializer, and on a non-nullable bool that yields false — which would silently
switch a working mailbox off. Unset therefore reads as OPEN; see
FromEmailNode.ResolveWindowOpen.
public Nullable<bool> WindowOpen { get; set; }
Property Value
PostProcessingMode
Post-processing applied to a message once its pipeline run confirmed the import (AB#5345) — the same three modes the Microsoft Graph channel offers, so a settings page can present ONE choice for both. Overrides FromEmailNodeConfiguration.MarkAsRead / FromEmailNodeConfiguration.DeleteAfterProcessing when set.
⚠️ UNSET is the migration path and means "keep doing what this pipeline already did":
the mode is then DERIVED from the two legacy flags —
FromEmailNodeConfiguration.DeleteAfterProcessing ⇒ MailPostProcessingMode.Delete,
else FromEmailNodeConfiguration.MarkAsRead ⇒ MailPostProcessingMode.MarkAsRead. Both flags
on is not a lost combination: a deleted message is expunged, so the \Seen flag it
would also have carried is not observable by anyone.
🔴 There is no fourth mode that leaves the message alone, and neither flag set is a
configuration error rather than a mode (AB#5372): the trigger start FAILS naming the three
valid modes. None = 0 existed until then and was a defect. Nothing in OctoMesh records
which mail was already processed — the mailbox IS the bookkeeping, the IMAP search is
NotSeen, and the three modes work precisely because each takes the message out of that
search result. Leaving it in re-fetches the same FromEmailNodeConfiguration.MaxMessagesPerPoll messages on
every poll and never reaches the mail behind the cap, so the import runs for ever, reports
success and imports nothing new — the shape of 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 same answer a pipeline that omits the key gets.
public Nullable<MailPostProcessingMode> PostProcessingMode { get; set; }
Property Value
Nullable<MailPostProcessingMode>
SourceFolder
Folder polled as the work queue, overriding the Folder of the
FromEmailNodeConfiguration.ServerConfiguration entity when set. Optional: the connection entity is
still the place a plain single-folder import configures its folder; this exists because
MailPostProcessingMode.MoveToFolders needs a source folder that belongs to
the same triple as FromEmailNodeConfiguration.DoneFolder and FromEmailNodeConfiguration.FailedFolder.
public string SourceFolder { get; set; }
Property Value
DoneFolder
Folder a message is moved to once its import was confirmed, under
MailPostProcessingMode.MoveToFolders. Segments separated by / and
translated to the server's own hierarchy delimiter — the leaf is created when missing,
its parents must exist.
public string DoneFolder { get; set; }
Property Value
FailedFolder
Folder a message is moved to when its import was NOT confirmed, under MailPostProcessingMode.MoveToFolders. Left empty, such a message stays in the source folder.
Set it wherever the import matters: it is not only where a mail nobody could import is parked, it is also the way BACK — moving a message from here into the source folder offers it to the import again. Unlike the Graph channel this trigger does NOT count attempts per message (there is no IMAP counterpart to an Outlook category that survives a process death, and the IMAP batch is one execution for many messages rather than one per message), so a message whose batch was not confirmed is moved aside on that first unconfirmed run.
public string FailedFolder { get; set; }
Property Value
SettingsConfiguration
Optional well-known name of a configuration entity carrying the RUNTIME settings of this
trigger, so they live in configuration instead of the pipeline definition (AB#5345). The
configuration must be reachable from the pipeline through a
System.Communication/Uses association.
🔴 The rule this exists for: setting a setting must never rewrite a pipeline definition. The definition is release content — it is what a redeploy reinstates — while a poll interval or an "only unread" switch is operating state. Writing the latter into the former is how the accounting app moved one tenant's pipeline entity from v35 to v39 with nothing but a checkbox.
The node stays domain-agnostic: which attributes to read is given by the
*Attribute properties below. A value found there overrides the corresponding node
property; anything missing falls back to the node property, which is what keeps every
already deployed pipeline behaving exactly as before.
public string SettingsConfiguration { get; set; }
Property Value
PollingSecondsAttribute
Attribute holding the poll interval in seconds (positive integers only).
public string PollingSecondsAttribute { get; set; }
Property Value
OnlyUnreadAttribute
Attribute holding the "only unread" switch (FromEmailNodeConfiguration.OnlyUnread).
public string OnlyUnreadAttribute { get; set; }
Property Value
PostProcessingModeAttribute
Attribute 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
FromEmailNodeConfiguration.PostProcessingMode — with ONE exception: a stored None FAILS the trigger
start (AB#5372). It was a real, storable mode until then, so reading it as "not configured"
would silently replace an operator's "change nothing" with the derived mode and start writing
to their mailbox.
public string PostProcessingModeAttribute { get; set; }
Property Value
SourceFolderAttribute
Attribute holding the polled folder (FromEmailNodeConfiguration.SourceFolder).
public string SourceFolderAttribute { get; set; }
Property Value
DoneFolderAttribute
Attribute holding the done folder (FromEmailNodeConfiguration.DoneFolder).
public string DoneFolderAttribute { get; set; }
Property Value
FailedFolderAttribute
Attribute holding the failed folder (FromEmailNodeConfiguration.FailedFolder).
public string FailedFolderAttribute { get; set; }
Property Value
MaxMessagesPerPollAttribute
Attribute holding the per-poll batch cap (FromEmailNodeConfiguration.MaxMessagesPerPoll). Read with
the zero-tolerant integer reader, because a configured 0 is this property's
deliberate "no limit" opt-out rather than an unset value.
public string MaxMessagesPerPollAttribute { get; set; }
Property Value
SinceDateAttribute
Attribute holding the absolute date cut-off (FromEmailNodeConfiguration.SinceDate).
public string SinceDateAttribute { get; set; }
Property Value
SinceDaysBackAttribute
Attribute holding the relative date cut-off (FromEmailNodeConfiguration.SinceDaysBack).
public string SinceDaysBackAttribute { get; set; }
Property Value
WindowOpenAttribute
Attribute holding the import-window flag (FromEmailNodeConfiguration.WindowOpen). A false there
suspends fetching for as long as it stands; unset leaves the definition's value, which is
"open".
public string WindowOpenAttribute { get; set; }
Property Value
SenderFilterAttribute
Attribute holding the sender filter (FromEmailNodeConfiguration.SenderFilter).
public string SenderFilterAttribute { get; set; }
Property Value
SubjectFilterAttribute
Attribute holding the subject filter (FromEmailNodeConfiguration.SubjectFilter).
public string SubjectFilterAttribute { get; set; }
Property Value
SuccessPathAttribute
Attribute holding the import confirmation path (FromEmailNodeConfiguration.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
CallerBinding
public CallerBindingMode CallerBinding { get; set; }
Property Value
CallerBindingMode
Description
public string Description { get; set; }
Property Value
Constructors
FromEmailNodeConfiguration()
public FromEmailNodeConfiguration()