Loading...
Loading...
Email delivery patterns including single, batch, scheduled emails and attachment handling. Use when building transactional email systems, batch communication workflows, scheduled delivery, or implementing file/URL attachments with reply-to and CC/BCC functionality.
npx skill4agent add vanman2024/ai-dev-marketplace email-deliveryimport { Resend } from 'resend';
const resend = new Resend('your_resend_key_here');
async function sendTransactionalEmail() {
const { data, error } = await resend.emails.send({
from: 'notifications@example.com',
to: 'user@example.com',
subject: 'Welcome to Example',
html: '<h1>Welcome!</h1><p>Thank you for signing up.</p>',
});
if (error) {
console.error('Failed to send email:', error);
return null;
}
return data;
}async function sendBatchEmails(recipients: Array<{email: string; name: string}>) {
const emails = recipients.map(recipient => ({
from: 'newsletter@example.com',
to: recipient.email,
subject: `Hello ${recipient.name}!`,
html: `<p>Welcome ${recipient.name}</p>`,
}));
const { data, error } = await resend.batch.send(emails);
if (error) {
console.error('Batch send failed:', error);
return null;
}
return data;
}async function scheduleEmail(scheduledAt: Date) {
const { data, error } = await resend.emails.send({
from: 'marketing@example.com',
to: 'user@example.com',
subject: 'Scheduled Message',
html: '<p>This was scheduled!</p>',
scheduled_at: scheduledAt.toISOString(),
});
if (error) {
console.error('Failed to schedule email:', error);
return null;
}
return data;
}import fs from 'fs';
import path from 'path';
async function sendWithFileAttachment(filePath: string) {
const fileContent = fs.readFileSync(filePath);
const fileName = path.basename(filePath);
const { data, error } = await resend.emails.send({
from: 'documents@example.com',
to: 'recipient@example.com',
subject: 'Your Document',
html: '<p>Please find attached your document.</p>',
attachments: [
{
filename: fileName,
content: fileContent,
},
],
});
return { data, error };
}async function sendWithBufferAttachment(buffer: Buffer, filename: string) {
const { data, error } = await resend.emails.send({
from: 'reports@example.com',
to: 'user@example.com',
subject: 'Monthly Report',
html: '<p>Your monthly report is attached.</p>',
attachments: [
{
filename: filename,
content: buffer,
},
],
});
return { data, error };
}async function sendWithUrlAttachment(fileUrl: string) {
const response = await fetch(fileUrl);
const buffer = await response.arrayBuffer();
const { data, error } = await resend.emails.send({
from: 'notifications@example.com',
to: 'user@example.com',
subject: 'Download Your File',
html: '<p>Your file is ready.</p>',
attachments: [
{
filename: 'document.pdf',
content: Buffer.from(buffer),
},
],
});
return { data, error };
}async function sendWithRouting(mainRecipient: string) {
const { data, error } = await resend.emails.send({
from: 'support@example.com',
to: mainRecipient,
reply_to: 'support-team@example.com',
cc: ['manager@example.com'],
bcc: ['archive@example.com'],
subject: 'Support Ticket #12345',
html: '<p>We received your support request.</p>',
});
return { data, error };
}import os
from resend import Resend
client = Resend(api_key=os.environ.get("RESEND_API_KEY"))
def send_email():
email = {
"from": "notifications@example.com",
"to": "user@example.com",
"subject": "Welcome",
"html": "<h1>Welcome!</h1>",
}
response = client.emails.send(email)
return responsedef send_batch_emails(recipients):
emails = [
{
"from": "newsletter@example.com",
"to": recipient["email"],
"subject": f"Hello {recipient['name']}",
"html": f"<p>Welcome {recipient['name']}</p>",
}
for recipient in recipients
]
response = client.batch.send(emails)
return responsedef send_with_attachment(file_path):
with open(file_path, 'rb') as f:
file_content = f.read()
email = {
"from": "documents@example.com",
"to": "recipient@example.com",
"subject": "Your Document",
"html": "<p>Document attached.</p>",
"attachments": [
{
"filename": "document.pdf",
"content": file_content,
}
],
}
response = client.emails.send(email)
return responseRESEND_API_KEY=your_resend_key_here
RESEND_FROM_EMAIL=your-verified-email@example.cominterface EmailPayload {
from: string; // Verified sender email
to: string | string[]; // Recipient(s)
cc?: string[]; // Carbon copy recipients
bcc?: string[]; // Blind carbon copy
reply_to?: string; // Reply-to address
subject: string; // Email subject
html?: string; // HTML content
text?: string; // Plain text fallback
attachments?: Array<{
filename: string;
content: Buffer | string;
}>;
scheduled_at?: string; // ISO 8601 datetime for scheduling
tags?: Array<{
name: string;
value: string;
}>;
}async function sendWithRetry(emailPayload, maxRetries = 3) {
for (let attempt = 1; attempt <= maxRetries; attempt++) {
const { data, error } = await resend.emails.send(emailPayload);
if (!error) return { data, success: true };
if (error.message?.includes('rate_limit') && attempt < maxRetries) {
const delay = Math.pow(2, attempt) * 1000;
await new Promise(resolve => setTimeout(resolve, delay));
continue;
}
return { error, success: false };
}
}async function sendLargeBatch(emails: EmailPayload[]) {
const batchSize = 100;
const results = [];
for (let i = 0; i < emails.length; i += batchSize) {
const batch = emails.slice(i, i + batchSize);
const { data, error } = await resend.batch.send(batch);
if (error) {
console.error(`Batch ${Math.floor(i / batchSize) + 1} failed:`, error);
results.push({ success: false, error });
} else {
results.push({ success: true, data });
}
// Rate limit handling - wait between batches
if (i + batchSize < emails.length) {
await new Promise(resolve => setTimeout(resolve, 1000));
}
}
return results;
}single-email/batch-emails/attachments/scheduled/RESEND_API_KEY