From 0ba873048760b35f724bf6c32517d5f3baa4488a Mon Sep 17 00:00:00 2001 From: justin Date: Sat, 30 May 2026 16:35:11 -0500 Subject: [PATCH] Add Telegram notifications for tickets, quotes, and insurance leads MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Tickets: 📩 for support, 🏥 for insurance leads, 💰 for quotes Quotes: 💰 with name, email, company, service, details All fire-and-forget to Telegram bot — non-blocking. Previously these only went to ERPNext with no real-time alert. Co-Authored-By: Claude Opus 4.6 (1M context) --- api/src/routes/quotes.ts | 21 +++++++++++++++++++++ api/src/routes/tickets.ts | 21 +++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/api/src/routes/quotes.ts b/api/src/routes/quotes.ts index 8cc4724..4675b83 100644 --- a/api/src/routes/quotes.ts +++ b/api/src/routes/quotes.ts @@ -64,6 +64,27 @@ router.post("/api/v1/quotes", submitLimiter, async (req, res) => { console.error("[quotes] ERPNext Opportunity creation failed (non-fatal):", erpErr); } + // Telegram notification for quote requests + try { + const botToken = process.env.TELEGRAM_BOT_TOKEN; + const chatId = process.env.TELEGRAM_CHAT_ID; + if (botToken && chatId) { + const msg = `💰 NEW QUOTE REQUEST\n\n` + + `Name: ${name.trim()}\n` + + `Email: ${email}\n` + + (company ? `Company: ${company}\n` : "") + + (phone ? `Phone: ${phone}\n` : "") + + `Service: ${service_slug}\n` + + (details ? `Details: ${details.substring(0, 300)}\n` : "") + + `Quote: #${quoteId}`; + fetch(`https://api.telegram.org/bot${botToken}/sendMessage`, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ chat_id: chatId, text: msg }), + }).catch(() => {}); + } + } catch {} + res.status(201).json({ success: true, message: "Quote request received. We'll send your quote within one business day.", diff --git a/api/src/routes/tickets.ts b/api/src/routes/tickets.ts index 92db5f5..aceb1b6 100644 --- a/api/src/routes/tickets.ts +++ b/api/src/routes/tickets.ts @@ -86,6 +86,27 @@ router.post("/api/v1/tickets", submitLimiter, async (req, res) => { console.error("[tickets] ERPNext createIssue failed (non-fatal):", erpErr); } + // Telegram notification for tickets/leads + try { + const botToken = process.env.TELEGRAM_BOT_TOKEN; + const chatId = process.env.TELEGRAM_CHAT_ID; + if (botToken && chatId) { + const emoji = category === "insurance_lead" ? "🏥" : category === "quote" ? "💰" : "📩"; + const msg = `${emoji} NEW ${category.toUpperCase().replace("_", " ")}\n\n` + + `Subject: ${subject.trim()}\n` + + (name ? `Name: ${name}\n` : "") + + (email ? `Email: ${email}\n` : "") + + `Message: ${message.trim().substring(0, 300)}\n` + + (page ? `Page: ${page}\n` : "") + + `Ticket: #${ticketId}`; + fetch(`https://api.telegram.org/bot${botToken}/sendMessage`, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ chat_id: chatId, text: msg }), + }).catch(() => {}); + } + } catch {} + res.status(201).json({ success: true, message: "Request received. We'll get back to you within one business day.",