Skip to content
Back to skills

1228 Patterns E8704f7b

ASecurity

```typescript import PostalMime from 'postal-mime';

  • 9 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added October 11, 2026
content-marketingtypescriptaws

Security analysis

A100/100

Scanned October 11, 2026

npx -y skills add tools-only/X-Skills --skill 1228-patterns_e8704f7b --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of 1228 Patterns E8704f7b?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for 1228 Patterns E8704f7b
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/tools-only-1228-patterns-e8704f7b/badge)](https://www.skillsdirectory.com/skills/tools-only-1228-patterns-e8704f7b)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

SKILL.md
# Email Workers Patterns

## Parse Email

```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('inbox@example.com');
  }
};
```

## Filtering

```typescript
// Allowlist from KV
const allowList = await env.ALLOWED_SENDERS.get('list', 'json') || [];
if (!allowList.includes(message.from)) {
  message.setReject('Not allowed');
  return;
}

// Size check (avoid parsing large emails)
if (message.rawSize > 5_000_000) {
  await message.forward('inbox@example.com'); // Forward without parsing
  return;
}
```

## Auto-Reply with Threading

```typescript
import { EmailMessage } from 'cloudflare:email';
import { createMimeMessage } from 'mimetext';

const msg = createMimeMessage();
msg.setSender({ addr: 'support@example.com' });
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('support@example.com', message.from, msg.asRaw()));
```

## Rate-Limited Auto-Reply

```typescript
const rateKey = `rate:${message.from}`;
if (!await env.RATE_LIMIT.get(rateKey)) {
  // Send reply...
  ctx.waitUntil(env.RATE_LIMIT.put(rateKey, '1', { expirationTtl: 3600 }));
}
```

## Subject-Based Routing

```typescript
const subject = (message.headers.get('Subject') || '').toLowerCase();
if (subject.includes('billing')) await message.forward('billing@example.com');
else if (subject.includes('support')) await message.forward('support@example.com');
else await message.forward('general@example.com');
```

## Multi-Tenant Routing

```typescript
// support+tenant123@example.com → 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');
```

## Archive & Extract Attachments

```typescript
// Archive to KV
ctx.waitUntil(env.ARCHIVE.put(`email:${Date.now()}`, JSON.stringify({
  from: message.from, subject: email.subject
})));

// Attachments to R2
for (const att of email.attachments) {
  ctx.waitUntil(env.R2.put(`${Date.now()}-${att.filename}`, att.content));
}
```

## Webhook Integration

```typescript
ctx.waitUntil(
  fetch(env.WEBHOOK_URL, {
    method: 'POST',
    body: JSON.stringify({ from: message.from, subject: message.headers.get('Subject') })
  }).catch(err => console.error(err))
);
```

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.