ShieldX commited on
Commit
33564cc
Β·
verified Β·
1 Parent(s): 5fd9c76

Upload 5 files

Browse files
Files changed (5) hide show
  1. Dockerfile +12 -0
  2. package-lock.json +0 -0
  3. package.json +19 -0
  4. server.js +95 -0
  5. src/firebase.js +31 -0
Dockerfile ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM node:18
2
+
3
+ WORKDIR /app
4
+
5
+ COPY package*.json ./
6
+ RUN npm install
7
+
8
+ COPY . .
9
+
10
+ EXPOSE 7860
11
+
12
+ CMD ["node", "server.js"]
package-lock.json ADDED
The diff for this file is too large to render. See raw diff
 
package.json ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "houseofruqa",
3
+ "version": "1.0.0",
4
+ "description": "House of Ruqa is a wedding aesthetic and experience design studio for modern couples who want a celebration that feels royal, looks modern, and flows effortlessly. We transform love stories into visual identities β€” through themes, colors, digital assets, and unforgettable experiences.",
5
+ "main": "server.js",
6
+ "scripts": {
7
+ "test": "echo \"Error: no test specified\" && exit 1"
8
+ },
9
+ "author": "Rohan SHaw",
10
+ "license": "ISC",
11
+ "dependencies": {
12
+ "axios": "^1.13.2",
13
+ "cors": "^2.8.5",
14
+ "dotenv": "^17.2.3",
15
+ "express": "^5.2.1",
16
+ "firebase-admin": "^13.6.0",
17
+ "nodemailer": "^7.0.12"
18
+ }
19
+ }
server.js ADDED
@@ -0,0 +1,95 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ const express = require('express');
2
+ const cors = require('cors');
3
+ const { db } = require('./src/firebase');
4
+ const axios = require('axios'); // Import axios
5
+ require('dotenv').config();
6
+
7
+ const app = express();
8
+ const PORT = process.env.PORT || 7860;
9
+
10
+ app.use(cors());
11
+ app.use(express.json());
12
+
13
+ // --- HELPER: Telegram Notification ---
14
+ const sendTelegramAlert = async (data) => {
15
+ const token = process.env.TELEGRAM_BOT_TOKEN;
16
+ const chatId = process.env.TELEGRAM_CHAT_ID;
17
+
18
+ if (!token || !chatId) {
19
+ console.warn("⚠️ Telegram credentials missing in .env");
20
+ return;
21
+ }
22
+
23
+ // Format the message nicely
24
+ const message = `
25
+ πŸ”” *New Lead: House of Ruqa*
26
+
27
+ πŸ‘€ *Name:* ${data.name}
28
+ πŸ“§ *Email:* ${data.email}
29
+ πŸ“ž *Phone:* ${data.phone}
30
+ πŸ“¦ *Package:* ${data.packageType}
31
+
32
+ πŸ“ *Message:*
33
+ ${data.message}
34
+ `;
35
+
36
+ try {
37
+ const url = `https://api.telegram.org/bot${token}/sendMessage`;
38
+ await axios.post(url, {
39
+ chat_id: chatId,
40
+ text: message,
41
+ parse_mode: 'Markdown' // Allows bolding
42
+ });
43
+ console.log("✈️ Telegram Notification Sent");
44
+ } catch (error) {
45
+ console.error("❌ Telegram Error:", error.response ? error.response.data : error.message);
46
+ }
47
+ };
48
+
49
+ // --- ROUTES ---
50
+
51
+ app.get('/health', (req, res) => {
52
+ res.status(200).json({ status: 'Online', system: 'House of Ruqa Backend' });
53
+ });
54
+
55
+ app.post('/api/lead', async (req, res) => {
56
+ try {
57
+ const { name, email, phone, message, packageType } = req.body;
58
+
59
+ if (!name || !email) {
60
+ return res.status(400).json({ error: 'Name and Email are required.' });
61
+ }
62
+
63
+ const leadData = {
64
+ name,
65
+ email,
66
+ phone: phone || 'N/A',
67
+ message: message || '',
68
+ packageType: packageType || 'General Inquiry',
69
+ timestamp: new Date().toISOString(),
70
+ status: 'new',
71
+ source: 'website_form'
72
+ };
73
+
74
+ // 1. Save to Firebase
75
+ const docRef = await db.collection('leads').add(leadData);
76
+ console.log(`βœ… New Lead Saved: ${docRef.id}`);
77
+
78
+ // 2. Send Telegram Alert (Async - don't wait for it to respond to user)
79
+ sendTelegramAlert(leadData);
80
+
81
+ res.status(201).json({
82
+ success: true,
83
+ message: 'Request received.',
84
+ id: docRef.id
85
+ });
86
+
87
+ } catch (error) {
88
+ console.error("❌ Error processing lead:", error);
89
+ res.status(500).json({ success: false, error: 'Internal Server Error' });
90
+ }
91
+ });
92
+
93
+ app.listen(PORT, () => {
94
+ console.log(`πŸ‘‘ House of Ruqa Server running on port ${PORT}`);
95
+ });
src/firebase.js ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ const admin = require('firebase-admin');
2
+ const dotenv = require('dotenv');
3
+
4
+ dotenv.config();
5
+
6
+ // Logic: Check if we are in production (HuggingFace) or Local
7
+ // In production, we'll parse the JSON string from env vars.
8
+ // Locally, we look for the file.
9
+
10
+ let serviceAccount;
11
+
12
+ try {
13
+ if (process.env.FIREBASE_SERVICE_ACCOUNT) {
14
+ // Production: Use Env Variable
15
+ serviceAccount = JSON.parse(process.env.FIREBASE_SERVICE_ACCOUNT);
16
+ } else {
17
+ // Local: Use file
18
+ serviceAccount = require('../serviceAccountKey.json');
19
+ }
20
+
21
+ admin.initializeApp({
22
+ credential: admin.credential.cert(serviceAccount)
23
+ });
24
+
25
+ console.log("πŸ”₯ Firebase Admin Initialized Successfully");
26
+ } catch (error) {
27
+ console.error("❌ Firebase Admin Init Error:", error.message);
28
+ }
29
+
30
+ const db = admin.firestore();
31
+ module.exports = { db };