Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 31 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ Example `.env` variables (or export in shell):
```bash
MAILTRAP_API_KEY=your_api_token # https://mailtrap.io/api-tokens
MAILTRAP_USE_SANDBOX=true # true/false toggle
MAILTRAP_INBOX_ID=123456 # Only needed for sandbox
MAILTRAP_SANDBOX_ID=123456 # Only needed for sandbox
```

Bootstrap logic:
Expand All @@ -71,12 +71,12 @@ import { MailtrapClient } from "mailtrap";

const apiKey = process.env.MAILTRAP_API_KEY;
const isSandbox = process.env.MAILTRAP_USE_SANDBOX === "true";
const inboxId = isSandbox ? Number(process.env.MAILTRAP_INBOX_ID) : undefined; // required only for sandbox
const sandboxId = isSandbox ? Number(process.env.MAILTRAP_SANDBOX_ID) : undefined; // required only for sandbox
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Resolved

const client = new MailtrapClient({
token: apiKey,
sandbox: isSandbox,
testInboxId: inboxId, // undefined is ignored for production
sandboxId, // undefined is ignored for production
});

client
Expand Down Expand Up @@ -119,7 +119,7 @@ const mailtrap = new MailtrapClient({
token: process.env.MAILTRAP_API_KEY, // your API token
bulk: false, // set to true for bulk email sending (false by default)
sandbox: false, // set to true for sandbox mode (false by default)
testInboxId: undefined, // optional, only for sandbox mode
sandboxId: undefined, // optional, only for sandbox mode
});

const welcomeImage = fs.readFileSync(path.join(__dirname, "welcome.png"));
Expand Down Expand Up @@ -236,23 +236,23 @@ Email API:
- Batch send (Bulk) – [`batch/bulk.ts`](examples/bulk/bulk.ts)
- Batch send with Template (Transactional) – [`batch/template.ts`](examples/batch/template.ts)
- Batch send with Template (Bulk) – [`batch/template.ts`](examples/batch/template.ts)
- Sending domain management CRUD and settings – [`sending-domains/everything.ts`](examples/sending-domains/everything.ts)
- Sending domain company info – [`company-info/everything.ts`](examples/company-info/everything.ts)
- Domain management CRUD and settings – [`domains/everything.ts`](examples/domains/everything.ts)
- Domain company info – [`company-info/everything.ts`](examples/company-info/everything.ts)
- Sending stats (aggregated and by domain, category, ESP, date) – [`stats/everything.ts`](examples/stats/everything.ts)
- Email logs (list with filters, get by message ID) – [`email-logs/everything.ts`](examples/email-logs/everything.ts)
- Webhooks CRUD – [`webhooks/everything.ts`](examples/webhooks/everything.ts)
- Verifying webhook signatures – [`webhooks/verify-signature.ts`](examples/webhooks/verify-signature.ts)

Email Sandbox (Testing):
Email Sandbox:

- Send an email (Sandbox) – [`testing/send-mail.ts`](examples/testing/send-mail.ts)
- Send an email with a Template (Sandbox) – [`testing/template.ts`](examples/testing/template.ts)
- Send an email (Sandbox) – [`sandbox/send-mail.ts`](examples/sandbox/send-mail.ts)
- Send an email with a Template (Sandbox) – [`sandbox/template.ts`](examples/sandbox/template.ts)
- Batch send (Sandbox) – [`batch/sandbox.ts`](examples/batch/sandbox.ts)
- Batch send with Template (Sandbox) – [`batch/sandbox.ts`](examples/batch/sandbox.ts)
- Message management CRUD – [`testing/messages.ts`](examples/testing/messages.ts)
- Inbox management CRUD – [`testing/inboxes.ts`](examples/testing/inboxes.ts)
- Project management CRUD – [`testing/projects.ts`](examples/testing/projects.ts)
- Attachments operations – [`testing/attachments.ts`](examples/testing/attachments.ts)
- Message management CRUD – [`sandbox/messages.ts`](examples/sandbox/messages.ts)
- Sandbox management CRUD – [`sandbox/sandboxes.ts`](examples/sandbox/sandboxes.ts)
- Project management CRUD – [`sandbox/projects.ts`](examples/sandbox/projects.ts)
- Attachments operations – [`sandbox/attachments.ts`](examples/sandbox/attachments.ts)

Inbound Email:

Expand Down Expand Up @@ -304,6 +304,24 @@ Everyone interacting in the Mailtrap project's codebases, issue trackers, chat r

Versions of this package up to 2.0.2 were an [unofficial client](https://github.com/vchin/mailtrap-client) developed by [@vchin](https://github.com/vchin). Package version 3 is a completely new package.

### Renamed APIs

The SDK now uses the product's names: Email Sandbox inboxes are **sandboxes** and sending domains are **domains**. The old names still work, call the same endpoints, and will be removed in a future major release. Each old option, getter and method emits a `DeprecationWarning` the first time it is used.

| Old name | New name |
|---|---|
| `testInboxId` config option | `sandboxId` |
| `client.testing` | `client.sandbox` |
| `client.testing.inboxes` | `client.sandbox.sandboxes` |
| `inboxes.getInboxAttributes()` | `sandboxes.getSandboxAttributes()` |
| `inboxes.updateInbox()` | `sandboxes.updateSandbox()` |
| `inboxes.cleanInbox()` | `sandboxes.cleanSandbox()` |
| `client.sendingDomains` | `client.domains` |

The other methods of `client.testing` and `client.sendingDomains` keep their names. Fields that mirror the API, such as `inbox_id` on messages or `sending_domain_id` on email logs, keep their names too. Passing both `sandboxId` and `testInboxId` with different values throws a `MailtrapError`.

The warnings carry the code `MAILTRAP_DEPRECATED_NAME`. `node --no-deprecation` silences them, along with every other deprecation warning.

### Upgrading to 5.0

`client.templates` now calls the paginated `/api/templates` endpoints instead of `/api/email_templates`:
Expand Down
4 changes: 2 additions & 2 deletions examples/batch/sandbox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@ import { MailtrapClient } from "mailtrap";
*/

const TOKEN = "<YOUR-TOKEN-HERE>";
const TEST_INBOX_ID = "<YOUR-TEST-INBOX-ID-HERE>";
const SANDBOX_ID = "<YOUR-SANDBOX-ID-HERE>";
const SENDER_EMAIL = "<SENDER@YOURDOMAIN.COM>";
const RECIPIENT_EMAIL = "<RECIPIENT@EMAIL.COM>";

const client = new MailtrapClient({
token: TOKEN,
sandbox: true,
testInboxId: TEST_INBOX_ID
sandboxId: Number(SANDBOX_ID)
});

client.batchSend({
Expand Down
2 changes: 1 addition & 1 deletion examples/company-info/everything.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ async function companyInfoFlow() {
});
console.log("Created company info:", JSON.stringify(created, null, 2));

// Get the company info of a sending domain
// Get the company info of a domain
const companyInfo = await client.companyInfo.get(DOMAIN_ID);
console.log("Company info:", JSON.stringify(companyInfo, null, 2));

Expand Down
57 changes: 57 additions & 0 deletions examples/domains/everything.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { MailtrapClient } from "mailtrap";

const TOKEN = "<YOUR-TOKEN-HERE>";
const ACCOUNT_ID = "<YOUR-ACCOUNT-ID-HERE>";

const client = new MailtrapClient({
token: TOKEN,
accountId: Number(ACCOUNT_ID),
});

async function domainsFlow() {
try {
// Get all domains
const all = await client.domains.getList();
console.log("All domains:", JSON.stringify(all, null, 2));

if (all.data && all.data.length > 0) {
// Get a specific domain
const one = await client.domains.get(all.data[0].id);
console.log("One domain:", JSON.stringify(one, null, 2));

// Send setup instructions
await client.domains.sendSetupInstructions(
all.data[0].id,
"admin@example.com"
);
console.log("Setup instructions sent");
} else {
console.log("No domains found for this account.");
}

// Create a new domain
const created = await client.domains.create({
domain_name: "test-domain-" + Date.now() + ".com",
});
console.log("Created domain:", JSON.stringify(created, null, 2));

// Update the settings of the created domain
const updated = await client.domains.update(created.id, {
open_tracking_enabled: true,
click_tracking_enabled: true,
tracking_opt_out_enabled: true,
auto_unsubscribe_link_enabled: false,
inbound_enabled: false,
});
console.log("Updated domain:", JSON.stringify(updated, null, 2));

// Delete the created domain
await client.domains.delete(created.id);
console.log("Domain deleted");

} catch (error) {
console.error("Error in domainsFlow:", error instanceof Error ? error.message : String(error));
}
}

domainsFlow();
4 changes: 2 additions & 2 deletions examples/email-campaigns/everything.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { MailtrapClient } from "mailtrap";

const TOKEN = "<YOUR-TOKEN-HERE>";
// ID of a verified sending domain on the account (required to create a campaign),
// as returned by the Sending Domains endpoints.
// ID of a verified domain on the account (required to create a campaign),
// as returned by `client.domains`.
const SENDING_DOMAIN_ID = "<YOUR-SENDING-DOMAIN-ID-HERE>";

// The Email Campaigns API is token-scoped — no `accountId` is needed.
Expand Down
3 changes: 1 addition & 2 deletions examples/general/account-accesses.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import { MailtrapClient } from "mailtrap"

const TOKEN = "<YOUR-TOKEN-HERE>";
const TEST_INBOX_ID = "<YOUR-TEST-INBOX-ID-HERE>"
const ACCOUNT_ID = "<YOUR-ACCOUNT-ID-HERE>"

const client = new MailtrapClient({ token: TOKEN, testInboxId: TEST_INBOX_ID, accountId: ACCOUNT_ID });
const client = new MailtrapClient({ token: TOKEN, accountId: Number(ACCOUNT_ID) });

const accountAccessesClient = client.general.accountAccesses

Expand Down
3 changes: 1 addition & 2 deletions examples/general/billing.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import { MailtrapClient } from "mailtrap"

const TOKEN = "<YOUR-TOKEN-HERE>";
const TEST_INBOX_ID = "<YOUR-TEST-INBOX-ID-HERE>"
const ACCOUNT_ID = "<YOUR-ACCOUNT-ID-HERE>"

const client = new MailtrapClient({ token: TOKEN, testInboxId: TEST_INBOX_ID, accountId: ACCOUNT_ID });
const client = new MailtrapClient({ token: TOKEN, accountId: Number(ACCOUNT_ID) });

const billingClient = client.general.billing

Expand Down
3 changes: 1 addition & 2 deletions examples/general/permissions.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import { MailtrapClient } from "mailtrap"

const TOKEN = "<YOUR-TOKEN-HERE>";
const TEST_INBOX_ID = "<YOUR-TEST-INBOX-ID-HERE>"
const ACCOUNT_ID = "<YOUR-ACCOUNT-ID-HERE>"

const client = new MailtrapClient({ token: TOKEN, testInboxId: TEST_INBOX_ID, accountId: ACCOUNT_ID });
const client = new MailtrapClient({ token: TOKEN, accountId: Number(ACCOUNT_ID) });

const permissionsClient = client.general.permissions

Expand Down
2 changes: 1 addition & 1 deletion examples/marketing-stats/everything.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ async function marketingStatsFlow() {
console.log("Campaigns only:", JSON.stringify(campaigns.data, null, 2));

// Narrow further by recipient email service provider; add
// `sending_domain_ids` (from the Sending Domains endpoints) to pick domains.
// `sending_domain_ids` (from `client.domains`) to pick domains.
const automationsAtGoogle = await client.marketingStats.get({
...dateRange,
sources: ["automations"],
Expand Down
32 changes: 32 additions & 0 deletions examples/sandbox/attachments.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { MailtrapClient } from "mailtrap"

const TOKEN = "<YOUR-TOKEN-HERE>";
const ACCOUNT_ID = "<YOUR-ACCOUNT-ID-HERE>"

const client = new MailtrapClient({ token: TOKEN, accountId: Number(ACCOUNT_ID) });

const sandboxesClient = client.sandbox.sandboxes
const messagesClient = client.sandbox.messages
const attachmentsClient = client.sandbox.attachments

sandboxesClient.getList()
.then(async (sandboxes) => {
if (sandboxes && sandboxes.length > 0) {
const firstSandboxId = sandboxes[0].id

const messages = await messagesClient.get(firstSandboxId)

if (messages && messages.length > 0) {
const firstMessageId = messages[0].id

const attachments = await attachmentsClient.getList(firstSandboxId, firstMessageId)

if (attachments && attachments.length > 0) {
const firstAttachment = attachments[0].id
const attachmentData = await attachmentsClient.get(firstSandboxId, firstMessageId, firstAttachment)

console.log(attachmentData)
}
}
}
})
39 changes: 39 additions & 0 deletions examples/sandbox/messages.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { MailtrapClient } from "mailtrap"

const TOKEN = "<YOUR-TOKEN-HERE>";
const ACCOUNT_ID = "<YOUR-ACCOUNT-ID-HERE>"

const client = new MailtrapClient({ token: TOKEN, accountId: Number(ACCOUNT_ID) });

const sandboxesClient = client.sandbox.sandboxes
const messagesClient = client.sandbox.messages

sandboxesClient.getList()
.then(async (sandboxes) => {
if (sandboxes && sandboxes.length > 0) {
const firstSandboxId = sandboxes[0].id

const messages = await messagesClient.get(firstSandboxId)

if (messages && messages.length > 0) {
const firstMessageId = messages[0].id

await messagesClient.getHtmlAnalysis(firstSandboxId, firstMessageId)
await messagesClient.getHtmlMessage(firstSandboxId, firstMessageId)
await messagesClient.getTextMessage(firstSandboxId, firstMessageId)
await messagesClient.getMailHeaders(firstSandboxId, firstMessageId)
await messagesClient.getMessageAsEml(firstSandboxId, firstMessageId)
await messagesClient.getMessageHtmlSource(firstSandboxId, firstMessageId)
await messagesClient.getRawMessage(firstSandboxId, firstMessageId)
await messagesClient.getSpamScore(firstSandboxId, firstMessageId)
await messagesClient.showEmailMessage(firstSandboxId, firstMessageId)
await messagesClient.updateMessage(firstSandboxId, firstMessageId, {
isRead: false
})
await messagesClient.forward(firstSandboxId, firstMessageId, 'mock@mail.com')
const response = await messagesClient.deleteMessage(firstSandboxId, firstMessageId)

console.log(response)
}
}
})
5 changes: 2 additions & 3 deletions examples/testing/projects.ts → examples/sandbox/projects.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import { MailtrapClient } from "mailtrap"

const TOKEN = "<YOUR-TOKEN-HERE>";
const TEST_INBOX_ID = "<YOUR-TEST-INBOX-ID-HERE>"
const ACCOUNT_ID = "<YOUR-ACCOUNT-ID-HERE>"

const client = new MailtrapClient({ token: TOKEN, testInboxId: TEST_INBOX_ID, accountId: ACCOUNT_ID });
const client = new MailtrapClient({ token: TOKEN, accountId: Number(ACCOUNT_ID) });

const projectsClient = client.testing.projects
const projectsClient = client.sandbox.projects

projectsClient.getList()
.then(async (projects) => {
Expand Down
32 changes: 32 additions & 0 deletions examples/sandbox/sandboxes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { MailtrapClient } from "mailtrap"

const TOKEN = "<YOUR-TOKEN-HERE>";
const ACCOUNT_ID = "<YOUR-ACCOUNT-ID-HERE>"

const client = new MailtrapClient({ token: TOKEN, accountId: Number(ACCOUNT_ID) });

const projectsClient = client.sandbox.projects
const sandboxesClient = client.sandbox.sandboxes

projectsClient.getList()
.then(async (projects) => {
if (projects && projects.length > 0) {
const firstProjectId = projects[0].id

// Work on the sandbox created here, so the account's existing sandboxes stay untouched.
const { id: sandboxId } = await sandboxesClient.create(firstProjectId, 'test-sandbox')

const sandboxes = await sandboxesClient.getList()
console.log(sandboxes)

const sandboxAttributes = await sandboxesClient.getSandboxAttributes(sandboxId)
await sandboxesClient.updateSandbox(sandboxId, {name: 'mock-name', emailUsername: 'mocker'})
await sandboxesClient.cleanSandbox(sandboxId)
await sandboxesClient.markAsRead(sandboxId)
await sandboxesClient.resetCredentials(sandboxId)
await sandboxesClient.enableEmailAddress(sandboxId)
const response = await sandboxesClient.resetEmailAddress(sandboxId)

console.log(response)
}
})
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ import { MailtrapClient } from "mailtrap"


const TOKEN = "<YOUR-TOKEN-HERE>";
const TEST_INBOX_ID = "<YOUR-TEST-INBOX-ID-HERE>"
const SANDBOX_ID = "<YOUR-SANDBOX-ID-HERE>"
const SENDER_EMAIL = "<SENDER@YOURDOMAIN.COM>";
const RECIPIENT_EMAIL = "<RECIPIENT@EMAIL.COM>";

const client = new MailtrapClient({ token: TOKEN, sandbox: true, testInboxId: TEST_INBOX_ID });
const client = new MailtrapClient({ token: TOKEN, sandbox: true, sandboxId: Number(SANDBOX_ID) });

client.send({
from: { name: "Mailtrap Test", email: SENDER_EMAIL },
Expand Down
5 changes: 3 additions & 2 deletions examples/testing/template.ts → examples/sandbox/template.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,13 @@ import { MailtrapClient } from "mailtrap"
*/

const TOKEN = "<YOUR-TOKEN-HERE>";
const SANDBOX_ID = "<YOUR-SANDBOX-ID-HERE>";
const SENDER_EMAIL = "<SENDER@YOURDOMAIN.COM>";
const RECIPIENT_EMAIL = "<RECIPIENT@EMAIL.COM>";

const client = new MailtrapClient({ token: TOKEN });
const client = new MailtrapClient({ token: TOKEN, sandbox: true, sandboxId: Number(SANDBOX_ID) });

client.testing.send({
client.send({
from: { name: "Mailtrap Test", email: SENDER_EMAIL },
to: [{ email: RECIPIENT_EMAIL }],
template_uuid: "813e39db-c74a-4830-b037-0e6ba8b1fe88",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ import { MailtrapTransport } from "mailtrap"
*/

const TOKEN = "<YOUR-TOKEN-HERE>"
const TEST_INBOX_ID = "<YOUR-TEST-INBOX-ID-HERE>"
const SANDBOX_ID = "<YOUR-SANDBOX-ID-HERE>"
const SENDER_EMAIL = "<SENDER@YOURDOMAIN.COM>";
const RECIPIENT_EMAIL = "<RECIPIENT@EMAIL.COM>";

const transport = Nodemailer.createTransport(MailtrapTransport({
token: TOKEN,
testInboxId: TEST_INBOX_ID,
sandboxId: Number(SANDBOX_ID),
sandbox: true
}))

Expand Down
Loading
Loading