okay
This commit is contained in:
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
node_modules/
|
||||||
|
*.sqlite
|
||||||
37
db.js
Normal file
37
db.js
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
const sqlite3 = require('sqlite3').verbose();
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
const dbPath = path.resolve(__dirname, 'database.sqlite');
|
||||||
|
const db = new sqlite3.Database(dbPath, (err) => {
|
||||||
|
if (err) {
|
||||||
|
console.error('Error opening database', err.message);
|
||||||
|
} else {
|
||||||
|
console.log('Connected to the SQLite database.');
|
||||||
|
|
||||||
|
// Create devices table
|
||||||
|
db.run(`CREATE TABLE IF NOT EXISTS devices (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
login TEXT UNIQUE NOT NULL,
|
||||||
|
password TEXT NOT NULL
|
||||||
|
)`, (err) => {
|
||||||
|
if (err) {
|
||||||
|
console.error('Error creating devices table', err);
|
||||||
|
} else {
|
||||||
|
// Insert a default device for testing if it doesn't exist
|
||||||
|
db.run(`INSERT OR IGNORE INTO devices (login, password) VALUES ('admin', 'admin123')`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Create sms_queue table
|
||||||
|
db.run(`CREATE TABLE IF NOT EXISTS sms_queue (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
phone TEXT NOT NULL,
|
||||||
|
message TEXT NOT NULL,
|
||||||
|
status TEXT DEFAULT 'pending', -- pending, processing, sent, failed
|
||||||
|
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
||||||
|
)`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = db;
|
||||||
1752
package-lock.json
generated
Normal file
1752
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
17
package.json
Normal file
17
package.json
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"name": "otp",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"keywords": [],
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"express": "^4.18.2",
|
||||||
|
"socket.io": "^4.7.4",
|
||||||
|
"sqlite3": "^6.0.1"
|
||||||
|
}
|
||||||
|
}
|
||||||
51
queueWorker.js
Normal file
51
queueWorker.js
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
const db = require('./db');
|
||||||
|
|
||||||
|
function startQueueWorker(io) {
|
||||||
|
console.log('Starting SMS Queue Worker...');
|
||||||
|
|
||||||
|
setInterval(() => {
|
||||||
|
// Check if there are any connected devices (we'll broadcast to the 'devices' room)
|
||||||
|
// For simplicity, we just fetch one pending message and emit it.
|
||||||
|
// If the app is connected, it will process it.
|
||||||
|
|
||||||
|
db.get(`SELECT * FROM sms_queue WHERE status = 'pending' ORDER BY created_at ASC LIMIT 1`, (err, row) => {
|
||||||
|
if (err) {
|
||||||
|
console.error('Queue Worker Error:', err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (row) {
|
||||||
|
console.log(`Processing SMS ID: ${row.id} for ${row.phone}`);
|
||||||
|
|
||||||
|
// Mark as processing
|
||||||
|
db.run(`UPDATE sms_queue SET status = 'processing', updated_at = CURRENT_TIMESTAMP WHERE id = ?`, [row.id], (updateErr) => {
|
||||||
|
if (updateErr) {
|
||||||
|
console.error('Error updating status to processing:', updateErr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Emit to authenticated devices
|
||||||
|
io.to('devices').emit('send_sms', {
|
||||||
|
id: row.id,
|
||||||
|
phone: row.phone,
|
||||||
|
message: row.message
|
||||||
|
});
|
||||||
|
|
||||||
|
// Note: If no device is connected, it stays in 'processing' state.
|
||||||
|
// A robust system would have a timeout to revert 'processing' back to 'pending'.
|
||||||
|
// We will add a simple timeout mechanism.
|
||||||
|
setTimeout(() => {
|
||||||
|
db.get(`SELECT status FROM sms_queue WHERE id = ?`, [row.id], (checkErr, checkRow) => {
|
||||||
|
if (checkRow && checkRow.status === 'processing') {
|
||||||
|
console.log(`SMS ID: ${row.id} timed out. Reverting to pending.`);
|
||||||
|
db.run(`UPDATE sms_queue SET status = 'pending' WHERE id = ?`, [row.id]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, 30000); // 30 seconds timeout
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, 5000); // Check every 5 seconds
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = startQueueWorker;
|
||||||
35
readme.md
Normal file
35
readme.md
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
📨 REST API
|
||||||
|
|
||||||
|
Endpoint:
|
||||||
|
|
||||||
|
# code derek bashga messageler hem ugradyp bilersiniz
|
||||||
|
|
||||||
|
POST /api/data
|
||||||
|
Body (JSON görnüşinde):
|
||||||
|
|
||||||
|
{
|
||||||
|
"phone": "63435005",
|
||||||
|
"code": "1234"
|
||||||
|
}
|
||||||
|
Jogap (Response):
|
||||||
|
|
||||||
|
{
|
||||||
|
"message": "Data received and processed successfully.",
|
||||||
|
"received": {
|
||||||
|
"phone": "63435005",
|
||||||
|
"code": "1234"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
📡 Socket.IO Ulanylyşy
|
||||||
|
|
||||||
|
Baglanyşyk döretmek:
|
||||||
|
|
||||||
|
const socket = io("http://localhost:3000");
|
||||||
|
Ibermek:
|
||||||
|
|
||||||
|
socket.emit("sendSignInData", { phone: "63435005", code: "1234" });
|
||||||
|
Almak:
|
||||||
|
|
||||||
|
socket.on("sendSmsCode", (data) => {
|
||||||
|
console.log(data);
|
||||||
|
});
|
||||||
49
routes/api.js
Normal file
49
routes/api.js
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
const express = require('express');
|
||||||
|
const db = require('../db');
|
||||||
|
|
||||||
|
module.exports = function (io) {
|
||||||
|
const router = express.Router();
|
||||||
|
|
||||||
|
// Existing endpoint (kept for compatibility if needed, or can be removed later)
|
||||||
|
router.post('/data', (req, res) => {
|
||||||
|
const { phone, code } = req.body;
|
||||||
|
|
||||||
|
if (!phone || !code) {
|
||||||
|
return res.status(400).json({ error: 'Phone and Code are required.' });
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('Received data at /api/data:', { phone, code });
|
||||||
|
|
||||||
|
io.emit('sendSignInData', { phone, code });
|
||||||
|
|
||||||
|
return res.status(200).json({
|
||||||
|
message: 'Data received and processed successfully.',
|
||||||
|
received: { phone, code }
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// New endpoint to queue SMS
|
||||||
|
router.post('/sms', (req, res) => {
|
||||||
|
const { phone, message } = req.body;
|
||||||
|
|
||||||
|
if (!phone || !message) {
|
||||||
|
return res.status(400).json({ error: 'Phone and message are required.' });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Insert into queue
|
||||||
|
db.run(`INSERT INTO sms_queue (phone, message) VALUES (?, ?)`, [phone, message], function(err) {
|
||||||
|
if (err) {
|
||||||
|
console.error('Error inserting into sms_queue:', err);
|
||||||
|
return res.status(500).json({ error: 'Failed to queue SMS.' });
|
||||||
|
}
|
||||||
|
|
||||||
|
return res.status(202).json({
|
||||||
|
message: 'SMS queued successfully.',
|
||||||
|
id: this.lastID
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return router;
|
||||||
|
};
|
||||||
|
|
||||||
32
server.js
Normal file
32
server.js
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
const express = require('express');
|
||||||
|
const http = require('http');
|
||||||
|
const socketIo = require('socket.io');
|
||||||
|
const bodyParser = require('body-parser');
|
||||||
|
const cors = require('cors');
|
||||||
|
const apiRoutes = require('./routes/api');
|
||||||
|
const socketHandler = require('./socket');
|
||||||
|
const startQueueWorker = require('./queueWorker');
|
||||||
|
require('./db'); // Initialize DB
|
||||||
|
|
||||||
|
const app = express();
|
||||||
|
const server = http.createServer(app);
|
||||||
|
const io = socketIo(server, {
|
||||||
|
cors: {
|
||||||
|
origin: '*',
|
||||||
|
methods: ['GET', 'POST']
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
app.use(cors());
|
||||||
|
app.use(bodyParser.json());
|
||||||
|
|
||||||
|
app.use('/api', apiRoutes(io));
|
||||||
|
|
||||||
|
socketHandler(io);
|
||||||
|
startQueueWorker(io);
|
||||||
|
|
||||||
|
const PORT = process.env.PORT || 3000;
|
||||||
|
server.listen(PORT, '0.0.0.0',() => {
|
||||||
|
console.log(`Server is running on http://0.0.0.0:${PORT}`);
|
||||||
|
});
|
||||||
|
|
||||||
74
socket.js
Normal file
74
socket.js
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
const db = require('./db');
|
||||||
|
|
||||||
|
module.exports = function (io) {
|
||||||
|
// Middleware for authentication
|
||||||
|
io.use((socket, next) => {
|
||||||
|
const login = socket.handshake.auth.login;
|
||||||
|
const password = socket.handshake.auth.password;
|
||||||
|
|
||||||
|
if (!login || !password) {
|
||||||
|
// Allow normal web clients to connect without auth if needed,
|
||||||
|
// but we won't put them in the 'devices' room.
|
||||||
|
return next();
|
||||||
|
}
|
||||||
|
|
||||||
|
db.get(`SELECT * FROM devices WHERE login = ? AND password = ?`, [login, password], (err, row) => {
|
||||||
|
if (err) {
|
||||||
|
return next(new Error('Database error'));
|
||||||
|
}
|
||||||
|
if (!row) {
|
||||||
|
return next(new Error('Authentication error'));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Attach device info to socket
|
||||||
|
socket.device = row;
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
io.on('connection', (socket) => {
|
||||||
|
console.log('A user connected:', socket.id);
|
||||||
|
|
||||||
|
if (socket.device) {
|
||||||
|
console.log(`Device authenticated: ${socket.device.login}`);
|
||||||
|
socket.join('devices');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle SMS status updates from the app
|
||||||
|
socket.on('sms_status', (data) => {
|
||||||
|
console.log('Received sms_status:', data);
|
||||||
|
const { id, status } = data; // status should be 'sent' or 'failed'
|
||||||
|
|
||||||
|
if (id && status) {
|
||||||
|
db.run(`UPDATE sms_queue SET status = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?`, [status, id], (err) => {
|
||||||
|
if (err) {
|
||||||
|
console.error('Error updating SMS status:', err);
|
||||||
|
} else {
|
||||||
|
console.log(`Updated SMS ID ${id} to status: ${status}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Existing events
|
||||||
|
socket.on('sendSignInData', (data) => {
|
||||||
|
console.log('sendSignInData:', data);
|
||||||
|
io.emit('sendSmsCode', { phone: data.phone, code: data.code });
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.on('sendDatas', (data) => {
|
||||||
|
console.log('sendDatas:', data);
|
||||||
|
io.emit('sendData', { phone: data.phone, code: data.code });
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.on('disconnect', () => {
|
||||||
|
console.log('User disconnected:', socket.id);
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.on('error', (err) => {
|
||||||
|
console.error('Socket error:', err);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user