Spaces:
Paused
Paused
File size: 4,234 Bytes
a5e013f 4c03281 a5e013f ff2364a acd0769 4c03281 acd0769 a5e013f 0c01db2 acd0769 a5e013f acd0769 a5e013f acd0769 a5e013f acd0769 a5e013f acd0769 4c03281 acd0769 a5e013f acd0769 a5e013f acd0769 a5e013f 4c03281 acd0769 a5e013f acd0769 4c03281 acd0769 0c01db2 acd0769 a5e013f acd0769 a5e013f | 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 | const express = require('express');
const cors = require('cors');
const admin = require('firebase-admin');
const app = express();
const PORT = process.env.PORT || 7860;
app.use(cors());
app.use(express.json());
// ==========================================
// ০. ফায়ারবেস এডমিন এসডিকে (Hugging Face Secrets থেকে)
// ==========================================
try {
// Hugging Face Secrets থেকে স্ট্রিংটি নেওয়া হচ্ছে
const secretKeyString = process.env.FIREBASE_SERVICE_ACCOUNT;
if (!secretKeyString) {
throw new Error("FIREBASE_SERVICE_ACCOUNT secret is missing in Hugging Face Spaces settings!");
}
// স্ট্রিংটিকে JSON অবজেক্টে রূপান্তর করা
const serviceAccount = JSON.parse(secretKeyString);
admin.initializeApp({
credential: admin.credential.cert(serviceAccount)
});
console.log("Firebase Admin SDK initialized successfully using Hugging Face Secrets!");
} catch (error) {
console.error("Firebase Initialization Failed:", error.message);
process.exit(1); // সিক্রেট না থাকলে সার্ভার রান করবে না
}
// ==========================================
// ১. হেলথ চেক রাউট (/health এবং /check)
// ==========================================
const healthCheckHandler = (req, res) => {
res.status(200).send('ok');
};
app.all('/health', healthCheckHandler);
app.all('/check', healthCheckHandler);
// ==========================================
// ২. সিকিউরিটি মিডলওয়্যার (Middleware)
// ==========================================
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 on this endpoint.`
});
}
next();
};
// ==========================================
// ৩. মূল কার্যকারী রাউট (/subscribe এবং /unsubscribe)
// ==========================================
// --- সাবস্ক্রাইব সেকশন ---
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 for subscription." });
}
try {
await admin.messaging().subscribeToTopic(fcm_token, selected_category);
console.log(`Successfully subscribed token to topic: ${selected_category}`);
res.status(200).json({
success: true,
message: `Successfully registered to ${selected_category} category.`
});
} catch (error) {
console.error("Firebase subscription error:", 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 for unsubscription." });
}
try {
await admin.messaging().unsubscribeFromTopic(fcm_token, selected_category);
console.log(`Successfully unsubscribed token from topic: ${selected_category}`);
res.status(200).json({
success: true,
message: `Successfully removed from ${selected_category} category.`
});
} catch (error) {
console.error("Firebase unsubscription error:", 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 on port ${PORT}`);
});
|