File size: 7,338 Bytes
f56741b
 
 
4ca25f0
 
0fe515c
f56741b
0fe515c
f56741b
4ca25f0
0fe515c
f56741b
 
32d4856
b21c9a4
 
 
bb8c78f
f56741b
8b3d448
bb8c78f
b483071
f56741b
 
 
b483071
f56741b
bb8c78f
 
 
 
 
 
 
 
1ad9ebc
 
bb8c78f
1ad9ebc
bb8c78f
1ad9ebc
f56741b
b483071
f56741b
1ad9ebc
 
 
 
 
 
 
 
 
 
 
 
bb8c78f
1ad9ebc
bb8c78f
 
 
 
 
 
f56741b
1ad9ebc
 
f56741b
 
1ad9ebc
 
f56741b
 
1ad9ebc
 
 
 
 
 
bb8c78f
f56741b
bb8c78f
f56741b
 
 
 
 
 
1ad9ebc
f56741b
 
8b3d448
f56741b
 
 
 
 
b483071
f56741b
 
 
1ad9ebc
 
 
 
 
f56741b
bb8c78f
f56741b
1ad9ebc
f56741b
b483071
f56741b
 
1ad9ebc
f56741b
1ad9ebc
b483071
f56741b
 
 
bb8c78f
b21c9a4
f56741b
bb8c78f
1ad9ebc
f56741b
4ca25f0
f56741b
 
1ad9ebc
f56741b
4ca25f0
f56741b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bb8c78f
 
4ca25f0
0fe515c
f56741b
 
1ad9ebc
f56741b
1ad9ebc
4ca25f0
f56741b
0fe515c
f56741b
 
 
0fe515c
f56741b
 
 
 
 
0fe515c
 
f56741b
 
 
 
 
 
0fe515c
1ad9ebc
 
 
 
 
0fe515c
 
 
f56741b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bb8c78f
f56741b
 
 
 
 
 
 
 
 
 
4ca25f0
 
f56741b
4ca25f0
 
 
 
 
 
 
f56741b
4ca25f0
 
 
 
 
 
0fe515c
f56741b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
const express = require('express');
const puppeteer = require('puppeteer-extra');
const StealthPlugin = require('puppeteer-extra-plugin-stealth');
puppeteer.use(StealthPlugin());

const app = express();
const PORT = process.env.PORT || 7860;

// Store browser instance to reuse
let browser = null;

// Middleware
app.use(express.json());

// Delay function to replace waitForTimeout
const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms));

// Initialize browser once on startup
async function initializeBrowser() {
  try {
    console.log('πŸš€ Initializing browser...');
    
    browser = await puppeteer.launch({
      headless: true, // Set to false for debugging
      args: ["--no-sandbox", "--disable-setuid-sandbox"]
    });

    console.log("βœ… Browser initialized successfully!");
    
  } catch (error) {
    console.error("❌ Failed to initialize browser:", error);
    throw error;
  }
}

// Login function for a given page
async function login(page) {
  try {
    console.log('πŸ” Checking login status...');
    
    await page.goto("https://getsms.cc/auth/login", {
      waitUntil: "networkidle2"
    });

    // Check if we're already logged in by looking for the #email field
    const isLoginPage = await page.evaluate(() => {
      return !!document.querySelector('#email');
    });

    if (!isLoginPage) {
      console.log('βœ… Already logged in, skipping login process.');
      return;
    }

    console.log('πŸ” Performing login...');

    // Clear any existing form data
    await page.evaluate(() => {
      const emailInput = document.querySelector('#email');
      const passwordInput = document.querySelector('#password');
      if (emailInput) emailInput.value = '';
      if (passwordInput) passwordInput.value = '';
    });

    // Replace with your actual credentials
    await page.type("#email", "reikernx@gmail.com", { delay: 50 });
    await page.type("#password", "Ogombo12", { delay: 50 });

    await Promise.all([
      page.click("input[type=submit]"),
      page.waitForNavigation({ waitUntil: "networkidle2" })
    ]);

    // Verify login success
    const finalUrl = page.url();
    if (finalUrl.includes('/auth/login')) {
      throw new Error('Login failed - still on login page');
    }

    console.log("βœ… Logged in successfully!");
  } catch (error) {
    console.error("❌ Failed to login:", error);
    throw error;
  }
}

// API endpoint to get messages for a phone number
app.get('/api/messages', async (req, res) => {
  let page = null;
  try {
    const { number } = req.query;
    
    if (!number) {
      return res.status(400).json({
        error: 'Phone number is required',
        message: 'Please provide a phone number in the query parameter: ?number=447414848795'
      });
    }

    console.log(`πŸ“± Fetching messages for number: ${number}`);

    // Create a new page for each request
    page = await browser.newPage();

    // Perform login or skip if already logged in
    await login(page);

    // Navigate to the specific info page
    const url = `https://getsms.cc/info/${number}`;
    await page.goto(url, {
      waitUntil: "networkidle2"
    });

    // Verify we didn't get redirected to login page
    const finalUrl = page.url();
    if (finalUrl.includes('/auth/login')) {
      throw new Error('Session invalid - redirected to login page');
    }

    console.log(`βœ… Successfully navigated to: ${finalUrl}`);

    // Wait for content to load
    await delay(2000);

    // Extract the latest 5 messages
    const lastMessages = await page.evaluate(() => {
      const messageElements = document.querySelectorAll('.direct-chat-msg');
      
      // Double-check we're not seeing login messages
      const bodyText = document.body.textContent || '';
      if (bodyText.includes('Login to view')) {
        return []; // Return empty array if still showing login message
      }
      
      const messages = Array.from(messageElements).map(msg => {
        const nameElement = msg.querySelector('.direct-chat-name');
        const timeElement = msg.querySelector('.direct-chat-timestamp');
        const textElement = msg.querySelector('.direct-chat-text');
        
        // Skip ads/empty messages
        const text = textElement?.textContent?.trim() || '';
        if (text.includes('adsbygoogle') || text === '' || text.includes('Login to view')) {
          return null;
        }
        
        return {
          sender: nameElement?.textContent?.trim() || 'Unknown',
          time: timeElement?.textContent?.trim() || 'Unknown time',
          message: text
        };
      }).filter(msg => msg !== null); // Remove null entries (ads)
      
      // Return latest 5 messages
      return messages.slice(0, 5);
    });

    // Check if we got empty results due to login requirement
    if (lastMessages.length === 0) {
      const pageContent = await page.evaluate(() => document.body.textContent);
      if (pageContent.includes('Login to view')) {
        throw new Error('Session invalid - still showing "Login to view"');
      }
    }

    console.log(`βœ… Found ${lastMessages.length} messages for ${number}`);

    // Return the response
    res.json({
      success: true,
      number: number,
      timestamp: new Date().toISOString(),
      messageCount: lastMessages.length,
      messages: lastMessages
    });

  } catch (error) {
    console.error(`❌ Error fetching messages for ${req.query.number}:`, error);
    res.status(500).json({
      success: false,
      error: 'Failed to fetch messages',
      message: error.message
    });
  } finally {
    // Close the page to avoid memory leaks
    if (page) {
      await page.close();
    }
  }
});

// Health check endpoint
app.get('/api/health', (req, res) => {
  res.json({
    status: 'OK',
    message: 'GetSMS API is running',
    timestamp: new Date().toISOString(),
    browserStatus: browser ? 'Connected' : 'Disconnected'
  });
});

// Get available endpoints
app.get('/', (req, res) => {
  res.json({
    message: 'GetSMS Message Extraction API',
    endpoints: {
      'GET /api/messages?number={phone_number}': 'Get latest 5 messages for a phone number',
      'GET /api/health': 'Check API health status',
      'GET /': 'This help page'
    },
    example: {
      url: '/api/messages?number=447414848795',
      description: 'Get messages for phone number 447414848795'
    }
  });
});

// Graceful shutdown
process.on('SIGINT', async () => {
  console.log('\nπŸ”„ Shutting down gracefully...');
  if (browser) {
    await browser.close();
  }
  process.exit(0);
});

process.on('SIGTERM', async () => {
  console.log('\nπŸ”„ Shutting down gracefully...');
  if (browser) {
    await browser.close();
  }
  process.exit(0);
});

// Start server
async function startServer() {
  try {
    await initializeBrowser();
    
    app.listen(PORT, () => {
      console.log(`\n🌟 GetSMS API Server running on port ${PORT}`);
      console.log(`πŸ“‹ Available endpoints:`);
      console.log(`   GET http://localhost:${PORT}/api/messages?number=447414848795`);
      console.log(`   GET http://localhost:${PORT}/api/health`);
      console.log(`   GET http://localhost:${PORT}/`);
    });
  } catch (error) {
    console.error('❌ Failed to start server:', error);
    process.exit(1);
  }
}

// Start the server
startServer();