What is extracted from a message, with nothing to configure
One-time code, links, codes and headers — what parsing finds on its own, and what it does not.
A test almost never needs the body of an email. It needs one thing inside the body: a six-digit code, a confirmation link, a token. Parsing pulls it out for you, on reception, with no configuration.
What you get
| Field | What it carries |
|---|---|
otp | The one-time code, when the message contains a single obvious one |
codes | The other digit or character runs that look like codes |
links | Every URL in the message, unescaped |
headers | The headers, lowercased, so you can find your own |
text.body / html.body | Both versions, as sent |
Links are unescaped, and that detail has already cost us
A link written inside HTML carries entities: & for &. A test that follows a
still-escaped link asks the server for a URL whose second parameter is called
amp;next — and gets a page that is not the one it expected, with no error.
The defect is real: we found it here, reading our own transactional mail back through our own product. The links the API returns are unescaped.
otp versus codes
otp is populated when the message contains one clear candidate. As soon as there
are several — a confirmation code and a six-digit order number — the ambiguity is
real, and we do not resolve it by guessing: otp stays empty and the candidates go
into codes.
That is the moment to move to a named pointer, which says where to look rather than what it looks like. See pointeurs.
Headers are your best correlation tool
Parsing keeps the message headers. If your application sets one that identifies the
run — X-Test-Id, X-Correlation-Id — you get it back as sent:
const message = messages.find((m) => m.headers['x-test-id'] === runId);
Keys are lowercase, always. A header is case-insensitive on the wire, and comparing it as sent produces a test that works until the day the sending library changes its capitalisation.
What parsing does not do
- It does not guess your format. A house identifier looks like nothing known. That is exactly what pointers address.
- It does not read attachments.
- It does not run on a refused message. Past the quota, nothing is stored or parsed — see quotas-et-retention.
- It happens after the SMTP acknowledgement. Hence the
statusfield, and why it must be read: lire-un-message.