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}`);
});