feat: worker: use hono api

This commit is contained in:
dreamhunter2333
2023-08-16 14:29:49 +08:00
parent 98a4101eaf
commit f05d70f361
5 changed files with 84 additions and 77 deletions

View File

@@ -8,6 +8,7 @@
"name": "cloudflare_temp_email",
"version": "0.0.0",
"dependencies": {
"hono": "^3.4.3",
"postal-mime": "^1.0.16"
},
"devDependencies": {
@@ -914,6 +915,14 @@
"integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==",
"dev": true
},
"node_modules/hono": {
"version": "3.4.3",
"resolved": "https://registry.npmjs.org/hono/-/hono-3.4.3.tgz",
"integrity": "sha512-HbVxZh9yC3hV25+mFjUaM65t7g8ia2mXbhAGmVHA0r8+guizTJq1Cg4f2SmB5+JrviG0vaqOnWJ9U3O05aikbA==",
"engines": {
"node": ">=16.0.0"
}
},
"node_modules/http-cache-semantics": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz",

View File

@@ -10,6 +10,7 @@
"wrangler": "^3.0.0"
},
"dependencies": {
"hono": "^3.4.3",
"postal-mime": "^1.0.16"
}
}

30
worker/src/email.js Normal file
View File

@@ -0,0 +1,30 @@
const PostalMime = require("postal-mime");
async function email(message, env, ctx) {
if (!env.PREFIX || (message.to && message.to.startsWith(env.PREFIX))) {
const reader = message.raw.getReader();
const decoder = new TextDecoder("utf-8");
let rawEmail = "";
while (true) {
const { done, value } = await reader.read();
if (done) {
break;
}
rawEmail += decoder.decode(value);
}
const parser = new PostalMime.default();
const parsedEmail = await parser.parse(rawEmail);
const { success } = await env.DB.prepare(
`INSERT INTO mails (address, message) VALUES (?, ?)`
).bind(message.to, parsedEmail.html).run();
if (!success) {
message.setReject(`Failed save message to ${message.to}`);
}
} else {
message.setReject(`Unknown address ${message.to}`);
}
}
export { email }

30
worker/src/router.js Normal file
View File

@@ -0,0 +1,30 @@
import { Hono } from 'hono'
const api = new Hono()
api.get('/api/mails', async (c) => {
const { address } = c.req.query()
if (!address) {
return c.json({ "error": "No address" }, 400)
}
const { results } = await c.env.DB.prepare(
`SELECT id, message FROM mails where address = ? order by id desc limit 10`
).bind(address).all();
return c.json(results);
})
api.get('/api/new_address', async (c) => {
// insert new address
const name = Math.random().toString(36).substring(2, 15)
const { success } = await c.env.DB.prepare(
`INSERT INTO address (name) VALUES (?)`
).bind(name).run();
if (!success) {
return c.json({ "error": "Failed to create address" }, 500)
}
return c.json({
address: c.env.PREFIX + name + "@" + c.env.DOMAIN
})
})
export { api }

View File

@@ -1,80 +1,17 @@
const PostalMime = require("postal-mime");
import { Hono } from 'hono'
import { cors } from 'hono/cors';
import { api } from './router';
import { email } from './email';
const app = new Hono()
app.use('/*', cors());
app.route('/', api)
app.all('/*', async c => c.html(`<h1>Hello World</h1>`))
export default {
async fetch(request, env) {
const corsHeaders = {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "*",
"Access-Control-Max-Age": "86400",
"Access-Control-Allow-Headers": "*"
};
if (request.method === "OPTIONS") {
return new Response(null, {
headers: corsHeaders,
});
}
const { pathname, searchParams } = new URL(request.url);
const address = searchParams.get("address");
if (address && (pathname === "/api/mails" || pathname === "/api/mails/")) {
const { results } = await env.DB.prepare(
`SELECT id, message FROM mails where address = ? order by id desc limit 10`
).bind(address).all();
return new Response(JSON.stringify(results), {
headers: {
...corsHeaders,
"Content-Type": "application/json"
}
});
} else if (pathname === "/api/new_address" || pathname === "/api/new_address/") {
// insert new address
const name = Math.random().toString(36).substring(2, 15)
const { success } = await env.DB.prepare(
`INSERT INTO address (name) VALUES (?)`
).bind(name).run();
if (success) {
return new Response(JSON.stringify({
address: env.PREFIX + name + "@" + env.DOMAIN
}), {
headers: {
...corsHeaders,
"Content-Type": "application/json"
}
}
)
}
return new Response("error", {
headers: corsHeaders,
status: 500
});
}
return new Response("Hello, world!");
},
async email(message, env, ctx) {
if (!env.PREFIX || (message.to && message.to.startsWith(env.PREFIX))) {
const reader = message.raw.getReader();
const decoder = new TextDecoder("utf-8");
let rawEmail = "";
while (true) {
const { done, value } = await reader.read();
if (done) {
break;
}
rawEmail += decoder.decode(value);
}
const parser = new PostalMime.default();
const parsedEmail = await parser.parse(rawEmail);
const { success } = await env.DB.prepare(
`INSERT INTO mails (address, message) VALUES (?, ?)`
).bind(message.to, parsedEmail.html).run();
if (!success) {
message.setReject(`Failed save message to ${message.to}`);
}
} else {
message.setReject(`Unknown address ${message.to}`);
}
}
fetch: app.fetch,
email: email,
}