-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathindex.js
More file actions
165 lines (140 loc) · 4.25 KB
/
index.js
File metadata and controls
165 lines (140 loc) · 4.25 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
const path = require("path");
const express = require("express");
const hbs = require("hbs");
const helmet = require("helmet");
const rateLimit = require("express-rate-limit");
const compression = require("compression");
const morgan = require("morgan");
const { body, validationResult } = require("express-validator");
const admin = require("firebase-admin");
const { Telegraf } = require("telegraf");
const dotenv = require("dotenv");
dotenv.config();
const app = express();
const port = process.env.PORT || 3000;
// Enhanced security
app.use(helmet());
// Rate limiting
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 100 // limit each IP to 100 requests per windowMs
});
app.use(limiter);
// Compression
app.use(compression());
// Logging
app.use(morgan("combined"));
const staticPath = path.join(__dirname, "./public");
const templatePath = path.join(__dirname, "./templates/views");
app.use(express.static(staticPath));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.set("view engine", "hbs");
app.set("views", templatePath);
// CORS middleware
app.use((req, res, next) => {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
// Firebase initialization
const serviceAccount = require("./software.json");
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: process.env.FIREBASE_DATABASE_URL,
});
// Telegraf bot initialization
const bot = new Telegraf(process.env.TELEGRAM_BOT_TOKEN);
// Routes
app.get("/", (req, res) => {
res.send("Welcome to the advanced server!");
});
app.get("/form", (req, res) => {
res.render("form");
});
app.post("/form", [
body("id").notEmpty().trim(),
body("name").notEmpty().trim(),
body("email").isEmail().normalizeEmail(),
body("mobile").isMobilePhone(),
body("checkbox1").isBoolean(),
], async (req, res) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() });
}
try {
await insertUserData(req.body);
await notifyAdminViaBot(req.body);
res.status(201).json({ message: "User data successfully inserted" });
} catch (error) {
console.error("Error processing form:", error);
res.status(500).json({ message: "An error occurred while processing your request" });
}
});
// Helper functions
async function insertUserData(userData) {
try {
const writeResult = await admin
.firestore()
.collection("userdata")
.doc(userData.id)
.set(userData);
console.log("Document successfully written!", writeResult);
return writeResult;
} catch (error) {
console.error("Error writing document: ", error);
throw error;
}
}
async function notifyAdminViaBot(userData) {
const adminChatId = process.env.ADMIN_CHAT_ID;
const message = `
New user registered:
ID: ${userData.id}
Name: ${userData.name}
Email: ${userData.email}
Mobile: ${userData.mobile}
Checkbox1: ${userData.checkbox1}
`;
try {
await bot.telegram.sendMessage(adminChatId, message);
console.log("Admin notified via Telegram");
} catch (error) {
console.error("Error sending Telegram message:", error);
}
}
// Telegram bot commands
bot.command("stats", async (ctx) => {
try {
const snapshot = await admin.firestore().collection("userdata").get();
const userCount = snapshot.size;
ctx.reply(`Total registered users: ${userCount}`);
} catch (error) {
console.error("Error fetching stats:", error);
ctx.reply("An error occurred while fetching stats.");
}
});
// Error handling middleware
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).send("Something broke!");
});
// Start the server
const server = app.listen(port, () => {
console.log(`Server is running on port ${port}`);
});
// Graceful shutdown
process.on("SIGTERM", () => {
console.log("SIGTERM signal received: closing HTTP server");
server.close(() => {
console.log("HTTP server closed");
bot.stop("SIGTERM");
});
});
// Launch the Telegram bot
bot.launch();
// Enable graceful stop for the bot
process.once("SIGINT", () => bot.stop("SIGINT"));
process.once("SIGTERM", () => bot.stop("SIGTERM"));
module.exports = app;