Recommended Approach for Email Classification Using Multiple Inbound Email Trigger Flows
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
3 weeks ago
Hello Community,
I would like to get feedback on the architecture of an inbound email processing solution.
## Background
We receive various types of emails that must be processed differently based on conditions such as sender, subject, and email content.
In addition, any email that does not explicitly match a defined processing rule should ultimately be classified as Junk.
## Proposed Architecture
I am considering implementing this using multiple Inbound Email Trigger Flows.
The system property `glide.hub.flow.inbound_email_trigger.show_advanced` would be enabled so that multiple flows can be configured and ordered.
### Processing Flow
1. An initial flow (Order = 0) receives the email and leaves it in the Inbox state.
2. Multiple business-specific flows (Order > 0) evaluate the email and perform their respective processing.
3. When a flow successfully processes the email, it updates the email status to `Received`.
4. A final flow (Order = 9999) evaluates the email:
- If the status is `Received`, no further action is taken.
- If the status is not `Received`, the email is classified as Junk.
### Goals
- Separate processing logic into independent flows.
- Simplify future maintenance and addition of new email-processing rules.
- Ensure that any email not matched by a processing rule is automatically treated as Junk.
## Questions
### 1. Is this architecture reasonable?
Has anyone implemented a similar pattern using multiple Inbound Email Trigger Flows?
In particular, are there any concerns with:
- Using the Order field to control processing sequence across multiple flows?
- Using the email status as a flag to indicate whether an email has already been processed?
### 2. Inbound Email Trigger Flow vs. Inbound Email Action
For this type of requirement, would you recommend:
- Inbound Email Trigger Flows
- Inbound Email Actions
I would appreciate recommendations from the perspectives of:
- Maintainability
- Scalability
- Processing order control
- Performance
- ServiceNow best practices
### 3. Status Update Visibility Across Flows
If multiple Inbound Email Trigger Flows are executed for the same email, can a later flow reliably determine whether an earlier flow has changed the email status (for example, to `Received`)?
Are there any transaction, execution-order, or timing considerations that could affect this design?
Any guidance, best practices, or alternative approaches would be greatly appreciated.
Thank you.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
3 weeks ago - last edited 3 weeks ago
hi @ShumaS ,
I would suggest using multiple Inbound Email Trigger Flows if you want to keep the processing logic separated, but I would be careful with the proposed status-based approach.
A few things to consider:
-
Execution order: Use the Order field to control the sequence, but don't assume that setting a higher order alone guarantees that all previous processing has completed in every scenario. Verify the execution behavior in your ServiceNow release.
-
Email status: I would avoid using the email status as the only indicator that a particular business rule has processed the email. It is better to maintain an explicit processing result or matched-rule indicator if your design requires it.
-
Final Junk flow: Before classifying an email as Junk, make sure all intended processing rules have had a chance to evaluate it. Otherwise, a valid email could be classified as Junk because of an execution or configuration issue.
-
Flows vs. Inbound Email Actions: Flows are useful for separating business logic and making it easier to maintain. Inbound Email Actions are also a good option for traditional email processing, especially when you need to create or update records based on the sender, subject, or email body.
For your requirement, I would consider a central classification step that evaluates the email and identifies the matching processing rule, then routes it to the appropriate flow or action. If no rule matches, classify it as Junk after the classification is complete.
Before implementing this, I would test whether status changes made by one Inbound Email Trigger Flow are visible to subsequent flows in your specific release, including cases where a flow exits without matching the email.
Regards,
Tejas
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
3 weeks ago
Hello Tejas,
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
3 weeks ago
Hi @ShumaS ,
Architecture for inbound email processing with multiple Inbound Email Trigger Flows
Your goals—separation of logic, easy maintenance, and Junk as the default—are reasonable. However, I would change the mechanism.
The problem:
The design uses the email status as a shared flag between independent flows, and the final flow (Order = 9999) infers that nothing matched based on that flag. This approach is fragile for three reasons.
Timing: Separate flows are not guaranteed to run sequentially, with each update committed before the next flow starts. The final flow could read the status before an earlier flow writes Received, causing a correctly processed email to be marked as Junk.
Ownership of the field: The inbound email engine manages the email's type and state as processing finishes. A flow's update might be overwritten or conflict with the engine's processing.
Silent failures: If a business flow fails halfway, the email may still appear unprocessed, causing the final flow to mark it as Junk and hide the underlying problem.
Also, test how Order behaves in your ServiceNow release. If the trigger uses first-match-wins behavior, a later flow might never execute after an earlier flow claims the email.
Recommended remedy: One dispatcher flow with subflows
Use a single Inbound Email trigger flow that evaluates the sender, subject, and body through If / Else If branches.
Each branch calls a sub-flow containing the relevant business logic.
The final Else branch handles unmatched emails and marks them as Junk.
This avoids using email status as a shared flag and makes the routing logic easier to maintain.
When adding a new rule, add a branch and a corresponding sub-flow.
If the rules grow, consider using a rules table containing sender patterns, subject patterns, and routing information.
Alternatives
Separate flows plus a catch-all:
Keep the specific flows and add a final flow without conditions that marks unmatched emails as Junk. Use this approach only after verifying the trigger execution and ordering behavior in your release.
Inbound Email Actions:
Use ordered actions with Stop processing enabled where appropriate, followed by a catch-all action that handles unmatched emails. Verify the behavior in your instance.
Answers to your questions
1. Is it reasonable?
The goals are reasonable, but using email status as an indicator that another flow has processed the email is risky. Use ordering only after confirming how the trigger handles multiple matching flows.
2. Flows or Actions?
Maintainability: Flows offer visual logic and reusable sub-flows.
Order control: Inbound Email Actions provide established ordering and Stop processing behavior.
Performance: Both can work well at normal email volumes.
Best practice: Choose one mechanism for a given routing process to avoid conflicts between flows and actions.
3. Can a later flow reliably see an earlier flow's status change?
Do not assume that it can. Execution timing, transaction behavior, and the inbound email engine's handling of status fields can affect the result.
If you need to keep separate flows, consider a dedicated custom field or tracking table. However, this does not automatically eliminate timing issues. A single dispatcher with subflows provides a more centralized approach.
Regards,
Tarun
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
3 weeks ago
Thank you for the detailed explanation.