Skip to content

Mail

The Mail namespace provides access to the in-game email system. Send emails to the player, attach custom metadata for programmatic detection, and read their inbox.

Required permission: mail

Import

typescript
import { Mail } from "@hotbunny/hackhub-content-sdk";

Methods

Mail.send(mail)

Send an email to the player's inbox.

ParameterTypeDescription
mail.subjectstringEmail subject line
mail.contentstringEmail body (supports HTML)
mail.fromstring?Sender email address
mail.tostring?Recipient (defaults to player)
mail.metadataRecord<string, any>?Custom data (not visible to player, available in events)
mail.attachmentsMailAttachment[]?File attachments
typescript
Mail.send({
    from: "[email protected]",
    subject: "New assignment",
    content: "Your target is 192.168.1.50. Good luck.",
});

Mail.send({
    from: "[email protected]",
    subject: "Password Reset",
    content: "<p>Click <a href='#'>here</a> to reset your password.</p>",
    metadata: { campaignId: "phish-01", targetType: "admin" },
    attachments: [
        { name: "credentials", extension: "txt", data: "admin:password123" },
    ],
});

Mail.sendBounce(failedRecipient, options?)

Send a realistic "undeliverable" bounce to the player, as if it came from a mailer-daemon at their own mail provider. Useful for phishing scenarios: when the player emails an address that doesn't exist, reply with a bounce so they learn the address was wrong instead of failing silently.

ParameterTypeDescription
failedRecipientstringThe address that could not be reached (shown in the bounce body)
options.tostring?Recipient of the bounce (defaults to the player)
typescript
Events.on("Mail.Sent", (mail) => {
    const validTargets = ["[email protected]", "[email protected]"];
    if (!validTargets.includes(mail.to)) {
        // Player emailed an address that doesn't exist -> bounce it back
        Mail.sendBounce(mail.to);
    }
});

The bounce subject and body are fully localized to the player's language.

Mail.registerTemplate(template)

Register a custom mail template in GoMail's compose dropdown. Players can select this template when writing emails.

ParameterTypeDescription
template.idstringUnique template identifier
template.labelstringLabel shown in the dropdown
template.titlestringEmail subject line when selected
template.contentstringEmail body with placeholders
template.fieldsstring[]?Editable field names
typescript
Mail.registerTemplate({
    id: "fake_security_alert",
    label: "Security Alert",
    title: "Security Alert: Unusual Login",
    content: "Dear {{name}}, we detected a login from {{ip}}. If this wasn't you, reset your password immediately.",
    fields: ["name", "ip"],
});

Mail.unregisterTemplate(id)

Remove a previously registered mail template from GoMail.

typescript
Mail.unregisterTemplate("fake_security_alert");

Mail.getInbox()

Get all emails in the player's inbox.

Returns: MailInfo[]

typescript
const inbox = Mail.getInbox();
const unread = inbox.filter((m) => !m.read);
console.log(`${unread.length} unread emails`);

Mail.markAsRead(id)

Mark an email as read.

typescript
const inbox = Mail.getInbox();
Mail.markAsRead(inbox[0].id);

Mail.getPlayerEmail()

Get the player's email address.

Returns: string

typescript
const email = Mail.getPlayerEmail();
// e.g. "[email protected]"

Events

Mail.Received

Fires when any email is sent or received (including mails sent by the player via GoMail).

typescript
import { Events, Mail } from "@hotbunny/hackhub-content-sdk";

Events.on("Mail.Received", (mail) => {
    console.log(mail.from, mail.to, mail.subject, mail.content);

    // Detect a mail you sent via metadata
    if (mail.metadata?.campaignId === "phish-01") {
        // This is the phishing mail we sent earlier
    }

    // Detect player sending mail via GoMail
    if (mail.from === Mail.getPlayerEmail()) {
        // Player just sent an email - auto-reply
        Mail.send({
            from: mail.to,
            to: mail.from,
            subject: "Re: " + mail.subject,
            content: "Thank you for contacting us.",
        });
    }
});

Mail.Sent

Fires only when the player sends an email via GoMail. Convenient alternative to filtering Mail.Received by sender.

typescript
Events.on("Mail.Sent", (mail) => {
    if (mail.to === "[email protected]") {
        // Player sent mail to Binance - generate reply
        Mail.send({
            from: "[email protected]",
            to: mail.from,
            subject: "Re: " + mail.subject,
            content: "Your request has been processed.",
        });
    }
});

Types

MailDefinition

typescript
interface MailDefinition {
    subject: string;
    content: string;
    from?: string;
    to?: string;
    metadata?: Record<string, any>;
    attachments?: MailAttachment[];
}

MailTemplateDefinition

typescript
interface MailTemplateDefinition {
    id: string;
    label: string;
    title: string;
    content: string;
    fields?: string[];
}

MailAttachment

typescript
interface MailAttachment {
    name: string;
    extension: string;
    data?: string;
}

MailInfo

typescript
interface MailInfo {
    id: string;
    from: string;
    to: string;
    subject: string;
    read: boolean;
    sentAt: number;
}

MailEvent

Event payload received via Events.on("Mail.Received") or Events.on("Mail.Sent").

typescript
interface MailEvent {
    id: string;
    from: string;
    to: string;
    subject: string;
    content: string;
    sentAt: number;
    metadata?: Record<string, any>;
}

HotBunny Interactive Entertainment Inc.