99 lines
3.0 KiB
TypeScript
99 lines
3.0 KiB
TypeScript
import { NextRequest, NextResponse } from "next/server";
|
||
|
||
export const runtime = "nodejs";
|
||
|
||
const MAX_LENGTHS = {
|
||
name: 100,
|
||
contact: 150,
|
||
message: 2000,
|
||
};
|
||
|
||
// Убираем HTML-теги и обрезаем длину, чтобы нельзя было сломать
|
||
// форматирование сообщения в Telegram или протащить лишний код.
|
||
function sanitize(value: unknown, maxLength: number): string {
|
||
if (typeof value !== "string") return "";
|
||
return value.replace(/<[^>]*>/g, "").trim().slice(0, maxLength);
|
||
}
|
||
|
||
// Экранируем спецсимволы Telegram MarkdownV2.
|
||
function escapeMarkdown(text: string): string {
|
||
return text.replace(/[_*[\]()~`>#+\-=|{}.!\\]/g, (m) => `\\${m}`);
|
||
}
|
||
|
||
export async function POST(req: NextRequest) {
|
||
const token = process.env.TELEGRAM_BOT_TOKEN;
|
||
const chatId = process.env.TELEGRAM_CHAT_ID;
|
||
|
||
if (!token || !chatId) {
|
||
console.error("TELEGRAM_BOT_TOKEN или TELEGRAM_CHAT_ID не заданы");
|
||
return NextResponse.json(
|
||
{ ok: false, error: "Сервис временно недоступен, попробуйте позже" },
|
||
{ status: 500 }
|
||
);
|
||
}
|
||
|
||
let body: unknown;
|
||
try {
|
||
body = await req.json();
|
||
} catch {
|
||
return NextResponse.json(
|
||
{ ok: false, error: "Некорректный запрос" },
|
||
{ status: 400 }
|
||
);
|
||
}
|
||
|
||
const { name, contact, message } = (body ?? {}) as Record<string, unknown>;
|
||
|
||
const cleanName = sanitize(name, MAX_LENGTHS.name);
|
||
const cleanContact = sanitize(contact, MAX_LENGTHS.contact);
|
||
const cleanMessage = sanitize(message, MAX_LENGTHS.message);
|
||
|
||
if (!cleanName || !cleanContact || !cleanMessage) {
|
||
return NextResponse.json(
|
||
{ ok: false, error: "Заполните имя, контакт и сообщение" },
|
||
{ status: 400 }
|
||
);
|
||
}
|
||
|
||
const text = [
|
||
"*Новая заявка с сайта LabNetHub*",
|
||
"",
|
||
`*Имя:* ${escapeMarkdown(cleanName)}`,
|
||
`*Контакт:* ${escapeMarkdown(cleanContact)}`,
|
||
`*Сообщение:*`,
|
||
escapeMarkdown(cleanMessage),
|
||
].join("\n");
|
||
|
||
try {
|
||
const telegramRes = await fetch(
|
||
`https://api.telegram.org/bot${token}/sendMessage`,
|
||
{
|
||
method: "POST",
|
||
headers: { "Content-Type": "application/json" },
|
||
body: JSON.stringify({
|
||
chat_id: chatId,
|
||
text,
|
||
parse_mode: "MarkdownV2",
|
||
}),
|
||
}
|
||
);
|
||
|
||
if (!telegramRes.ok) {
|
||
const details = await telegramRes.text();
|
||
console.error("Telegram API error:", details);
|
||
return NextResponse.json(
|
||
{ ok: false, error: "Не удалось отправить сообщение" },
|
||
{ status: 502 }
|
||
);
|
||
}
|
||
|
||
return NextResponse.json({ ok: true });
|
||
} catch (err) {
|
||
console.error("Ошибка отправки в Telegram:", err);
|
||
return NextResponse.json(
|
||
{ ok: false, error: "Не удалось отправить сообщение" },
|
||
{ status: 500 }
|
||
);
|
||
}
|
||
}
|