first commit
This commit is contained in:
@@ -0,0 +1,98 @@
|
||||
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 }
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user