メール
ワーカーからメールを送信し、プロジェクトのアドレス宛に送られたメールをワーカーで受信できます。runlot が送信者の評判を管理し、受信メールサーバーを運用します。
すべてのプロジェクトにメールアドレスが 1 つあります。org acme のプロジェクト shop の場合:
| アドレス | |
|---|---|
| 送信 | [email protected] |
| 受信 | *@shop.acme.runlot.email — ローカルパートは何でも構いません |
アドレスはダッシュボードの Email タブ、または runlot email で確認できます。
送信
export default {
async fetch(request, env) {
await env.email.send({
to: "[email protected]", // string or array (up to 10)
subject: "Order received",
text: "Thanks. Shipping soon.",
html: "<p>Thanks. Shipping soon.</p>", // text or html is required
replyTo: "[email protected]", // optional
});
return new Response("ok");
},
};既定では from はありません — 送信者はプロジェクトアドレスです。自分で持っているドメインから送るには次の節をご覧ください。呼び出しは { id } を返し、失敗時には例外をスローします — e.status はHTTPステータスです(429は時間あたりの上限を意味します)。
自分のドメインから送る
ドメインを追加してレコードを 3 件公開すると、from が使えるようになります。
runlot email domain add acme.com公開するレコードが表示されます。このうち 3 件は必須で、公開しないと確認が終わりません。
| 種類 | 名前 | 値 |
|---|---|---|
| CNAME | <token1>._domainkey.acme.com | <token1>.dkim.amazonses.com |
| CNAME | <token2>._domainkey.acme.com | <token2>.dkim.amazonses.com |
| CNAME | <token3>._domainkey.acme.com | <token3>.dkim.amazonses.com |
残りの 2 件は推奨で、確認はこれを待ちません。
| 種類 | 名前 | 値 |
|---|---|---|
| TXT | acme.com | v=spf1 include:amazonses.com ~all |
| TXT | _dmarc.acme.com | v=DMARC1; p=none; adkim=r; aspf=r |
SPF レコードをソフトフェイル(~all)にしているのには理由があります。お持ちのドメインはすでに別の場所からもメールを送っている可能性が高く、当社がハードフェイルを加えるとそのメールが届かなくなります。厳しくするのはご自身の判断で行ってください。
runlot email domain verify acme.com確認中のドメインは当社も 1 分ごとに再確認します。レコードを公開したら、あとは待たずに別の作業に移っていただけます。DNS が行き渡るまで数分から数時間かかり、72 時間経ってもレコードが見えない場合は失敗として扱われるので、あらためて追加してください。
そのドメインのゾーンを当社がホストしている場合(runlot dns)は --publish を付けてください。レコードを代わりに書き込みます。ご自身で書いたレコードは上書きしません。
verified になれば、次のように使えます。
await env.email.send({
from: "[email protected]", // 確認済みドメインならローカル部は自由です
to: "[email protected]",
subject: "Order received",
text: "Thanks. Shipping soon.",
});確認済みドメインのサブドメインも使えます — [email protected] は acme.com でカバーされます。それ以外のドメインを from に指定すると from_not_verified で拒否され、まだ確認中のドメインも同じです。
runlot email domain list # ドメインと状態
runlot email domain rm acme.com # 削除 (admin)受信は引き続き *@<project>.<org>.runlot.email です。お持ちのドメインの MX を当社に向けることはまだできません。
受信
export default {
async fetch(request, env) { /* … */ },
async email(message, env, ctx) {
// message.from, message.to, message.headers (Headers), message.raw (ReadableStream), message.rawSize
const raw = await new Response(message.raw).text();
await env.db.query("insert into inbox (from_addr, to_addr, raw) values ($1, $2, $3)",
[message.from, message.to, raw]);
// To refuse — the sender sees this text
if (message.headers.get("authentication-results")?.includes("spf=fail")) {
message.setReject("SPF check failed");
}
},
};email ハンドラーは受信したメッセージごとに一度呼び出されます。message.raw はヘッダーを含むメッセージ全体です — 添付ファイルには postal-mime などのパーサーを使用してください。
ハンドラーをエクスポートしていないプロジェクト宛てのメールはバウンスします。ハンドラーが例外をスローすると、送信者は後で再試行します(一時的な失敗として扱われます)。
制限
| 値 | |
|---|---|
| 1時間あたりの送信数 | Free 30・Pro 300 — サインインメール(env.auth)と共有 |
| 1メッセージあたりの受信者数 | 10 |
| 1時間あたりの受信数 | 600 |
| 受信メッセージのサイズ | 25 MiB |
| ハンドラーの実行時間 | 30秒 |
送信の上限を超えると429が返されます。受信の上限を超えると、送信者には後で再試行するよう伝えられます。
送受信されたメールを確認する
送受信されたすべてのメッセージは、ダッシュボードの Email タブに1行として表示されます: 時刻・方向・from・to・件名・結果・サイズ。行をクリックするとヘッダーと本文が表示され、生メッセージは .eml としてダウンロードできます。HTML本文はレンダリングされず、ソースとして表示されます。
| プラン | 保存期間 |
|---|---|
| 無料 | 30日 |
| プロ | 365日 |
runlot email log # latest 50
runlot email log --direction in # received only
runlot email log --cursor <cursor> # next page
runlot email raw <mailId> > mail.eml # raw message受信メールの結果は、ハンドラーが行った処理を示します — 処理済み・拒否・ハンドラーなし・ハンドラーエラー。送信メールの結果は、リレーが受け入れたかどうか、受け入れなかった場合はその理由を示します。
対応していないもの
- **自分のドメインでの受信。**送信は上記のとおり可能です。お持ちのドメインの MX はまだ対応していません。
- 送信時の添付ファイル。
textとhtmlのみです。 - ニュースレター。 1メッセージあたり10件の宛先が絶対上限です。
- **
forward()/reply()。**どちらもenv.email.sendで実現できます。
CLI
runlot email # address and sent/received counts for the last hour and 24 hours
runlot email --json
runlot email delete # turn off (admin). Mail to this address will bounce
runlot email domain add acme.com [--publish] # send from your own domain
runlot email domain list # domains and their state
runlot email domain verify acme.com # re-check now
runlot email domain rm acme.com # remove (admin)