Files
webmailserver/app/api/webhooks/mail-signal/route.ts

115 lines
3.8 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { NextResponse } from 'next/server';
import { prisma } from '@/lib/prisma';
import { sendTelegramNotification } from '@/lib/notifications';
import { sendWA } from '@/lib/whatsapp';
// Bu kısım normalde .env içinde olmalı
const WEBHOOK_SECRET = process.env.WEBHOOK_SIGNAL_SECRET || 'besiktasK1903*';
// RFC 2047 Decode Fonksiyonu
function decodeMimeText(text: string) {
if (!text) return text;
// Eğer metin =? ile başlıyorsa decode etmeye çalış
return text.replace(/=\?([^?]+)\?([QB])\?([^?]+)\?=/gi, (match, charset, encoding, data) => {
try {
if (encoding.toUpperCase() === 'Q') {
// Quoted-Printable decode
return data
.replace(/_/g, ' ')
.replace(/=([0-9A-F]{2})/gi, (_: any, hex: string) => String.fromCharCode(parseInt(hex, 16)));
} else if (encoding.toUpperCase() === 'B') {
// Base64 decode
return Buffer.from(data, 'base64').toString(charset.toLowerCase() === 'utf-8' ? 'utf8' : 'binary');
}
} catch (e) {
return match;
}
return match;
});
}
export async function POST(request: Request) {
const secret = request.headers.get('x-ayristech-secret');
if (secret !== WEBHOOK_SECRET) {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
}
const body = await request.json();
const { to, event, subject: incomingSubject, snippet: incomingSnippet, from: incomingFrom } = body;
const subject = decodeMimeText(incomingSubject || "");
console.log(`📩 Webhook Sinyali Alındı! Alıcı: ${to} | Konu: ${subject}`);
try {
// 1. Mailbox Mapping kontrolü
const mapping = await prisma.mailboxMapping.findUnique({
where: { email: to },
include: { user: true }
});
if (!mapping) {
console.log(`[Signal] Mapping bulunamadı: ${to}`);
return NextResponse.json({ success: true, message: 'No mapping found' });
}
// 2. Mail İçeriğini Belirle
if (!incomingSubject && !incomingSnippet) {
console.log(`[Signal] İçerik eksik, işlem durduruldu: ${to}`);
return NextResponse.json({ success: true, message: 'No content provided' });
}
const mailData = {
subject: subject || "(Konu Yok)",
text: incomingSnippet || "",
from: incomingFrom || "Bilinmiyor"
};
// 3. Bildirim Gönder (Telegram)
let tgStatus = 'SKIPPED';
if (mapping.user.telegramEnabled && mapping.user.telegramId) {
const tgResult = await sendTelegramNotification(
mapping.userId,
to,
mailData.from,
mailData.subject,
""
);
tgStatus = tgResult.status;
}
// 4. Bildirim Gönder (WhatsApp)
let waStatus = 'SKIPPED';
if (mapping.user.whatsappEnabled && (mapping.user.whatsappNumber || process.env.DEFAULT_WHATSAPP_NUMBER)) {
const waNumber = mapping.user.whatsappNumber || process.env.DEFAULT_WHATSAPP_NUMBER;
const waMessage = `📩 *Yeni E-posta*\n\n*Gönderen:* ${mailData.from}\n*Konu:* ${mailData.subject}\n*Alıcı:* ${to}\n\n_AyrisMail Central_`;
const waResult = await sendWA(waNumber, waMessage, mapping.userId);
waStatus = waResult.success ? 'SENT' : 'FAILED';
}
// 5. Bildirim Logu
await prisma.notificationLog.create({
data: {
mailbox: to,
sender: mailData.from,
subject: mailData.subject,
status: tgStatus === 'SENT' || waStatus === 'SENT' ? 'SENT' : 'FAILED',
userId: mapping.userId,
error: tgStatus === 'FAILED' ? 'TG Failed' : (waStatus === 'FAILED' ? 'WA Failed' : null)
}
});
return NextResponse.json({
success: true,
notification: notificationResult.status,
subject: mailData.subject
});
} catch (error: any) {
console.error("[Signal Webhook] Hata:", error.message);
return NextResponse.json({ error: error.message }, { status: 500 });
}
}