add email catcher

This commit is contained in:
oiov
2025-03-29 21:10:03 +08:00
parent d4745e1234
commit 6a9769f4c8
7 changed files with 114 additions and 3 deletions
+11 -2
View File
@@ -1,7 +1,16 @@
import { createEmail, OriginalEmail } from "@/lib/dto/email";
export async function POST(req: Request) {
try {
const data = await req.json();
return Response.json({ data, msg: "success" });
const data = (await req.json()) as OriginalEmail;
console.log("Received email:", data);
if (!data) {
return Response.json("No email data received", { status: 400 });
}
const res = await createEmail(data);
console.log("[存储]", res);
return Response.json({ msg: "success" });
} catch (error) {
return Response.json({ statusText: "Server error" }, { status: 500 });
}
+2
View File
@@ -28,6 +28,7 @@ export const env = createEnv({
NEXT_PUBLIC_FREE_URL_QUOTA: z.string().min(1).default("100"),
NEXT_PUBLIC_OPEN_SIGNUP: z.string().min(1).default("1"),
NEXT_PUBLIC_SHORT_DOMAINS: z.string().min(1).default(""),
NEXT_PUBLIC_EMAIL_R2_DOMAIN: z.string().min(1),
},
runtimeEnv: {
NEXTAUTH_URL: process.env.NEXTAUTH_URL,
@@ -43,6 +44,7 @@ export const env = createEnv({
NEXT_PUBLIC_FREE_URL_QUOTA: process.env.NEXT_PUBLIC_FREE_URL_QUOTA,
NEXT_PUBLIC_OPEN_SIGNUP: process.env.NEXT_PUBLIC_OPEN_SIGNUP,
NEXT_PUBLIC_SHORT_DOMAINS: process.env.NEXT_PUBLIC_SHORT_DOMAINS,
NEXT_PUBLIC_EMAIL_R2_DOMAIN: process.env.NEXT_PUBLIC_EMAIL_R2_DOMAIN,
CLOUDFLARE_ZONE_ID: process.env.CLOUDFLARE_ZONE_ID,
CLOUDFLARE_ZONE_NAME: process.env.CLOUDFLARE_ZONE_NAME,
CLOUDFLARE_API_KEY: process.env.CLOUDFLARE_API_KEY,
+55
View File
@@ -0,0 +1,55 @@
import { ForwardEmail } from "@prisma/client";
import { prisma } from "@/lib/db";
export type EmailAddress = {
name: string;
address?: string;
group?: EmailAddress[];
};
export type EmailHeader = Record<string, string>;
export interface OriginalEmail {
from: string;
fromName: string;
to: string;
cc?: string;
subject?: string;
text?: string;
html?: string;
date?: string;
messageId?: string;
replyTo?: string;
headers?: string;
attachments?: {
filename: string;
mimeType: string;
r2Path: string;
size: number;
}[];
}
export async function createEmail(emailData: OriginalEmail) {
const res = await prisma.forwardEmail.create({
data: {
from: emailData.from,
fromName: emailData.fromName,
to: emailData.to,
subject: emailData.subject,
text: emailData.text,
html: emailData.html,
date: emailData.date,
messageId: emailData.messageId,
replyTo: emailData.replyTo,
cc: emailData.cc,
headers: emailData.headers,
attachments: JSON.stringify(emailData.attachments), // 转换为 JSON 字符串
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString(),
},
});
if (!res) {
return null;
}
return res.id;
}
+4
View File
@@ -20,6 +20,10 @@ const nextConfig = {
protocol: "https",
hostname: "randomuser.me",
},
{
protocol: "https",
hostname: "email-attachment.wr.do",
},
],
},
experimental: {
@@ -214,3 +214,24 @@ CREATE UNIQUE INDEX "scrape_metas_type_ip_link_key" ON "scrape_metas" ("type", "
-- AddForeignKey
ALTER TABLE "scrape_metas" ADD CONSTRAINT "scrape_metas_userId_fkey" FOREIGN KEY ("userId") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE;
CREATE TABLE "forward_emails"
(
"id" TEXT NOT NULL,
"from" TEXT NOT NULL,
"fromName" TEXT NOT NULL,
"to" TEXT NOT NULL,
"subject" TEXT DEFAULT 'No Subject',
"text" TEXT DEFAULT '',
"html" TEXT DEFAULT '',
"date" TEXT DEFAULT '',
"messageId" TEXT DEFAULT '',
"replyTo" TEXT DEFAULT '',
"cc" TEXT DEFAULT '[]',
"headers" TEXT DEFAULT '[]',
"attachments" TEXT DEFAULT '[]',
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "forward_emails_pkey" PRIMARY KEY ("id")
);
+20
View File
@@ -179,3 +179,23 @@ model ScrapeMeta {
@@index([userId, type, apiKey])
@@map(name: "scrape_metas")
}
model ForwardEmail {
id String @id @default(uuid()) // 使用 UUID 作为主键
from String
fromName String
to String
subject String? @default("No Subject")
text String? @default("")
html String? @default("")
date String? @default("")
messageId String? @default("")
replyTo String? @default("")
cc String? @default("[]")
headers String? @default("[]")
attachments String? @default("[]")
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
+1 -1
View File
File diff suppressed because one or more lines are too long