원클릭으로
wraps-email
TypeScript SDK for AWS SES with automatic credential resolution, React.email support, and template management.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
TypeScript SDK for AWS SES with automatic credential resolution, React.email support, and template management.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
CLI that deploys SES, DynamoDB, Lambda, and IAM resources to your AWS account with automatic DKIM, SPF, DMARC configuration.
Email deliverability, warming, compliance, and operational guidelines for AWS Simple Email Service.
Best practices for email content that avoids spam filters. Apply these rules when writing email copy, building templates, or debugging spam placement issues.
Interactive SES deliverability troubleshooting. Diagnoses bounces, spam placement, send failures, account health, and complaint issues with targeted AWS CLI commands and ordered remediation steps.
Get started with Wraps email infrastructure. Guides through deploying infrastructure, verifying a domain, installing the SDK, and sending the first email. Adapts to project framework and hosting provider.
TypeScript SDK for AWS End User Messaging (Pinpoint SMS) with opt-out management, batch sending, and E.164 validation.
| name | wraps-email |
| description | TypeScript SDK for AWS SES with automatic credential resolution, React.email support, and template management. |
TypeScript SDK for AWS SES with automatic credential resolution, React.email support, and template management. Calls your SES directly — no proxy, no markup.
npm install @wraps.dev/email
# or
pnpm add @wraps.dev/email
import { WrapsEmail } from '@wraps.dev/email';
const email = new WrapsEmail();
const result = await email.send({
from: 'hello@yourapp.com',
to: 'user@example.com',
subject: 'Welcome!',
html: '<h1>Hello from Wraps!</h1>',
});
console.log('Sent:', result.messageId);
// Uses AWS credential chain (env vars, IAM role, ~/.aws/credentials)
const email = new WrapsEmail();
const email = new WrapsEmail({
region: 'us-west-2', // defaults to us-east-1
});
const email = new WrapsEmail({
region: 'us-east-1',
credentials: {
accessKeyId: process.env.AWS_ACCESS_KEY_ID!,
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!,
},
});
// For Vercel, EKS, GitHub Actions with OIDC federation
const email = new WrapsEmail({
region: 'us-east-1',
roleArn: 'arn:aws:iam::123456789012:role/WrapsEmailRole',
roleSessionName: 'my-app-session', // optional
});
import { fromWebToken } from '@aws-sdk/credential-providers';
const credentials = fromWebToken({
roleArn: process.env.AWS_ROLE_ARN!,
webIdentityToken: async () => process.env.VERCEL_OIDC_TOKEN!,
});
const email = new WrapsEmail({
region: 'us-east-1',
credentials,
});
import { SESClient } from '@aws-sdk/client-ses';
const sesClient = new SESClient({ region: 'us-east-1' });
const email = new WrapsEmail({ client: sesClient });
const result = await email.send({
from: 'sender@example.com',
to: 'recipient@example.com',
subject: 'Hello!',
html: '<h1>Welcome</h1><p>This is a test email.</p>',
text: 'Welcome! This is a test email.', // optional fallback
});
await email.send({
from: { email: 'hello@example.com', name: 'My App' },
to: 'user@example.com',
subject: 'Welcome!',
html: '<h1>Hello!</h1>',
});
await email.send({
from: 'sender@example.com',
to: ['user1@example.com', 'user2@example.com'],
cc: 'manager@example.com',
bcc: ['audit@example.com'],
subject: 'Team Update',
html: '<p>Hello team!</p>',
});
await email.send({
from: 'noreply@example.com',
to: 'user@example.com',
replyTo: 'support@example.com',
subject: 'Your Request',
html: '<p>We received your request.</p>',
});
await email.send({
from: 'sender@example.com',
to: 'user@example.com',
subject: 'Welcome!',
html: '<h1>Hello!</h1>',
tags: {
campaign: 'onboarding',
userId: 'user_123',
},
});
await email.send({
from: 'sender@example.com',
to: 'user@example.com',
subject: 'Welcome!',
html: '<h1>Hello!</h1>',
configurationSetName: 'wraps-email-tracking', // for opens/clicks/bounces
});
Use React components for beautiful, maintainable email templates.
import { WrapsEmail } from '@wraps.dev/email';
import WelcomeEmail from './emails/welcome';
const email = new WrapsEmail();
await email.send({
from: 'hello@example.com',
to: 'user@example.com',
subject: 'Welcome to Our App!',
react: <WelcomeEmail username="John" />,
});
Note: Cannot use both html and react — choose one.
import { readFileSync } from 'fs';
await email.send({
from: 'sender@example.com',
to: 'user@example.com',
subject: 'Your Invoice',
html: '<p>Please find your invoice attached.</p>',
attachments: [
{
filename: 'invoice.pdf',
content: readFileSync('./invoice.pdf'),
contentType: 'application/pdf',
},
{
filename: 'logo.png',
content: Buffer.from(base64Logo, 'base64'),
contentType: 'image/png',
},
],
});
Limits:
SES templates allow personalized bulk emails with variable substitution.
await email.templates.create({
name: 'welcome-email',
subject: 'Welcome, {{name}}!',
html: '<h1>Hello {{name}}</h1><p>Thanks for joining {{company}}!</p>',
text: 'Hello {{name}}, Thanks for joining {{company}}!',
});
import WelcomeTemplate from './emails/welcome-template';
await email.templates.createFromReact({
name: 'welcome-email',
subject: 'Welcome, {{name}}!',
react: <WelcomeTemplate />, // Use {{variable}} placeholders in the component
});
await email.sendTemplate({
from: 'hello@example.com',
to: 'user@example.com',
template: 'welcome-email',
templateData: {
name: 'John',
company: 'Acme Inc',
},
});
const result = await email.sendBulkTemplate({
from: 'hello@example.com',
template: 'welcome-email',
destinations: [
{ to: 'user1@example.com', templateData: { name: 'Alice', company: 'Acme' } },
{ to: 'user2@example.com', templateData: { name: 'Bob', company: 'Acme' } },
{ to: 'user3@example.com', templateData: { name: 'Carol', company: 'Acme' } },
],
defaultTemplateData: {
company: 'Acme Inc', // fallback if not in destination
},
});
// Check results
result.status.forEach((s, i) => {
if (s.status === 'success') {
console.log(`Email ${i} sent: ${s.messageId}`);
} else {
console.log(`Email ${i} failed: ${s.error}`);
}
});
Limit: Maximum 50 destinations per bulk send.
// List all templates
const templates = await email.templates.list();
// Get template details
const template = await email.templates.get('welcome-email');
// Update template
await email.templates.update({
name: 'welcome-email',
subject: 'Welcome aboard, {{name}}!',
html: '<h1>Welcome {{name}}!</h1>',
});
// Delete template
await email.templates.delete('welcome-email');
import { WrapsEmail, SESError, ValidationError } from '@wraps.dev/email';
try {
await email.send({
from: 'sender@example.com',
to: 'user@example.com',
subject: 'Hello',
html: '<p>Hi!</p>',
});
} catch (error) {
if (error instanceof ValidationError) {
// Invalid parameters (e.g., invalid email format)
console.error('Validation error:', error.message);
} else if (error instanceof SESError) {
// AWS SES error
console.error('SES error:', error.message);
console.error('Error code:', error.code);
console.error('Request ID:', error.requestId);
console.error('Is throttled:', error.isThrottled);
} else {
throw error;
}
}
// When done (e.g., in serverless cleanup or app shutdown)
email.destroy();
import type {
WrapsEmailConfig,
SendEmailParams,
SendEmailResult,
SendTemplateParams,
SendBulkTemplateParams,
SendBulkTemplateResult,
CreateTemplateParams,
UpdateTemplateParams,
Template,
TemplateMetadata,
EmailAddress,
Attachment,
} from '@wraps.dev/email';
import { WrapsEmail } from '@wraps.dev/email';
class EmailService {
private email: WrapsEmail;
constructor() {
this.email = new WrapsEmail({
region: process.env.AWS_REGION,
configurationSetName: 'wraps-email-tracking',
});
}
async sendWelcome(to: string, name: string) {
return this.email.send({
from: { email: 'hello@myapp.com', name: 'My App' },
to,
subject: `Welcome, ${name}!`,
html: `<h1>Welcome ${name}!</h1><p>Thanks for signing up.</p>`,
tags: { type: 'welcome', userId: to },
});
}
async sendPasswordReset(to: string, resetLink: string) {
return this.email.send({
from: 'security@myapp.com',
to,
subject: 'Reset Your Password',
html: `<p>Click <a href="${resetLink}">here</a> to reset your password.</p>`,
tags: { type: 'password-reset' },
});
}
}
import { WrapsEmail } from '@wraps.dev/email';
// Initialize outside handler for connection reuse
const email = new WrapsEmail({
roleArn: process.env.AWS_ROLE_ARN,
});
export async function POST(request: Request) {
const { to, subject, html } = await request.json();
const result = await email.send({
from: 'noreply@myapp.com',
to,
subject,
html,
});
return Response.json({ messageId: result.messageId });
}
npx @wraps.dev/cli email init for easy setup)