feat: implement email sending functionality via Resend service

This commit is contained in:
beilunyang
2025-06-22 00:32:09 +08:00
parent 9d55564073
commit e85f6b04bd
27 changed files with 2347 additions and 467 deletions
+32 -9
View File
@@ -1,9 +1,11 @@
import { NextResponse } from "next/server"
import { createDb } from "@/lib/db"
import { emails, messages } from "@/lib/schema"
import { eq, and, lt, or, sql } from "drizzle-orm"
import { eq, and, lt, or, sql, ne } from "drizzle-orm"
import { encodeCursor, decodeCursor } from "@/lib/cursor"
import { getUserId } from "@/lib/apiKey"
import { checkBasicSendPermission } from "@/lib/send-permissions"
export const runtime = "edge"
export async function DELETE(
@@ -52,12 +54,22 @@ export async function GET(
) {
const { searchParams } = new URL(request.url)
const cursorStr = searchParams.get('cursor')
const messageType = searchParams.get('type')
try {
const db = createDb()
const { id } = await params
const userId = await getUserId()
if (messageType === 'sent') {
const permissionResult = await checkBasicSendPermission(userId!)
if (!permissionResult.canSend) {
return NextResponse.json(
{ error: permissionResult.error || "您没有查看发送邮件的权限" },
{ status: 403 }
)
}
}
const email = await db.query.emails.findFirst({
where: and(
@@ -73,7 +85,10 @@ export async function GET(
)
}
const baseConditions = eq(messages.emailId, id)
const baseConditions = and(
eq(messages.emailId, id),
messageType === 'sent' ? eq(messages.type, "sent") : ne(messages.type, "sent")
)
const totalResult = await db.select({ count: sql<number>`count(*)` })
.from(messages)
@@ -84,22 +99,24 @@ export async function GET(
if (cursorStr) {
const { timestamp, id } = decodeCursor(cursorStr)
const orderByTime = messageType === 'sent' ? messages.sentAt : messages.receivedAt
conditions.push(
// @ts-expect-error "ignore the error"
or(
lt(messages.receivedAt, new Date(timestamp)),
lt(orderByTime, new Date(timestamp)),
and(
eq(messages.receivedAt, new Date(timestamp)),
eq(orderByTime, new Date(timestamp)),
lt(messages.id, id)
)
)
)
}
const orderByTime = messageType === 'sent' ? messages.sentAt : messages.receivedAt
const results = await db.query.messages.findMany({
where: and(...conditions),
orderBy: (messages, { desc }) => [
desc(messages.receivedAt),
desc(orderByTime),
desc(messages.id)
],
limit: PAGE_SIZE + 1
@@ -108,7 +125,9 @@ export async function GET(
const hasMore = results.length > PAGE_SIZE
const nextCursor = hasMore
? encodeCursor(
results[PAGE_SIZE - 1].receivedAt.getTime(),
messageType === 'sent'
? results[PAGE_SIZE - 1].sentAt!.getTime()
: results[PAGE_SIZE - 1].receivedAt.getTime(),
results[PAGE_SIZE - 1].id
)
: null
@@ -117,9 +136,13 @@ export async function GET(
return NextResponse.json({
messages: messageList.map(msg => ({
id: msg.id,
from_address: msg.fromAddress,
from_address: msg?.fromAddress,
to_address: msg?.toAddress,
subject: msg.subject,
received_at: msg.receivedAt.getTime()
content: msg.content,
html: msg.html,
sent_at: msg.sentAt?.getTime(),
received_at: msg.receivedAt?.getTime()
})),
nextCursor,
total: totalCount