How to Route Inbound Vendor Emails to the Right Team with AI Agent Mode
Forward vendor notifications to a Mailhook address, let an Agent-mode connector node classify each email's intent and urgency, then tag the matching Front conversation and post a Slack alert to the team channel that owns it.
What This Integration Does
Vendor email is noisy: shipping notices, invoice reminders, outage alerts, and contract questions all land in the same shared inbox, and the people who need to act often see them late. This workflow reads each incoming vendor email, uses an Agent-mode Connector node to decide what kind of message it is and how urgent it is, then routes it two ways at once. The Front conversation gets a tag so it is visible to the right team in their shared inbox, and a short alert lands in the Slack channel that owns that category so someone can pick it up immediately.
The run is push-driven. When mail arrives at your Spojit Mailhook address, a run starts within seconds with the full email available as {{ input }}. An Agent-mode Connector node returns a structured classification, a Transform node maps that classification to a Front tag and a Slack channel, and two connector calls finish the run. Nothing is stored between runs: each email is handled independently, deduplicated per message, and routed on its own merits. Re-running the same email produces the same routing because the decision is driven only by the email content and your mapping table.
Prerequisites
- A Front connection (API key) with permission to read conversations and add tags. Note the tag IDs you want to apply, available from the
list-tagstool. - A Slack connection with permission to post messages to your team channels.
- The Front channel ID you will reply from (if you want Front to send a templated reply), available from
list-inboxes. This is optional and only needed if you add the reply branch in the Tips section. - A short mapping of vendor email categories (for example
shipping,billing,incident,general) to a Front tag ID and a Slack channel name. You will paste this into a Transform node. - A way to send vendor mail to your Mailhook address: a forwarding rule on your shared mailbox, or pointing the vendor portal's notification address at it.
Step 1: Start with a Mailhook trigger
Create a new workflow and open the Trigger node. Set Trigger Type to Mailhook. Optionally set an Address prefix such as vendors (1 to 24 characters), then click Generate email address. Spojit creates a unique address like vendors-1a2b3c4d5e6f7g8h@mailhook.spojit.com. Copy it and add a forwarding rule in your shared mailbox so vendor notifications land there. Mailhook needs no mailbox login and no OAuth: any mail to the address starts a run within seconds.
To keep the workflow focused, add an optional Subject regex or From allowlist so only genuine vendor mail triggers a run. The trigger output is available downstream as {{ input }} with fields including {{ input.from }}, {{ input.subject }}, {{ input.text }}, {{ input.replyTo }}, and {{ input.attachments }}. For more detail on this trigger see the guide on setting up a Mailhook trigger.
Step 2: Classify intent and urgency with an Agent-mode Connector node
Add a Connector node and switch it to Agent mode. Agent mode lets the agent read the email and reason about it, and the Response Schema forces the answer into clean JSON you can branch on. In the prompt, pass the email subject and body:
Classify this vendor email.
From: {{ input.from }}
Subject: {{ input.subject }}
Body:
{{ input.text }}
Decide the category (one of: shipping, billing, incident, general),
an urgency of low, normal, or high, and a one-line summary for a
Slack alert. Base urgency on words like "down", "outage", "overdue",
or "urgent".
Set the Response Schema so the node always returns the same shape:
{
"type": "object",
"properties": {
"category": { "type": "string", "enum": ["shipping", "billing", "incident", "general"] },
"urgency": { "type": "string", "enum": ["low", "normal", "high"] },
"summary": { "type": "string" }
},
"required": ["category", "urgency", "summary"]
}
Set the node's Output Variable to classification so later steps can read {{ classification.category }}, {{ classification.urgency }}, and {{ classification.summary }}. If you are unsure when to use Agent mode over Direct mode, read how to choose between Agent mode and Direct mode.
Step 3: Map the category to a Front tag and Slack channel
Add a Transform node to turn the category into the routing values you need. Keep your mapping in one place so it is easy to update as teams change. A small lookup keyed by {{ classification.category }} produces a Front tag ID and a Slack channel:
{
"tagId": {{ classification.category == "shipping" ? "tag_ship01" :
classification.category == "billing" ? "tag_bill02" :
classification.category == "incident" ? "tag_inc03" : "tag_gen04" }},
"channel": {{ classification.category == "shipping" ? "#ops-shipping" :
classification.category == "billing" ? "#finance-ap" :
classification.category == "incident" ? "#incident-response" : "#vendor-inbox" }}
}
Set the Output Variable to route. Replace the example tag IDs with the real IDs from your Front account (pull them once with the Front list-tags tool) and the channel names with your real Slack channels. You now have {{ route.tagId }} and {{ route.channel }} ready for the connector calls.
Step 4: Find the Front conversation for this email
Add a Connector node in Direct mode for the Front connector and pick the list-conversations tool. Front threads the inbound email into a conversation automatically; this step finds that conversation so you can tag it. Filter the results to the matching inbox and the most recent conversation involving {{ input.from }}, then take the first conversation's ID. Set the Output Variable to conversation so the next step can reference the conversation ID, for example {{ conversation.results[0].id }}.
If your Front setup uses a known single inbox for vendor mail, you can narrow the call by passing that inbox ID so you only search the right place. Keeping this step in Direct mode keeps it deterministic and free of AI cost, since there is no judgement required: you already know which conversation you want.
Step 5: Tag the Front conversation
Add another Front Connector node in Direct mode and select the add-tag tool. Map its two inputs:
conversationId={{ conversation.results[0].id }}tag_ids=[ {{ route.tagId }} ](an array of one tag ID)
This applies the routing tag so the owning team sees the conversation in their filtered Front view. Because the tag comes from {{ route.tagId }}, a shipping email is tagged for the shipping team and a billing email for accounts payable, all from the same workflow. Set the Output Variable to tagged in case you want to confirm success later.
Step 6: Post a Slack alert to the matching team channel
Add a Slack Connector node in Direct mode and select the send-message tool. This pings the team that owns the category so the tagged conversation does not sit unseen. Map the fields:
- Channel =
{{ route.channel }} - Message text:
:incoming_envelope: New vendor email ({{ classification.urgency }})
*{{ input.subject }}*
From: {{ input.from }}
{{ classification.summary }}
Add a Condition node before this step if you want to suppress Slack noise for low-urgency mail: branch on {{ classification.urgency }} and only send to Slack when it equals high or normal, while still tagging every conversation in Front. For background on the Slack connector, see the Slack connector reference, and for routing patterns generally see how to route Front customer messages to Slack channels.
Tips
- To reply to the vendor, add a Send Email node and address it to
{{ input.replyTo }}. Mailhook runs are always asynchronous, so a reply must be an explicit step, not a return value to the sender. - Keep the routing table in the single Transform node rather than spreading conditions across the canvas. When a team or channel changes, you edit one place.
- Use the Response Schema in Step 2 to keep the category list closed with an
enum. A constrained set of categories keeps your Transform mapping exhaustive and predictable. - Ask Miraxa to scaffold the skeleton: "Build a workflow with a Mailhook trigger, an Agent-mode Connector node that classifies a vendor email, a Transform node, then Front add-tag and Slack send-message nodes." Then fine-tune each node in the properties panel.
Common Pitfalls
- Front tag IDs are not the human-readable tag names. Use the
list-tagstool once to get the real IDs and paste those into the Transform mapping, or theadd-tagcall will fail. - If
list-conversationsreturns no match, the inbound email may not have threaded yet. Add a short delay or a Condition node that checks{{ conversation.results }}is non-empty before the tag step so the run does not error. - Regenerating the Mailhook address rotates it instantly and the old address stops working, so update your forwarding rule whenever you regenerate.
- Long vendor emails may be truncated; check
{{ input.truncated }}. If the classification looks off for a long thread, base the prompt on the subject plus the first portion of the body rather than expecting the full text.
Testing
Before pointing live vendor mail at the address, send a few test emails to your Mailhook address from your own mailbox, one for each category and urgency level. Open the workflow's execution history to confirm the run fired, then inspect the Agent-mode node's {{ classification }} output, the Transform node's {{ route }} values, and that the correct Front conversation was tagged and the right Slack channel received the alert. Once a small batch routes correctly end to end, add your From allowlist or Subject regex on the trigger and switch the real vendor forwarding rule over.