From cbf553119ceaea883a86bd051232b708ad91d130 Mon Sep 17 00:00:00 2001 From: oneisall Date: Tue, 7 Jan 2025 18:05:06 +0800 Subject: [PATCH] WorkerEntrypoint style & expose rpc interface --- .gitignore | 2 ++ src/index.ts | 31 ++++++++++++++++++++++--------- src/rpcEmail.ts | 41 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 65 insertions(+), 9 deletions(-) create mode 100644 src/rpcEmail.ts diff --git a/.gitignore b/.gitignore index 3b0fe33..a216f15 100644 --- a/.gitignore +++ b/.gitignore @@ -170,3 +170,5 @@ dist .dev.vars .wrangler/ +.wrangler +wrangler.toml \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index 708d531..72a0ee0 100644 --- a/src/index.ts +++ b/src/index.ts @@ -5,10 +5,12 @@ created by: github@TooonyChen created on: 2024 Oct 07 Last updated: 2024 Oct 07 */ +import { WorkerEntrypoint } from "cloudflare:workers"; +import {RPCEmailMessage} from './rpcEmail'; import indexHtml from './index.html'; -export interface Env { +interface Env { // If you set another name in wrangler.toml as the value for 'binding', // replace "DB" with the variable name you defined. DB: D1Database; @@ -20,8 +22,10 @@ export interface Env { UseBark: string; } -export default { - async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise { +export default class extends WorkerEntrypoint { + async fetch(request: Request): Promise { + const env: Env = this.env; + const ctx: ExecutionContext = this.ctx; // 将依赖 env 的常量移到函数内部 const FrontEndAdminID = env.FrontEndAdminID; const FrontEndAdminPassword = env.FrontEndAdminPassword; @@ -118,15 +122,16 @@ export default { console.error('Error querying database:', error); return new Response('Internal Server Error', { status: 500 }); } - }, + } // 主要功能 - async email(message, env, ctx) { + async email(message: ForwardableEmailMessage): Promise { + + const env: Env = this.env; const useBark = env.UseBark.toLowerCase() === 'true'; // true or false const GoogleAPIKey = env.GoogleAPIKey; // "xxxxxxxxxxxxxxxxxxxxxxxx" - - const rawEmail = await new Response(message.raw).text(); + const rawEmail = message instanceof RPCEmailMessage ? (message).rawEmail : await new Response(message.raw).text(); const message_id = message.headers.get("Message-ID"); // 将电子邮件保存到数据库 @@ -303,7 +308,15 @@ export default { console.error("Error calling AI or saving to database:", e); } } -} satisfies ExportedHandler; - + // 暴露rpc接口,处理来自其他worker的邮件请求 + async rpcEmail(requestBody: string): Promise { + console.log(`Received RPC email , request body: ${requestBody}`); + const bodyObject =JSON.parse(requestBody); + const headersObject = bodyObject.headers; + const headers = new Headers(headersObject); + const rpcEmailMessage: RPCEmailMessage = new RPCEmailMessage(bodyObject.from, bodyObject.to, bodyObject.rawEmail, headers); + await this.email(rpcEmailMessage); + } +} \ No newline at end of file diff --git a/src/rpcEmail.ts b/src/rpcEmail.ts new file mode 100644 index 0000000..dc505b0 --- /dev/null +++ b/src/rpcEmail.ts @@ -0,0 +1,41 @@ +class RPCEmailMessage implements ForwardableEmailMessage { + readonly from: string; + readonly to: string; + readonly rawEmail: String; + readonly raw: ReadableStream; + readonly headers: Headers; + readonly rawSize: number; + + constructor(from: string, to: string, rawEmail: string, headers: Headers) { + this.from = from; + this.to = to; + this.rawEmail = rawEmail; + this.raw = RPCEmailMessage.stringToStream(rawEmail); + this.rawSize = new TextEncoder().encode(rawEmail).length; + this.headers = headers; + } + + static stringToStream(str: string): ReadableStream { + return new ReadableStream({ + start(controller) { + const encoder = new TextEncoder(); + controller.enqueue(encoder.encode(str)); + controller.close(); + } + }); + } + + setReject(reason: string): void { + console.log(`rpcEmail default implementation: Message rejected: ${reason}`); + } + + async forward(rcptTo: string, headers: Headers = new Headers()): Promise { + console.log(`rpcEmail default implementation: Forwarding message to: ${rcptTo}, with headers:`, headers); + } + + async reply(message: EmailMessage): Promise { + console.log(`rpcEmail default implementation: Replying to: ${message}`); + } +} + +export { RPCEmailMessage }; \ No newline at end of file