Prerequisites
To get the most out of this guide, you’ll need to:- Create a SendPost Account
- Cloudflare Account (free tier works)
- Wrangler CLI installed
- A Sub-Account API Key from your SendPost dashboard
You can find your API keys in your SendPost Dashboard. Make sure to use your Sub-Account API Key for sending emails.
1. Install Wrangler CLI
npm install -g wrangler
2. Initialize Worker
wrangler init sendpost-email
cd sendpost-email
3. Basic Email Worker
Updatesrc/index.ts:
TypeScript
export interface Env {
SENDPOST_API_KEY: string;
}
export default {
async fetch(request: Request, env: Env): Promise<Response> {
// Handle CORS
if (request.method === 'OPTIONS') {
return new Response(null, {
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'POST, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type',
},
});
}
if (request.method !== 'POST') {
return new Response(
JSON.stringify({ error: 'Method not allowed' }),
{
status: 405,
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*',
},
}
);
}
try {
const { to, subject, htmlBody, textBody } = await request.json();
if (!to || !subject || !htmlBody) {
return new Response(
JSON.stringify({
success: false,
error: 'Missing required fields: to, subject, htmlBody',
}),
{
status: 400,
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*',
},
}
);
}
// Prepare email message
const emailMessage = {
from: {
email: 'hello@playwithsendpost.io',
name: 'SendPost',
},
to: [{ email: to }],
subject,
htmlBody,
textBody: textBody || htmlBody.replace(/<[^>]*>/g, ''),
trackOpens: true,
trackClicks: true,
};
// Send email via SendPost API
const response = await fetch('https://api.sendpost.io/api/v1/subaccount/email/', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-SubAccount-ApiKey': env.SENDPOST_API_KEY,
},
body: JSON.stringify(emailMessage),
});
if (!response.ok) {
const error = await response.text();
throw new Error(`SendPost API error: ${error}`);
}
const result = await response.json();
return new Response(
JSON.stringify({
success: true,
messageId: result.messageId,
}),
{
status: 200,
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*',
},
}
);
} catch (error: any) {
console.error('SendPost error:', error);
return new Response(
JSON.stringify({
success: false,
error: error.message,
}),
{
status: 500,
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*',
},
}
);
}
},
};
4. Configure Worker
Updatewrangler.toml:
name = "sendpost-email"
main = "src/index.ts"
compatibility_date = "2023-10-30"
[vars]
# Environment variables (use secrets for sensitive data)
5. Set Secrets
Set the API key as a secret:wrangler secret put SENDPOST_API_KEY
6. Deploy Worker
Deploy to Cloudflare:wrangler deploy
7. Common Use Cases
Welcome Email Worker
Createsrc/welcome-email.ts:
TypeScript
export interface Env {
SENDPOST_API_KEY: string;
}
export default {
async fetch(request: Request, env: Env): Promise<Response> {
if (request.method === 'OPTIONS') {
return new Response(null, {
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'POST, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type',
},
});
}
try {
const { email, firstName } = await request.json();
if (!email || !firstName) {
return new Response(
JSON.stringify({
success: false,
error: 'Missing required fields: email, firstName',
}),
{
status: 400,
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*',
},
}
);
}
const emailMessage = {
from: {
email: 'hello@playwithsendpost.io',
name: 'SendPost',
},
to: [
{
email,
name: firstName,
customFields: { firstName },
},
],
subject: 'Welcome {{firstName}}!',
htmlBody: `
<h1>Welcome, {{firstName}}!</h1>
<p>Thank you for joining us. We're excited to have you on board.</p>
<p>Get started by exploring our features:</p>
<ul>
<li>Feature 1</li>
<li>Feature 2</li>
<li>Feature 3</li>
</ul>
<p>If you have any questions, just reply to this email.</p>
<p><a href="{{unsubscribe}}">Unsubscribe</a></p>
`,
textBody: `
Welcome, {{firstName}}!
Thank you for joining us. We're excited to have you on board.
Get started by exploring our features:
- Feature 1
- Feature 2
- Feature 3
If you have any questions, just reply to this email.
Unsubscribe: {{unsubscribe}}
`,
groups: ['welcome'],
trackOpens: true,
trackClicks: true,
};
const response = await fetch('https://api.sendpost.io/api/v1/subaccount/email/', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-SubAccount-ApiKey': env.SENDPOST_API_KEY,
},
body: JSON.stringify(emailMessage),
});
const result = await response.json();
return new Response(
JSON.stringify({
success: true,
messageId: result.messageId,
}),
{
status: 200,
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*',
},
}
);
} catch (error: any) {
return new Response(
JSON.stringify({
success: false,
error: error.message,
}),
{
status: 500,
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*',
},
}
);
}
},
};
8. Testing Locally
Run locally:wrangler dev
curl -X POST http://localhost:8787 \
-H "Content-Type: application/json" \
-d '{
"to": "user@example.com",
"subject": "Test Email",
"htmlBody": "<h1>Hello from Cloudflare Workers!</h1>"
}'
9. Using with Pages Functions
If using Cloudflare Pages, createfunctions/send-email.ts:
TypeScript
export async function onRequestPost(context: EventContext) {
const { request, env } = context;
// Same implementation as above
}
Make sure your sender email domain is verified in your SendPost account before sending emails.
10. Next Steps
Explore more examples and use cases:Cloudflare Workers
Learn more about Cloudflare Workers
Wrangler CLI
Learn more about Wrangler CLI
Quickstart Example
View a complete working example on GitHub