- Homepage faithfully matching dejband.com (hero, services, consulting,
stats, about block, timeline, portfolio, articles) + About/Contact/
Portfolios/Articles pages under source URLs
- Meshkee API integration: live blog content, favicon, user menu,
sitemap/robots proxy, canonical /blog/{id}/{slug}
- SEO pass: one H1 per page, unique metadata + canonicals, alt text
- Contact form wired to /api/contact with toast + reset
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
76 lines
2.8 KiB
JavaScript
76 lines
2.8 KiB
JavaScript
import { DOMAIN, API_BASE } from "@/lib/api";
|
||
|
||
// Contact form endpoint.
|
||
// Validates the submission and — when an SMS key is configured — notifies the
|
||
// business through the Meshkee SMS gateway. Without a key it still accepts the
|
||
// message so the storefront keeps working; wire delivery by setting:
|
||
// MESHKEE_SMS_API_KEY server-to-server key for /public/sms/send
|
||
// MESHKEE_CONTACT_NOTIFY_TO phone number that should receive the alert
|
||
|
||
export const runtime = "nodejs";
|
||
|
||
const faDigits = (s) => String(s).replace(/[۰-۹]/g, (d) => "۰۱۲۳۴۵۶۷۸۹".indexOf(d));
|
||
|
||
function validate(body) {
|
||
const name = String(body?.name || "").trim();
|
||
const phone = faDigits(body?.phone || "").trim();
|
||
const email = String(body?.email || "").trim();
|
||
const message = String(body?.message || "").trim();
|
||
|
||
const errors = {};
|
||
if (name.length < 2) errors.name = "نام را وارد کنید";
|
||
if (!/^0?\d{10,11}$/.test(phone.replace(/[\s-]/g, "")))
|
||
errors.phone = "شماره تماس معتبر نیست";
|
||
if (email && !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email))
|
||
errors.email = "ایمیل معتبر نیست";
|
||
if (message.length < 5) errors.message = "متن پیام را وارد کنید";
|
||
|
||
return { data: { name, phone, email, message }, errors };
|
||
}
|
||
|
||
async function notifyBusiness({ name, phone, email, message }) {
|
||
const key = process.env.MESHKEE_SMS_API_KEY;
|
||
const to = process.env.MESHKEE_CONTACT_NOTIFY_TO;
|
||
if (!key || !to) return { delivered: false, reason: "not-configured" };
|
||
|
||
const text = `پیام جدید از فرم تماس دژبند\nنام: ${name}\nتماس: ${phone}${
|
||
email ? `\nایمیل: ${email}` : ""
|
||
}\nپیام: ${message}`.slice(0, 600);
|
||
|
||
try {
|
||
const res = await fetch(`${API_BASE}/public/sms/send`, {
|
||
method: "POST",
|
||
headers: { "Content-Type": "application/json", "X-Api-Key": key },
|
||
body: JSON.stringify({ domain: DOMAIN, to, message: text }),
|
||
});
|
||
return { delivered: res.ok, reason: res.ok ? "sent" : `sms-${res.status}` };
|
||
} catch {
|
||
return { delivered: false, reason: "sms-error" };
|
||
}
|
||
}
|
||
|
||
export async function POST(request) {
|
||
let body;
|
||
try {
|
||
body = await request.json();
|
||
} catch {
|
||
return Response.json({ ok: false, message: "درخواست نامعتبر است" }, { status: 400 });
|
||
}
|
||
|
||
const { data, errors } = validate(body);
|
||
if (Object.keys(errors).length) {
|
||
return Response.json(
|
||
{ ok: false, message: "لطفاً فیلدها را بررسی کنید", errors },
|
||
{ status: 422 }
|
||
);
|
||
}
|
||
|
||
const notify = await notifyBusiness(data);
|
||
|
||
return Response.json({
|
||
ok: true,
|
||
message: "پیام شما با موفقیت ثبت شد. بهزودی همکاران ما با شما تماس میگیرند.",
|
||
delivered: notify.delivered,
|
||
});
|
||
}
|