feat: profile page & webhook notification

This commit is contained in:
beilunyang
2024-12-17 13:26:34 +08:00
parent e0bd04818e
commit c69947ceae
20 changed files with 1533 additions and 288 deletions

View File

@@ -66,4 +66,19 @@ export const messages = sqliteTable("message", {
receivedAt: integer("received_at", { mode: "timestamp_ms" })
.notNull()
.$defaultFn(() => new Date()),
})
export const webhooks = sqliteTable('webhook', {
id: text('id').primaryKey().$defaultFn(() => crypto.randomUUID()),
userId: text('user_id')
.notNull()
.references(() => users.id, { onDelete: "cascade" }),
url: text('url').notNull(),
enabled: integer('enabled', { mode: 'boolean' }).notNull().default(true),
createdAt: integer('created_at', { mode: 'timestamp_ms' })
.notNull()
.$defaultFn(() => new Date()),
updatedAt: integer('updated_at', { mode: 'timestamp_ms' })
.notNull()
.$defaultFn(() => new Date()),
})

54
app/lib/webhook.ts Normal file
View File

@@ -0,0 +1,54 @@
import { WEBHOOK_CONFIG } from "@/config"
export interface EmailMessage {
emailId: string
messageId: string
fromAddress: string
subject: string
content: string
html: string
receivedAt: string
toAddress: string
}
export interface WebhookPayload {
event: typeof WEBHOOK_CONFIG.EVENTS[keyof typeof WEBHOOK_CONFIG.EVENTS]
data: EmailMessage
}
export async function callWebhook(url: string, payload: WebhookPayload) {
let lastError: Error | null = null
for (let i = 0; i < WEBHOOK_CONFIG.MAX_RETRIES; i++) {
try {
const controller = new AbortController()
const timeoutId = setTimeout(() => controller.abort(), WEBHOOK_CONFIG.TIMEOUT)
const response = await fetch(url, {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-Webhook-Event": payload.event,
},
body: JSON.stringify(payload.data),
signal: controller.signal,
})
clearTimeout(timeoutId)
if (response.ok) {
return true
}
lastError = new Error(`HTTP error! status: ${response.status}`)
} catch (error) {
lastError = error as Error
if (i < WEBHOOK_CONFIG.MAX_RETRIES - 1) {
await new Promise(resolve => setTimeout(resolve, WEBHOOK_CONFIG.RETRY_DELAY))
}
}
}
throw lastError
}