From 0e47af87941b4729fa7e94584b4f3de3dc106efd Mon Sep 17 00:00:00 2001 From: Jon M Date: Tue, 26 May 2026 15:31:35 +0100 Subject: [PATCH 1/4] README improvements --- README.md | 57 +++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 43 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index c8f055f..82e49b8 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,7 @@ This guide provides several key sections: - [Working with hyperlinks](#working-with-hyperlinks) - [Links in plain text (including SMS messages)](#links-in-plain-text-including-sms-messages) - [Working with attachments](#working-with-attachments) + - [Writing an attachment to disk](#writing-an-attachment-to-disk) - [Working with images and web beacons](#working-with-images-and-web-beacons) - [Remotely-hosted images](#remotely-hosted-images) - [Triggering web beacons](#triggering-web-beacons) @@ -97,7 +98,7 @@ MailosaurClient mailosaur = new MailosaurClient(); This library is powered by the Mailosaur [email & SMS testing API](https://mailosaur.com/docs/api/). You can easily check out the API itself by looking at our [API reference documentation](https://mailosaur.com/docs/api/) or via our Postman or Insomnia collections: [![Run in Postman](https://run.pstmn.io/button.svg)](https://app.getpostman.com/run-collection/6961255-6cc72dff-f576-451a-9023-b82dec84f95d?action=collection%2Ffork&collection-url=entityId%3D6961255-6cc72dff-f576-451a-9023-b82dec84f95d%26entityType%3Dcollection%26workspaceId%3D386a4af1-4293-4197-8f40-0eb49f831325) -[![Run in Insomnia}](https://insomnia.rest/images/run.svg)](https://insomnia.rest/run/?label=Mailosaur&uri=https%3A%2F%2Fmailosaur.com%2Finsomnia.json) + [![Run in Insomnia](https://insomnia.rest/images/run.svg)](https://insomnia.rest/run/?label=Mailosaur&uri=https%3A%2F%2Fmailosaur.com%2Finsomnia.json) ## Creating an account @@ -123,7 +124,7 @@ Here's how it works: - `rAnDoM63423@abc123.mailosaur.net` - You can create more servers when you need them. Each one will have its own domain name. -**\*Can't use test email addresses?** You can also [use SMTP to test email](https://mailosaur.com/docs/email-testing/sending-to-mailosaur/#sending-via-smtp). By connecting your product or website to Mailosaur via SMTP, Mailosaur will catch all email your application sends, regardless of the email address.\* +***Can't use test email addresses?** You can also [use SMTP to test email](https://mailosaur.com/docs/email-testing/sending-to-mailosaur/#sending-via-smtp). By connecting your product or website to Mailosaur via SMTP, Mailosaur will catch all email your application sends, regardless of the email address.* ## Find an email @@ -162,22 +163,27 @@ public class AppTest { ### What is this code doing? -1. Sets up an instance of `MailosaurClient` using the `MAILOSAUR_API_KEY` environment variable. +1. Sets up an instance of `MailosaurClient`, reading the API key from the `MAILOSAUR_API_KEY` environment variable. 2. Waits for an email to arrive at the server with ID `abc123`. 3. Asserts the subject line of the email equals the expected value. ### My email wasn't found -First, check that the email you sent is visible in the [Mailosaur Dashboard](https://mailosaur.com/api/project/messages). +First, check that the email you sent is visible in the [Mailosaur Dashboard](https://mailosaur.com/app/project/messages). If it is, the likely reason is that by default, `messages.get` only searches emails received by Mailosaur in the last 1 hour. You can override this behavior (see the `receivedAfter` option below), however we only recommend doing this during setup, as your tests will generally run faster with the default settings: ```java +import java.time.LocalDate; +import java.time.ZoneOffset; + +// ... + MessageSearchParams params = new MessageSearchParams(); -params.withServer("SERVER_ID") - .withReceivedAfter(1577836800000); +params.withServer(serverId) + // Override receivedAfter to search all messages since Jan 1st + .withReceivedAfter(LocalDate.of(2021, 1, 1).atStartOfDay().toInstant(ZoneOffset.UTC).toEpochMilli()); -// Override receivedAfter to search all messages since Jan 1st Message email = mailosaur.messages().get(params, criteria); ``` @@ -213,7 +219,7 @@ Most emails, and all SMS messages, should have a plain text body. Mailosaur expo System.out.println(message.text().body()); // "Hi Jason, ..." if (message.text().body().contains("Jason")) { - System.out.println('Email contains "Jason"'); + System.out.println("Email contains \"Jason\""); } ``` @@ -245,7 +251,7 @@ System.out.println(message.html().body()); // " @@ -264,7 +270,7 @@ import org.jsoup.select.Elements; Document doc = Jsoup.parse(message.html().body()); -Elements elements = doc.getElementsByTag(".verification-code"); +Elements elements = doc.select(".verification-code"); String verificationCode = elements.get(0).text(); System.out.println(verificationCode); // "542163" @@ -287,7 +293,7 @@ System.out.println(firstLink.text()); // "Google Search" System.out.println(firstLink.href()); // "https://www.google.com/" ``` -**Important:** To ensure you always have valid emails. Mailosaur only extracts links that have been correctly marked up with `` or `` tags. +**Important:** To ensure you always have valid emails, Mailosaur only extracts links that have been correctly marked up with `` or `` tags. ### Links in plain text (including SMS messages) @@ -326,6 +332,20 @@ Attachment firstAttachment = message.attachments().get(0); System.out.println(firstAttachment.length()); // 4028 ``` +### Writing an attachment to disk + +```java +import java.nio.file.Files; +import java.nio.file.Paths; + +// ... + +Attachment firstAttachment = message.attachments().get(1); + +byte[] fileBytes = mailosaur.files().getAttachment(firstAttachment.id()); +Files.write(Paths.get(firstAttachment.fileName()), fileBytes); +``` + ## Working with images and web beacons The `html.images` property of a message contains an array of images found within the HTML content of an email. The length of this array corresponds to the number of images found within an email: @@ -353,13 +373,20 @@ A web beacon is a small image that can be used to track whether an email has bee Because a web beacon is simply another form of remotely-hosted image, you can use the `src` attribute to perform an HTTP request to that address: ```java +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; + +// ... + Image image = message.html().images().get(0); System.out.println(image.src()); // "https://example.com/s.png?abc123" // Make an HTTP call to trigger the web beacon -var client = HttpClient.newHttpClient(); -var request = HttpRequest.newBuilder(URI.create(image.src())).build(); -var response = client.send(request, null); +HttpClient client = HttpClient.newHttpClient(); +HttpRequest request = HttpRequest.newBuilder(URI.create(image.src())).build(); +HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString()); System.out.println(response.statusCode()); // 200 ``` @@ -382,6 +409,8 @@ result.spamFilterResults().spamAssassin().forEach(r -> ## Development +If you'd like to contribute to this library, here is how to set it up locally. + The test suite requires the following environment variables to be set: ```sh From 69405ffce441db669358d31bcf442fdbdf137c51 Mon Sep 17 00:00:00 2001 From: Jon M Date: Tue, 26 May 2026 16:34:15 +0100 Subject: [PATCH 2/4] Better documentation of 'codes' in README --- README.md | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 82e49b8..8eb7a36 100644 --- a/README.md +++ b/README.md @@ -225,21 +225,15 @@ if (message.text().body().contains("Jason")) { ### Extracting verification codes from plain text -You may have an email or SMS message that contains an account verification code, or some other one-time passcode. You can extract content like this using a simple regex. - -Here is how to extract a 6-digit numeric code: +You may have an email or SMS message that contains an account verification code, or some other one-time passcode. Mailosaur automatically extracts these for you and makes them available via the `codes` array on the message content: ```java System.out.println(message.text().body()); // "Your access code is 243546." -Pattern pattern = Pattern.compile(".*([0-9]{6}).*"); -Matcher matcher = pattern.matcher(message.text().body()); -matcher.find(); - -System.out.println(matcher.group(1)); // "243546" +System.out.println(message.text().codes().get(0).value()); // "243546" ``` -[Read more](https://mailosaur.com/docs/test-cases/text-content/) +[Read more](https://mailosaur.com/docs/automation/codes) ## Testing HTML content From 11050f82a1283401b753c04119efe23995e4564d Mon Sep 17 00:00:00 2001 From: Jon M Date: Wed, 27 May 2026 09:14:06 +0100 Subject: [PATCH 3/4] Use inbox (server) terminology in README prose Lead with the UI term "inbox" and gloss "(server)" on entity mentions, leaving code identifiers, dashboard field labels, and the MAILOSAUR_SERVER env var unchanged. --- README.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 8eb7a36..8d344ce 100644 --- a/README.md +++ b/README.md @@ -106,9 +106,9 @@ Create a [free trial account](https://mailosaur.com/app/signup) for Mailosaur vi Once you have this, navigate to the [API tab](https://mailosaur.com/app/project/api) to find the following values: -- **Server ID** - Servers act like projects, which group your tests together. You need this ID whenever you interact with a server via the API. -- **Server Domain** - Every server has its own domain name. You'll need this to send email to your server. -- **API Key** - You can create an API key per server (recommended), or an account-level API key to use across your whole account. [Learn more about API keys](https://mailosaur.com/docs/managing-your-account/api-keys/). +- **Server ID** - Inboxes (servers) act like projects, which group your tests together. You need this ID whenever you interact with an inbox (server) via the API. +- **Server Domain** - Every inbox (server) has its own domain name. You'll need this to send email to your inbox (server). +- **API Key** - You can create an API key per inbox (server) — recommended — or an account-level API key to use across your whole account. [Learn more about API keys](https://mailosaur.com/docs/managing-your-account/api-keys/). ## Test email addresses with Mailosaur @@ -116,13 +116,13 @@ Mailosaur gives you an **unlimited number of test email addresses** - with no se Here's how it works: -- When you create an account, you are given a server. -- Every server has its own **Server Domain** name (e.g. `abc123.mailosaur.net`) +- When you create an account, you are given an inbox (server). +- Every inbox (server) has its own **Server Domain** name (e.g. `abc123.mailosaur.net`) - Any email address that ends with `@{YOUR_SERVER_DOMAIN}` will work with Mailosaur without any special setup. For example: - `build-423@abc123.mailosaur.net` - `john.smith@abc123.mailosaur.net` - `rAnDoM63423@abc123.mailosaur.net` -- You can create more servers when you need them. Each one will have its own domain name. +- You can create more inboxes (servers) when you need them. Each one will have its own domain name. ***Can't use test email addresses?** You can also [use SMTP to test email](https://mailosaur.com/docs/email-testing/sending-to-mailosaur/#sending-via-smtp). By connecting your product or website to Mailosaur via SMTP, Mailosaur will catch all email your application sends, regardless of the email address.* @@ -164,7 +164,7 @@ public class AppTest { ### What is this code doing? 1. Sets up an instance of `MailosaurClient`, reading the API key from the `MAILOSAUR_API_KEY` environment variable. -2. Waits for an email to arrive at the server with ID `abc123`. +2. Waits for an email to arrive at the inbox (server) with ID `abc123`. 3. Asserts the subject line of the email equals the expected value. ### My email wasn't found From 6f674f74b7dda164e42e880a84de3e5e9ea8a501 Mon Sep 17 00:00:00 2001 From: Jon M Date: Wed, 27 May 2026 10:42:48 +0100 Subject: [PATCH 4/4] Update dashboard links for new API keys and inboxes (servers) layout --- README.md | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 8d344ce..ed6127c 100644 --- a/README.md +++ b/README.md @@ -104,11 +104,11 @@ This library is powered by the Mailosaur [email & SMS testing API](https://mailo Create a [free trial account](https://mailosaur.com/app/signup) for Mailosaur via the website. -Once you have this, navigate to the [API tab](https://mailosaur.com/app/project/api) to find the following values: +To start testing you'll need three things: -- **Server ID** - Inboxes (servers) act like projects, which group your tests together. You need this ID whenever you interact with an inbox (server) via the API. -- **Server Domain** - Every inbox (server) has its own domain name. You'll need this to send email to your inbox (server). -- **API Key** - You can create an API key per inbox (server) — recommended — or an account-level API key to use across your whole account. [Learn more about API keys](https://mailosaur.com/docs/managing-your-account/api-keys/). +- **API key** - [manage API keys within the Mailosaur Dashboard](https://mailosaur.com/app/keys). You can scope a key to a single inbox (server) — recommended — or create an account-level key. [Learn more about API keys](https://mailosaur.com/docs/managing-your-account/api-keys/). +- **Inbox (server) domain** - open [your inbox](https://mailosaur.com/app/servers/default) (server) within the Mailosaur Dashboard to see its domain name (e.g. `abc123.mailosaur.net`). You'll need this to send email to the inbox (server). +- **Inbox (server) ID** - the first part of the inbox (server) domain. For `abc123.mailosaur.net` the ID is `abc123`. You need this whenever you interact with the inbox (server) via the API. ## Test email addresses with Mailosaur @@ -117,7 +117,7 @@ Mailosaur gives you an **unlimited number of test email addresses** - with no se Here's how it works: - When you create an account, you are given an inbox (server). -- Every inbox (server) has its own **Server Domain** name (e.g. `abc123.mailosaur.net`) +- Every inbox (server) has its own domain name (e.g. `abc123.mailosaur.net`) - Any email address that ends with `@{YOUR_SERVER_DOMAIN}` will work with Mailosaur without any special setup. For example: - `build-423@abc123.mailosaur.net` - `john.smith@abc123.mailosaur.net` @@ -144,7 +144,6 @@ public class AppTest { @Test public void testExample() throws IOException, MailosaurException { MailosaurClient mailosaur = new MailosaurClient(); - // See https://mailosaur.com/app/project/api String serverId = "abc123"; String serverDomain = "abc123.mailosaur.net";