What you will take away from this lesson
Plenty of systems a company depends on never send a webhook. They send email: a carrier’s delay notice, a supplier’s invoice, a bank’s remittance advice, a report another system mails out every morning. Somebody reads those messages and types what matters into a spreadsheet.
A mailbox source gives that job to Plexara. The team creates an address, forwards or directs the mail to it, and an administrator gives Plexara the mailbox to read. Each message from an allowed sender becomes a row and its attachments become files, and an automation that names the source runs once per message, exactly as the return check in 609 runs once per return.
Learning Objectives
- 01Set up a mailbox the team gives Plexara to read: the folders, the allowed senders, and the sender authentication a message must pass.
- 02Say what is kept of each message: one row per message, each attachment a file, and nothing at all of mail from anyone else.
- 03Treat what a sender wrote as external text, and explain why the platform marks it.
- 04Write an automation that runs once per message and files carrier delay notices into a table.
- 05State the limits: extraction is the automation’s job, and there is no OCR.
Where this lesson sits
Lesson 607 covered sources other systems post to, and 609 an automation that runs once for each event a source stores. This lesson adds a source nobody posts to: a mailbox Plexara reads.
600 Series: Automations
- 601Do not spend AI on what a script can doThe automation gap, what integration platforms and laptop scripts each cost, and the division of labor: a script for the deterministic part, the model for writing it and for judgment.
- 602The agent writes the first scriptThe loop from a recorded draft through tests to the save, what a save requires, what validate and a dry run report, the dialect’s deliberate absences, the traps that fail a draft, and the script’s page in the portal.
- 603Outputs: feeds, reports, and dashboards that refresh themselvesOutput identity across runs, tables and documents, the semi-dynamic dashboard and its data region, the referencing pattern, version caps, and delivery to a bucket drop.
- 604Running it: by hand, from the portal, and on a scheduleFour triggers, the cadence builder, the pinned fire date, what a schedule guarantees, and the run history with every trigger, duration, output, and log.
- 605What a run may do, and the record it leavesThe authority a run carries, what a save refuses, why the language cannot reach out, the lifecycle, ownership and transfer, and the administrator’s view.
- 606Scripts as skills: the weekly review the agent runs on your businessThree scripts attached to one prompt, the agent running them and reading the outputs against the knowledge graph, and a weekly list of action items with the figures behind them.
- 607Events in: a webhook source, its table, and an automation that reads itCreating a source, presets for known senders, what a sender is told, the table that serves events from acknowledgement, compaction and retention, the Webhooks page and its alerts, and the two ways an automation reads events.
- 608Results out: notification channels and signed delivery to other systemsChannel kinds and who may send to them, sending from a session and from an automation, the delivery history and the retry rule, the JSON envelope a system routes on, signed requests, and delivery to another deployment.
- 609One run per event: an automation that answers each returnNaming a source, the event a run reads, the run history with each event id, bursts and arrival order, a failed event run that alerts and is not replayed, and when a scheduled batch fits better.
- 610A mailbox as a source: filing the mail other systems sendA mailbox Plexara reads, allowed senders and sender authentication, one row per message and a file per attachment, text marked external, a filing automation, and the limits: no OCR.
- 611When an automation fails at 2 a.m.One incident instead of a message per failure, the recovery message, the operations channel, causes and what is retried within a run, and the agent’s briefing at the next session.
The 600 series picks up the registered table from the 500 series and the prompt mechanics from the 400 series.
Setting up a mailbox source
An administrator creates the source under Admin > Webhooks, choosing a mailbox instead of a sender. Six settings decide what is read and what is kept.
Admin > Webhooks, a mailbox source
- 01
The mailbox and its login
The server, and the address and password Plexara signs in with. The password is stored encrypted and never shown again. Saving the source signs in and opens each folder, so a mailbox Plexara cannot read is refused with the server’s own answer.
- 02
Folders
The folders to read, named one by one. There is no read-everything default, and each folder keeps its own place.
- 03
Allowed senders
Addresses and whole domains whose mail becomes a row. A domain entry does not admit its subdomains. Mail from anyone else is counted on the source’s page and nothing else of it is kept: not its subject, its sender, or its size.
- 04
Sender authentication
On by default: an allowed sender’s message is kept only when the receiving mail server recorded an SPF, DKIM, or DMARC pass for the domain in its From line, so a forged From does not get through.
- 05
How often, and how large
The mailbox is checked every minute unless set otherwise. A message over 10 MB is filed with its headers and no body or attachments, and says why; an attachment over 25 MB is listed on the row and not saved.
- 06
Who sees the files
The persona whose members see the attachments in Resources and search, fixed when the source is created. Left unset, only administrators.
Plexara opens each folder read-only. It never marks a message read, moves it, deletes it, or sends anything, so the people who also use the mailbox see it exactly as they left it. The source’s page shows, for each folder, the messages stored, the ones withheld because the sender is not allowed or did not authenticate, when it was last checked, and the last error.
What is kept of each message
Each message from an allowed sender is one event, written exactly as a webhook request’s events are, so everything 607 said about the table, compaction, and retention applies.
One message, one row
- received_at
- When the mail server received the message.
- event_id
- The message’s Message-ID, so the same message read twice is filed once.
- event_type
- key
- The folder it was read from.
- payload
- What Plexara read of the message: its ids, date, sender address, the authentication result, its size, and its attachments, each named with the file it was saved as. Under external, what the sender wrote: from, to, cc, subject, and body.
The rows land in the source’s table, webhook_ and the source’s name, in the same scratch catalog as every webhook source, and are queryable as soon as they are written. Each attachment is saved as a file in the source’s library, under a folder for the day and the message, tagged with the source’s name, and searchable. Reading the same message again replaces its files with a new version rather than adding a copy. Attachments stay until someone deletes them or the source is deleted.
Text a stranger wrote
What a sender wrote is marked external
Everything the sender controls, the From name, the recipients, the subject, and the body, sits under external in the row, beside a notice that says so. Invisible, bidirectional, and control characters are removed from it, and an HTML body is reduced to its visible text with hidden elements dropped.
Sender authentication proves which domain a message came from. It says nothing about whether its words can be trusted. An automation that hands the body to a model, or an agent that reads it, should treat it as text a stranger wrote. An instruction inside a message body is part of the message, not a command to follow.
An automation that files each notice
With the source in place, the automation is the same shape as the return check in 609: it names the source, runs once per message, and reads the message as its event. This one files carrier delay notices into a table the merchandising team queries beside the store data.
Filing carrier delay notices
FIELDS = {"shipment": "shipment", "store": "store", "original eta": "original_eta",
"new eta": "new_eta", "reason": "reason"}
def parse_notice(body):
found = {}
for line in body.split("\n"):
if ":" not in line:
continue
label, value = line.split(":", 1)
key = FIELDS.get(label.strip().lower())
if key:
found[key] = value.strip()
return found
def handle(event):
mail = event["payload"]
external = mail.get("external", {})
if "delay" not in external.get("subject", "").lower():
return {"filed": False, "skipped": "not a delay notice"}
fields = parse_notice(external.get("body", ""))
missing = [f for f in ["shipment", "new_eta"] if f not in fields]
if missing:
return {"filed": False, "skipped": "missing " + ", ".join(missing)}
files = [a["uri"] for a in mail.get("attachments", []) if a.get("uri")]
platform.execute(INSERT_SQL, connection = "acme", params = {...})
return {"filed": True, "shipment": fields["shipment"], "new_eta": fields["new_eta"],
"attachments": len(files)}
# INSERT_SQL writes one row to scratch.uploads.carrier_delays with bound
# values: the message id, when it arrived, the shipment, the store, both
# dates, the reason, and the attachment files.What the agent calls. This is the exchange the agent has with Plexara on your behalf, shown for the technical reader. You ask in plain language; you never type any of it.
manage_script validate acme-carrier-notice-610
-> ok true
capabilities platform.execute, platform.result
connections acme
tests test_files_a_delay_notice passed
test_skips_other_mail passed
test_skips_a_notice_without_a_shipment passed
test_a_run_without_an_event_says_so passed
coverage 31 of 32 statementsThe notice format belongs to the carrier: labelled lines such as Shipment, Store, Original ETA, New ETA, and Reason. The script reads only those labels and ignores every other line, so a signature, a disclaimer, or a marketing footer changes nothing. A message that is not a delay notice, or one missing its shipment or new date, is skipped and the run’s result says which. The values reach the table as bound parameters, never pasted into the SQL, so a sender cannot write a statement of their own. The tests were run on the demo tenant against messages built the way the source stores them.
The limits to plan around
A mailbox source is a reliable way to get mail into a table. It is not a document reader, and four limits follow from that.
The limits to plan around
- Extraction is the automation’s job
- The source files the message as the sender wrote it. Turning a body into fields, a shipment number, a date, an amount, is code the agent writes for that sender’s format, and a new format is a new version of the script with its own tests.
- There is no OCR
- An attachment is saved as a file. Plexara does not read the text inside a scanned PDF or an image, so a notice whose only content is a scan is filed with the scan attached and its fields left for a person, or for a format the sender can provide as text.
- Mail is read, never answered
- The source sends nothing back. A reply to the sender, if one is needed, is a notification channel or an email list the automation posts to.
- One check files at most 200 messages per folder
- Oldest first; the rest wait for the next check. A check that fails leaves the folder’s place where it was, so nothing is skipped.
One more way in
The mail other systems send now arrives the way their webhooks would: verified, stored, queryable, and acted on once per message by an automation with tests.
Key terms
Four terms cover a mailbox as a source.
Key Terms
- Mailbox source
- A source Plexara fills by reading a mailbox an administrator gives it, one row per message from an allowed sender.
- Allowed senders
- The addresses and domains whose mail becomes a row. Everything else is counted and not kept.
- Sender authentication
- The SPF, DKIM, or DMARC pass the receiving mail server recorded for the From domain, required by default.
- External text
- What the sender wrote, kept under external in the row and to be treated as a stranger’s words.
