Reading a one-time code from an email without false matches

Updated October 16, 2026 · Zyntra

A bare \d{6} also matches order numbers, phone numbers and dates in the footer. Anchor the pattern to the words around the code, normalize whitespace first, and require exactly one match, so a template change fails the test with a clear message instead of typing the wrong number.

What goes wrong with \d{6}

  • Other numbers: an order ID, a support phone number, a postcode, a date written as 20261016.
  • Split codes: "123 456" or "123-456" for readability, or each digit in its own table cell.
  • Non-breaking spaces between groups, which \s in some engines and tools does not cover the way you expect.
  • HTML-only emails: no plain-text part, so the text you search is empty.
  • Codes with letters: A7K-29Q never matches a digit pattern at all.

A safer reader

read-code.ts
const stripHtml = (html: string) =>
  html
    .replace(/<(style|script)[\s\S]*?<\/\1>/gi, " ")
    .replace(/<[^>]+>/g, " ")
    .replace(/&nbsp;/g, " ");

export function readCode(email: { body: string; html: string | null }) {
  const text = (email.body || stripHtml(email.html ?? ""))
    .replace(/\u00a0/g, " ")
    .replace(/\s+/g, " ");

  // Anchor to the words your template uses around the code.
  const pattern = /(?:code|passcode)(?: is)?:? (\d{3})[ -]?(\d{3})\b/gi;
  const found = [...text.matchAll(pattern)];
  if (found.length !== 1) {
    throw new Error(`Expected one code, found ${found.length}`);
  }
  return found[0]![1]! + found[0]![2]!;
}

Write the anchor from your own template ("Your code is", "Enter this code"). If the wording changes, the test fails with "found 0" rather than passing with a wrong number.

Check the subject too

Many apps put the code in the subject ("123456 is your sign-in code") so it shows in notifications. If yours does, read it from there: the subject is short and has no footer. Then assert that the body contains the same code, which checks both at once.

Make expiry part of the test

Codes usually expire within minutes. Read the email right after the step that sends it, and add a separate test that enters a used or expired code and expects an error. For time-based expiry, shorten the lifetime in the test environment instead of waiting.

Questions

Should the email service pick the code out for me?
A service can't know your code format or the words around it as well as your test does. Reading it in the test keeps the rule next to the template it depends on.