Skip to content

Instantly share code, notes, and snippets.

Last active June 10, 2024 20:35
Show Gist options
  • Save ihsangan/6111b59b9a7b022b5897d28d8454ad8d to your computer and use it in GitHub Desktop.
Save ihsangan/6111b59b9a7b022b5897d28d8454ad8d to your computer and use it in GitHub Desktop.
Send email from Workers with MailChannel API
async function readRequestBody(request) {
const { headers } = request;
const contentType = headers.get('content-type') || '';
if (contentType.includes('application/json')) {
return JSON.stringify(await request.json());
} else if (contentType.includes('form')) {
const formData = await request.formData();
const body = {};
for (const entry of formData.entries()) {
body[entry[0]] = entry[1];
let data = JSON.parse(JSON.stringify(body));
let combine = `{"personalizations":[{"to":[{"email":"${}","name":"${data.ton}"}],"dkim_domain":"${data.dkim}","dkim_selector":"${data.dkims}","dkim_private_key":"${data.dkimpk}"}],"from":{"email":"${data.from}","name":"${data.fromn}"},"reply_to":{"email":"${data.rep}","name":"${data.repn}"},"subject":"${data.sbj}","content":[{"type":"${data.type}","value":"${data.body}"}]}`;
return combine;
} else {
return '{"success":false}';
async function handleRequest(request) {
let start =;
let reqBody = await readRequestBody(request);
let send_request = new Request("", {
"method": "POST",
"headers": {
"content-type": "application/json",
"body": reqBody
let resp = await fetch(send_request);
let respText = await resp.text();
let end =;
let total = end - start;
return new Response(respText, {
headers: {
"X-MC-Status": resp.status,
"X-Response-Time": total
const htmlForm =`<!DOCTYPE html>
<meta content="width=device-width,initial-scale=1" name="viewport">
<title>Submit your email</title>
(*) is required
<form action="/" method="POST" autocomplete="on">
<input name="from" type="email" placeholder=" *" required><br>
<input name="fromn" type="text" placeholder="Sender Name"><br>
<input name="to" type="email" placeholder=" *" required><br>
<input name="ton" type="text" placeholder="Receiver Name"><br>
<input name="rep" type="email" placeholder=""><br>
<input name="repn" type="text" placeholder="Replier Name"><br>
<input name="dkim" type="text" placeholder="DKIM Domain"><br>
<input name="dkims" type="text" placeholder="DKIM Selector"><br>
<textarea name="dkimpk" rows="4" cols="23" type="text" placeholder="DKIM Private Key MIICXQIBAAKBgQCU......."></textarea><br>
<select name="type">
<option value="text/html; charset=utf-8">HTML</option>
<option value="text/plain; charset=utf-8" selected>Plain</option>
<input name="sbj" type="text" placeholder="Email Subject *" required><br>
<textarea name="body" rows="7" cols="23" placeholder="Email Body *" required></textarea><br>
<input type="submit" value="submit">
addEventListener('fetch', event => {
const { request } = event;
const { url } = request;
if (url.includes('submit')) {
return event.respondWith(new Response(htmlForm, {headers:{"Content-Type":"text/html"}}));
if (request.method === 'POST') {
return event.respondWith(handleRequest(request));
} else if (request.method === 'GET') {
return event.respondWith(new Response(`The request was a GET`));
Copy link

ihsangan commented Mar 7, 2022

curl -H 'Content-Type: application/json' -d '{"personalizations":[{"to":[{"email":"","name":"M"}]}],"from":{"email":"","name":"A"},"subject":"hi","content":[{"type":"text/plain","value":"hi"}]}' -v


Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment