Skip to content

Email

Email handler vals get their own email address that you can send email to, and when Val Town receives that email, it triggers the val with the email as its first argument. Ever wanted a robot that you could forward emails to, or to be able to control something via an email trigger? With email handler vals it’s simple: they get their own, unique address.

Type Signature

Email handlers receive an argument called Email and can do anything with it: they can go on to reply to the email with the standard library, or call methods in response to it.

Example
export function emailHandler(email: Email) {
console.log("Email received!");
}

The Email type has this shape:

interface Email {
from: string;
to: string[];
subject: string | undefined;
text: string | undefined;
html: string | undefined;
}

Example

Save received emails
import { blob } from "https://esm.town/v/std/blob";
import { email } from "https://esm.town/v/std/email";
export async function testEmail2(e: {
from: string;
to: string[];
subject: string;
text: string;
html: string;
}) {
const testEmails = await blob.getJSON("testEmails") as [];
await blob.setJSON("testEmails", [...testEmails, {
...e,
from: "~redacted~",
}]);
return email({
text: JSON.stringify(e),
subject: "Emailed received at @stevekrouse.testEmail2!",
});
}

The email address for a val @user.testEmail would be user.testEmail@valtown.email. Note that the username does not contain a leading @ and that the email domain is valtown.email.

You can view all the emails sent to your function with the following val:

List received emails
import { blob } from "https://esm.town/v/std/blob";
const testEmails = await blob.getJSON("testEmails") as [];
console.log("Received emails:\n", testEmails ?? []);