Raybil-AI-Engine / server.js
r9rk9r's picture
Update server.js
b922d49 verified
Raw
History Blame Contribute Delete
3.59 kB
const express = require('express');
const cors = require('cors');
const admin = require('firebase-admin');
const app = express();
const PORT = process.env.PORT || 7860;
const allowedOrigins = [
'https://raybil.me',
'https://story.raybil.me'
];
const corsOptions = {
origin: function (origin, callback) {
if (!origin) return callback(null, true);
if (allowedOrigins.indexOf(origin) !== -1) {
callback(null, true);
} else {
callback(null, false);
}
},
methods: ['POST', 'GET', 'OPTIONS'],
credentials: true
};
app.use(cors(corsOptions));
app.use(express.json());
try {
const secretKeyString = process.env.FIREBASE_SERVICE_ACCOUNT;
if (!secretKeyString) {
throw new Error("FIREBASE_SERVICE_ACCOUNT secret is missing!");
}
const serviceAccount = JSON.parse(secretKeyString);
admin.initializeApp({
credential: admin.credential.cert(serviceAccount)
});
console.log("Firebase Admin SDK initialized successfully!");
} catch (error) {
console.error("Firebase Initialization Failed:", error.message);
process.exit(1);
}
const healthCheckHandler = (req, res) => {
res.status(200).send('ok');
};
app.all('/health', healthCheckHandler);
app.all('/check', healthCheckHandler);
const enforcePostOnly = (req, res, next) => {
if (req.method !== 'POST') {
return res.status(405).json({
success: false,
message: `Method ${req.method} Not Allowed. Only POST requests are accepted.`
});
}
next();
};
function getSafeTopicName(category) {
const mapping = {
"নবীদের কাহিনী": "nobider_kahini",
"সাহাবিদের জীবনী": "sahabider_jiboni",
"আল-কুরআন ও হাদিসের গল্প": "quran_hadis",
"পূর্বসূরি ও বুজুর্গদের কাহিনী": "scholars_stories",
"শিশুদের ইসলামিক গল্প": "kids_stories"
};
if (mapping[category]) {
return mapping[category];
}
return "general_stories";
}
app.post('/subscribe', enforcePostOnly, async (req, res) => {
const { fcm_token, selected_category, action } = req.body;
if (!fcm_token || !selected_category || action !== 'subscribe') {
return res.status(400).json({ success: false, message: "Invalid payload or wrong action." });
}
try {
const safeTopic = getSafeTopicName(selected_category);
await admin.messaging().subscribeToTopic(fcm_token, safeTopic);
res.status(200).json({
success: true,
message: `Successfully registered to ${selected_category} category.`
});
} catch (error) {
res.status(500).json({ success: false, error: error.message });
}
});
app.post('/unsubscribe', enforcePostOnly, async (req, res) => {
const { fcm_token, selected_category, action } = req.body;
if (!fcm_token || !selected_category || action !== 'unsubscribe') {
return res.status(400).json({ success: false, message: "Invalid payload or wrong action." });
}
try {
const safeTopic = getSafeTopicName(selected_category);
await admin.messaging().unsubscribeFromTopic(fcm_token, safeTopic);
res.status(200).json({
success: true,
message: `Successfully removed from ${selected_category} category.`
});
} catch (error) {
res.status(500).json({ success: false, error: error.message });
}
});
app.use((req, res) => {
res.status(404).json({ success: false, message: "Endpoint not found." });
});
app.listen(PORT, '0.0.0.0', () => {
console.log(`Server is running securely on port ${PORT}`);
});