# Email Workers 模式
## 解析邮件
typescript
import PostalMime from 'postal-mime';
export default {
async email(message, env, ctx) {
const buffer = await new Response(message.raw).arrayBuffer();
const email = await PostalMime.parse(buffer);
console.log(email.from, email.subject, email.text, email.attachments.length);
await message.forward('
[email protected]');
}
};
## 过滤
typescript
// 从 KV 获取允许列表
const allowList = await env.ALLOWED_SENDERS.get('list', 'json') || [];
if (!allowList.includes(message.from)) {
message.setReject('Not allowed');
return;
}
// 大小检查(避免解析过大的邮件)
if (message.rawSize > 5_000_000) {
await message.forward('
[email protected]'); // 直接转发而不解析
return;
}
## 带会话的自动回复
typescript
import { EmailMessage } from 'cloudflare:email';
import { createMimeMessage } from 'mimetext';
const msg = createMimeMessage();
msg.setSender({ addr: '
[email protected]' });
msg.setRecipient(message.from);
msg.setSubject(`Re: ${message.headers.get('Subject')}`);
msg.setHeader('In-Reply-To', message.headers.get('Message-ID') || '');
msg.addMessage({ contentType: 'text/plain', data: 'Thank you. We will respond.' });
await message.reply(new EmailMessage('
[email protected]', message.from, msg.asRaw()));
## 限流自动回复
typescript
const rateKey = `rate:${message.from}`;
if (!await env.RATE_LIMIT.get(rateKey)) {
// 发送回复...
ctx.waitUntil(env.RATE_LIMIT.put(rateKey, '1', { expirationTtl: 3600 }));
}
## 基于主题的路由
typescript
const subject = (message.headers.get('Subject') || '').toLowerCase();
if (subject.includes('billing')) await message.forward('
[email protected]');
else if (subject.includes('support')) await message.forward('
[email protected]');
else await message.forward('
[email protected]');
## 多租户路由
typescript
//
[email protected] → tenant123
const tenantId = message.to.split('@')[0].match(/+(.+)$/)?.[1] || 'default';
const config = await env.TENANT_CONFIG.get(tenantId, 'json');
config?.forwardTo ? await message.forward(config.forwardTo) : message.setReject('Unknown');
## 归档与提取附件
typescript
// 归档到 KV
ctx.waitUntil(env.ARCHIVE.put(`email:${Date.now()}`, JSON.stringify({
from: message.from, subject: email.subject
})));
// 附件存入 R2
for (const att of email.attachments) {
ctx.waitUntil(env.R2.put(`${Date`