Merge branch 'main' of https://github.com/Xargana/blahaj-srv
This commit is contained in:
commit
e05db3ba4d
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -137,3 +137,6 @@ dist
|
||||||
|
|
||||||
# pm2 ecosystem file
|
# pm2 ecosystem file
|
||||||
ecosystem.config.js
|
ecosystem.config.js
|
||||||
|
|
||||||
|
# firebase service file
|
||||||
|
firebase-service-account.json
|
||||||
|
|
|
@ -3,6 +3,19 @@ const ping = require("ping");
|
||||||
const pm2 = require("pm2");
|
const pm2 = require("pm2");
|
||||||
const fs = require("fs");
|
const fs = require("fs");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
|
const axios = require("axios");
|
||||||
|
const admin = require("firebase-admin");
|
||||||
|
|
||||||
|
// Initialize Firebase Admin SDK
|
||||||
|
try {
|
||||||
|
const serviceAccount = require("../../firebase-service-account.json");
|
||||||
|
admin.initializeApp({
|
||||||
|
credential: admin.credential.cert(serviceAccount)
|
||||||
|
});
|
||||||
|
console.log("Firebase Admin SDK initialized successfully");
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error initializing Firebase Admin SDK:", error);
|
||||||
|
}
|
||||||
|
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
|
|
||||||
|
@ -30,6 +43,10 @@ function ensureLogDirectories() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Track previous states for notifications
|
||||||
|
let previousServersStatus = {};
|
||||||
|
let previousPM2Status = {};
|
||||||
|
|
||||||
let serversStatus = {};
|
let serversStatus = {};
|
||||||
REMOTE_SERVERS.forEach(server => {
|
REMOTE_SERVERS.forEach(server => {
|
||||||
serversStatus[server.name] = {
|
serversStatus[server.name] = {
|
||||||
|
@ -37,11 +54,41 @@ REMOTE_SERVERS.forEach(server => {
|
||||||
lastChecked: null,
|
lastChecked: null,
|
||||||
responseTime: null,
|
responseTime: null,
|
||||||
};
|
};
|
||||||
|
// Initialize previous status
|
||||||
|
previousServersStatus[server.name] = false;
|
||||||
});
|
});
|
||||||
|
|
||||||
// Add PM2 services status object
|
// Add PM2 services status object
|
||||||
let pm2ServicesStatus = {};
|
let pm2ServicesStatus = {};
|
||||||
|
|
||||||
|
// Function to send FCM notification
|
||||||
|
async function sendFCMNotification(message, topic) {
|
||||||
|
try {
|
||||||
|
if (!admin.apps.length) {
|
||||||
|
console.warn("Firebase Admin not initialized, skipping notification");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the message object according to Firebase Admin SDK format
|
||||||
|
const fcmMessage = {
|
||||||
|
topic: topic,
|
||||||
|
notification: {
|
||||||
|
title: 'Server Status Alert',
|
||||||
|
body: message
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
type: 'server_status',
|
||||||
|
timestamp: Date.now().toString()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
await admin.messaging().send(fcmMessage);
|
||||||
|
console.log(`Notification sent: ${message}`);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error sending notification:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function checkServers() {
|
async function checkServers() {
|
||||||
try {
|
try {
|
||||||
ensureLogDirectories();
|
ensureLogDirectories();
|
||||||
|
@ -51,13 +98,37 @@ async function checkServers() {
|
||||||
const res = await ping.promise.probe(server.host, {
|
const res = await ping.promise.probe(server.host, {
|
||||||
timeout: 4, // Set a timeout of 4 seconds
|
timeout: 4, // Set a timeout of 4 seconds
|
||||||
});
|
});
|
||||||
serversStatus[server.name].online = res.alive;
|
|
||||||
|
// Get previous status before updating
|
||||||
|
const wasOnline = previousServersStatus[server.name];
|
||||||
|
const isNowOnline = res.alive;
|
||||||
|
|
||||||
|
// Update status
|
||||||
|
serversStatus[server.name].online = isNowOnline;
|
||||||
serversStatus[server.name].responseTime = res.time;
|
serversStatus[server.name].responseTime = res.time;
|
||||||
|
|
||||||
|
// Send notifications for status changes
|
||||||
|
if (wasOnline === false && isNowOnline) {
|
||||||
|
await sendFCMNotification(`Server ${server.name} is back online`, 'service_online');
|
||||||
|
} else if (wasOnline === true && !isNowOnline) {
|
||||||
|
await sendFCMNotification(`Server ${server.name} is offline`, 'service_offline');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update previous status
|
||||||
|
previousServersStatus[server.name] = isNowOnline;
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`Error pinging ${server.host}:`, error);
|
console.error(`Error pinging ${server.host}:`, error);
|
||||||
serversStatus[server.name].online = false;
|
serversStatus[server.name].online = false;
|
||||||
serversStatus[server.name].responseTime = null;
|
serversStatus[server.name].responseTime = null;
|
||||||
|
|
||||||
|
// Check if status changed from online to offline
|
||||||
|
if (previousServersStatus[server.name] === true) {
|
||||||
|
await sendFCMNotification(`Server ${server.name} is unreachable`, 'service_offline');
|
||||||
|
previousServersStatus[server.name] = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
serversStatus[server.name].lastChecked = new Date().toISOString();
|
serversStatus[server.name].lastChecked = new Date().toISOString();
|
||||||
|
|
||||||
// Log server status to the appropriate folder
|
// Log server status to the appropriate folder
|
||||||
|
@ -85,47 +156,73 @@ async function checkServers() {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function checkPM2Services() {
|
async function checkPM2Services() {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
pm2.connect(function(err) {
|
pm2.connect(function(err) {
|
||||||
if (err) {
|
if (err) {
|
||||||
console.error('Error connecting to PM2:', err);
|
console.error('Error connecting to PM2:', err);
|
||||||
pm2.disconnect();
|
pm2.disconnect();
|
||||||
resolve();
|
resolve();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
pm2.list((err, list) => {
|
pm2.list(async (err, list) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
console.error('Error getting PM2 process list:', err);
|
console.error('Error getting PM2 process list:', err);
|
||||||
pm2.disconnect();
|
pm2.disconnect();
|
||||||
resolve();
|
resolve();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update PM2 services status
|
try {
|
||||||
list.forEach(process => {
|
// Process each PM2 service sequentially with proper async handling
|
||||||
// Calculate uptime correctly - pm_uptime is a timestamp, not a duration
|
for (const process of list) {
|
||||||
const uptimeMs = process.pm2_env.pm_uptime ?
|
const uptimeMs = process.pm2_env.pm_uptime ?
|
||||||
Date.now() - process.pm2_env.pm_uptime :
|
Date.now() - process.pm2_env.pm_uptime :
|
||||||
null;
|
null;
|
||||||
|
|
||||||
pm2ServicesStatus[process.name] = {
|
const processName = process.name;
|
||||||
name: process.name,
|
const isNowOnline = process.pm2_env.status === 'online';
|
||||||
id: process.pm_id,
|
|
||||||
status: process.pm2_env.status,
|
// Check if we've seen this process before
|
||||||
cpu: process.monit ? process.monit.cpu : null,
|
if (previousPM2Status[processName] === undefined) {
|
||||||
memory: process.monit ? process.monit.memory : null,
|
// First time seeing this process - initialize and don't send notification
|
||||||
uptime: uptimeMs, // Store the uptime in milliseconds
|
previousPM2Status[processName] = isNowOnline;
|
||||||
restarts: process.pm2_env.restart_time,
|
console.log(`Initializing PM2 service status for ${processName}: ${isNowOnline ? 'online' : 'offline'}`);
|
||||||
lastChecked: new Date().toISOString()
|
}
|
||||||
};
|
// Check if status changed
|
||||||
});
|
else if (previousPM2Status[processName] === false && isNowOnline) {
|
||||||
|
await sendFCMNotification(`PM2 service ${processName} is back online`, 'service_online');
|
||||||
pm2.disconnect();
|
console.log(`PM2 service ${processName} changed from offline to online`);
|
||||||
resolve();
|
}
|
||||||
});
|
else if (previousPM2Status[processName] === true && !isNowOnline) {
|
||||||
});
|
await sendFCMNotification(`PM2 service ${processName} is offline (status: ${process.pm2_env.status})`, 'service_offline');
|
||||||
});
|
console.log(`PM2 service ${processName} changed from online to ${process.pm2_env.status}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update previous status
|
||||||
|
previousPM2Status[processName] = isNowOnline;
|
||||||
|
|
||||||
|
// Update status object
|
||||||
|
pm2ServicesStatus[processName] = {
|
||||||
|
name: processName,
|
||||||
|
id: process.pm_id,
|
||||||
|
status: process.pm2_env.status,
|
||||||
|
cpu: process.monit ? process.monit.cpu : null,
|
||||||
|
memory: process.monit ? process.monit.memory : null,
|
||||||
|
uptime: uptimeMs,
|
||||||
|
restarts: process.pm2_env.restart_time,
|
||||||
|
lastChecked: new Date().toISOString()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error processing PM2 services:', error);
|
||||||
|
}
|
||||||
|
|
||||||
|
pm2.disconnect();
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function checkAll() {
|
async function checkAll() {
|
||||||
|
|
107
package-lock.json
generated
107
package-lock.json
generated
|
@ -15,13 +15,17 @@
|
||||||
"dotenv": "^16.5.0",
|
"dotenv": "^16.5.0",
|
||||||
"express": "^4.21.2",
|
"express": "^4.21.2",
|
||||||
"firebase-admin": "^13.3.0",
|
"firebase-admin": "^13.3.0",
|
||||||
|
<<<<<<< HEAD
|
||||||
"googleapis": "^148.0.0",
|
"googleapis": "^148.0.0",
|
||||||
|
=======
|
||||||
|
>>>>>>> 917b12bb273711b9117a93963c6ee0ff957376a8
|
||||||
"nodejs": "^0.0.0",
|
"nodejs": "^0.0.0",
|
||||||
"ping": "^0.4.4",
|
"ping": "^0.4.4",
|
||||||
"pm2": "^6.0.5",
|
"pm2": "^6.0.5",
|
||||||
"whois-json": "^2.0.4"
|
"whois-json": "^2.0.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
<<<<<<< HEAD
|
||||||
"node_modules/@discordjs/builders": {
|
"node_modules/@discordjs/builders": {
|
||||||
"version": "1.11.1",
|
"version": "1.11.1",
|
||||||
"resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-1.11.1.tgz",
|
"resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-1.11.1.tgz",
|
||||||
|
@ -149,6 +153,8 @@
|
||||||
"url": "https://github.com/discordjs/discord.js?sponsor"
|
"url": "https://github.com/discordjs/discord.js?sponsor"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
=======
|
||||||
|
>>>>>>> 917b12bb273711b9117a93963c6ee0ff957376a8
|
||||||
"node_modules/@fastify/busboy": {
|
"node_modules/@fastify/busboy": {
|
||||||
"version": "3.1.1",
|
"version": "3.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-3.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-3.1.1.tgz",
|
||||||
|
@ -884,6 +890,7 @@
|
||||||
"license": "BSD-3-Clause",
|
"license": "BSD-3-Clause",
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
|
<<<<<<< HEAD
|
||||||
"node_modules/@sapphire/async-queue": {
|
"node_modules/@sapphire/async-queue": {
|
||||||
"version": "1.5.5",
|
"version": "1.5.5",
|
||||||
"resolved": "https://registry.npmjs.org/@sapphire/async-queue/-/async-queue-1.5.5.tgz",
|
"resolved": "https://registry.npmjs.org/@sapphire/async-queue/-/async-queue-1.5.5.tgz",
|
||||||
|
@ -917,6 +924,8 @@
|
||||||
"npm": ">=7.0.0"
|
"npm": ">=7.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
=======
|
||||||
|
>>>>>>> 917b12bb273711b9117a93963c6ee0ff957376a8
|
||||||
"node_modules/@tootallnate/once": {
|
"node_modules/@tootallnate/once": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz",
|
||||||
|
@ -1019,9 +1028,15 @@
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@types/node": {
|
"node_modules/@types/node": {
|
||||||
|
<<<<<<< HEAD
|
||||||
"version": "22.15.2",
|
"version": "22.15.2",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.2.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.2.tgz",
|
||||||
"integrity": "sha512-uKXqKN9beGoMdBfcaTY1ecwz6ctxuJAcUlwE55938g0ZJ8lRxwAZqRz2AJ4pzpt5dHdTPMB863UZ0ESiFUcP7A==",
|
"integrity": "sha512-uKXqKN9beGoMdBfcaTY1ecwz6ctxuJAcUlwE55938g0ZJ8lRxwAZqRz2AJ4pzpt5dHdTPMB863UZ0ESiFUcP7A==",
|
||||||
|
=======
|
||||||
|
"version": "22.15.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.3.tgz",
|
||||||
|
"integrity": "sha512-lX7HFZeHf4QG/J7tBZqrCAXwz9J5RD56Y6MpP0eJkka8p+K0RY/yBTW7CYFJ4VGCclxqOLKmiGP5juQc6MKgcw==",
|
||||||
|
>>>>>>> 917b12bb273711b9117a93963c6ee0ff957376a8
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"undici-types": "~6.21.0"
|
"undici-types": "~6.21.0"
|
||||||
|
@ -1097,6 +1112,7 @@
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
|
<<<<<<< HEAD
|
||||||
"node_modules/@types/ws": {
|
"node_modules/@types/ws": {
|
||||||
"version": "8.18.1",
|
"version": "8.18.1",
|
||||||
"resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz",
|
"resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz",
|
||||||
|
@ -1116,6 +1132,8 @@
|
||||||
"npm": ">=7.0.0"
|
"npm": ">=7.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
=======
|
||||||
|
>>>>>>> 917b12bb273711b9117a93963c6ee0ff957376a8
|
||||||
"node_modules/abort-controller": {
|
"node_modules/abort-controller": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz",
|
||||||
|
@ -2061,7 +2079,12 @@
|
||||||
"version": "3.1.3",
|
"version": "3.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
|
||||||
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
|
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
|
||||||
|
<<<<<<< HEAD
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
|
=======
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true
|
||||||
|
>>>>>>> 917b12bb273711b9117a93963c6ee0ff957376a8
|
||||||
},
|
},
|
||||||
"node_modules/fast-json-patch": {
|
"node_modules/fast-json-patch": {
|
||||||
"version": "3.1.1",
|
"version": "3.1.1",
|
||||||
|
@ -2173,6 +2196,7 @@
|
||||||
"@google-cloud/storage": "^7.14.0"
|
"@google-cloud/storage": "^7.14.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
<<<<<<< HEAD
|
||||||
"node_modules/firebase-admin/node_modules/uuid": {
|
"node_modules/firebase-admin/node_modules/uuid": {
|
||||||
"version": "11.1.0",
|
"version": "11.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.0.tgz",
|
||||||
|
@ -2186,6 +2210,8 @@
|
||||||
"uuid": "dist/esm/bin/uuid"
|
"uuid": "dist/esm/bin/uuid"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
=======
|
||||||
|
>>>>>>> 917b12bb273711b9117a93963c6ee0ff957376a8
|
||||||
"node_modules/follow-redirects": {
|
"node_modules/follow-redirects": {
|
||||||
"version": "1.15.9",
|
"version": "1.15.9",
|
||||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz",
|
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz",
|
||||||
|
@ -2280,6 +2306,22 @@
|
||||||
"node": ">=14"
|
"node": ">=14"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
<<<<<<< HEAD
|
||||||
|
=======
|
||||||
|
"node_modules/gaxios/node_modules/uuid": {
|
||||||
|
"version": "9.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz",
|
||||||
|
"integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==",
|
||||||
|
"funding": [
|
||||||
|
"https://github.com/sponsors/broofa",
|
||||||
|
"https://github.com/sponsors/ctavan"
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"bin": {
|
||||||
|
"uuid": "dist/bin/uuid"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
>>>>>>> 917b12bb273711b9117a93963c6ee0ff957376a8
|
||||||
"node_modules/gcp-metadata": {
|
"node_modules/gcp-metadata": {
|
||||||
"version": "6.1.1",
|
"version": "6.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-6.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-6.1.1.tgz",
|
||||||
|
@ -2440,6 +2482,23 @@
|
||||||
"node": ">=14"
|
"node": ">=14"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
<<<<<<< HEAD
|
||||||
|
=======
|
||||||
|
"node_modules/google-gax/node_modules/uuid": {
|
||||||
|
"version": "9.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz",
|
||||||
|
"integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==",
|
||||||
|
"funding": [
|
||||||
|
"https://github.com/sponsors/broofa",
|
||||||
|
"https://github.com/sponsors/ctavan"
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"bin": {
|
||||||
|
"uuid": "dist/bin/uuid"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
>>>>>>> 917b12bb273711b9117a93963c6ee0ff957376a8
|
||||||
"node_modules/google-logging-utils": {
|
"node_modules/google-logging-utils": {
|
||||||
"version": "0.0.2",
|
"version": "0.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/google-logging-utils/-/google-logging-utils-0.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/google-logging-utils/-/google-logging-utils-0.0.2.tgz",
|
||||||
|
@ -2449,6 +2508,7 @@
|
||||||
"node": ">=14"
|
"node": ">=14"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
<<<<<<< HEAD
|
||||||
"node_modules/googleapis": {
|
"node_modules/googleapis": {
|
||||||
"version": "148.0.0",
|
"version": "148.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/googleapis/-/googleapis-148.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/googleapis/-/googleapis-148.0.0.tgz",
|
||||||
|
@ -2479,6 +2539,8 @@
|
||||||
"node": ">=14.0.0"
|
"node": ">=14.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
=======
|
||||||
|
>>>>>>> 917b12bb273711b9117a93963c6ee0ff957376a8
|
||||||
"node_modules/gopd": {
|
"node_modules/gopd": {
|
||||||
"version": "1.2.0",
|
"version": "1.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
|
||||||
|
@ -3038,12 +3100,15 @@
|
||||||
"integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==",
|
"integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
<<<<<<< HEAD
|
||||||
"node_modules/lodash.snakecase": {
|
"node_modules/lodash.snakecase": {
|
||||||
"version": "4.1.1",
|
"version": "4.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz",
|
||||||
"integrity": "sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==",
|
"integrity": "sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
=======
|
||||||
|
>>>>>>> 917b12bb273711b9117a93963c6ee0ff957376a8
|
||||||
"node_modules/long": {
|
"node_modules/long": {
|
||||||
"version": "5.3.2",
|
"version": "5.3.2",
|
||||||
"resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz",
|
||||||
|
@ -3097,12 +3162,15 @@
|
||||||
"node": ">=10"
|
"node": ">=10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
<<<<<<< HEAD
|
||||||
"node_modules/magic-bytes.js": {
|
"node_modules/magic-bytes.js": {
|
||||||
"version": "1.12.1",
|
"version": "1.12.1",
|
||||||
"resolved": "https://registry.npmjs.org/magic-bytes.js/-/magic-bytes.js-1.12.1.tgz",
|
"resolved": "https://registry.npmjs.org/magic-bytes.js/-/magic-bytes.js-1.12.1.tgz",
|
||||||
"integrity": "sha512-ThQLOhN86ZkJ7qemtVRGYM+gRgR8GEXNli9H/PMvpnZsE44Xfh3wx9kGJaldg314v85m+bFW6WBMaVHJc/c3zA==",
|
"integrity": "sha512-ThQLOhN86ZkJ7qemtVRGYM+gRgR8GEXNli9H/PMvpnZsE44Xfh3wx9kGJaldg314v85m+bFW6WBMaVHJc/c3zA==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
=======
|
||||||
|
>>>>>>> 917b12bb273711b9117a93963c6ee0ff957376a8
|
||||||
"node_modules/math-intrinsics": {
|
"node_modules/math-intrinsics": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
|
||||||
|
@ -4577,6 +4645,23 @@
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
|
<<<<<<< HEAD
|
||||||
|
=======
|
||||||
|
"node_modules/teeny-request/node_modules/uuid": {
|
||||||
|
"version": "9.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz",
|
||||||
|
"integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==",
|
||||||
|
"funding": [
|
||||||
|
"https://github.com/sponsors/broofa",
|
||||||
|
"https://github.com/sponsors/ctavan"
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"bin": {
|
||||||
|
"uuid": "dist/bin/uuid"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
>>>>>>> 917b12bb273711b9117a93963c6ee0ff957376a8
|
||||||
"node_modules/title-case": {
|
"node_modules/title-case": {
|
||||||
"version": "2.1.1",
|
"version": "2.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/title-case/-/title-case-2.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/title-case/-/title-case-2.1.1.tgz",
|
||||||
|
@ -4613,12 +4698,15 @@
|
||||||
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
|
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
<<<<<<< HEAD
|
||||||
"node_modules/ts-mixer": {
|
"node_modules/ts-mixer": {
|
||||||
"version": "6.0.4",
|
"version": "6.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/ts-mixer/-/ts-mixer-6.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/ts-mixer/-/ts-mixer-6.0.4.tgz",
|
||||||
"integrity": "sha512-ufKpbmrugz5Aou4wcr5Wc1UUFWOLhq+Fm6qa6P0w0K5Qw2yhaUoiWszhCVuNQyNwrlGiscHOmqYoAox1PtvgjA==",
|
"integrity": "sha512-ufKpbmrugz5Aou4wcr5Wc1UUFWOLhq+Fm6qa6P0w0K5Qw2yhaUoiWszhCVuNQyNwrlGiscHOmqYoAox1PtvgjA==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
=======
|
||||||
|
>>>>>>> 917b12bb273711b9117a93963c6ee0ff957376a8
|
||||||
"node_modules/tslib": {
|
"node_modules/tslib": {
|
||||||
"version": "2.8.1",
|
"version": "2.8.1",
|
||||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
|
||||||
|
@ -4670,6 +4758,7 @@
|
||||||
"integrity": "sha512-GMXzWtsc57XAtguZgaQViUOzs0KTkk8ojr3/xAxXLITqf/3EMwxC0inyETfDFjH/Krbhuep0HNbbjI9i/q3F3g==",
|
"integrity": "sha512-GMXzWtsc57XAtguZgaQViUOzs0KTkk8ojr3/xAxXLITqf/3EMwxC0inyETfDFjH/Krbhuep0HNbbjI9i/q3F3g==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
<<<<<<< HEAD
|
||||||
"node_modules/undici": {
|
"node_modules/undici": {
|
||||||
"version": "6.21.1",
|
"version": "6.21.1",
|
||||||
"resolved": "https://registry.npmjs.org/undici/-/undici-6.21.1.tgz",
|
"resolved": "https://registry.npmjs.org/undici/-/undici-6.21.1.tgz",
|
||||||
|
@ -4679,6 +4768,8 @@
|
||||||
"node": ">=18.17"
|
"node": ">=18.17"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
=======
|
||||||
|
>>>>>>> 917b12bb273711b9117a93963c6ee0ff957376a8
|
||||||
"node_modules/undici-types": {
|
"node_modules/undici-types": {
|
||||||
"version": "6.21.0",
|
"version": "6.21.0",
|
||||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
|
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
|
||||||
|
@ -4708,12 +4799,15 @@
|
||||||
"upper-case": "^1.1.1"
|
"upper-case": "^1.1.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
<<<<<<< HEAD
|
||||||
"node_modules/url-template": {
|
"node_modules/url-template": {
|
||||||
"version": "2.0.8",
|
"version": "2.0.8",
|
||||||
"resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz",
|
"resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz",
|
||||||
"integrity": "sha512-XdVKMF4SJ0nP/O7XIPB0JwAEuT9lDIYnNsK8yGVe43y0AWoKeJNdv3ZNWh7ksJ6KqQFjOO6ox/VEitLnaVNufw==",
|
"integrity": "sha512-XdVKMF4SJ0nP/O7XIPB0JwAEuT9lDIYnNsK8yGVe43y0AWoKeJNdv3ZNWh7ksJ6KqQFjOO6ox/VEitLnaVNufw==",
|
||||||
"license": "BSD"
|
"license": "BSD"
|
||||||
},
|
},
|
||||||
|
=======
|
||||||
|
>>>>>>> 917b12bb273711b9117a93963c6ee0ff957376a8
|
||||||
"node_modules/util-deprecate": {
|
"node_modules/util-deprecate": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||||
|
@ -4730,16 +4824,26 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/uuid": {
|
"node_modules/uuid": {
|
||||||
|
<<<<<<< HEAD
|
||||||
"version": "9.0.1",
|
"version": "9.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz",
|
||||||
"integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==",
|
"integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==",
|
||||||
|
=======
|
||||||
|
"version": "11.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.0.tgz",
|
||||||
|
"integrity": "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==",
|
||||||
|
>>>>>>> 917b12bb273711b9117a93963c6ee0ff957376a8
|
||||||
"funding": [
|
"funding": [
|
||||||
"https://github.com/sponsors/broofa",
|
"https://github.com/sponsors/broofa",
|
||||||
"https://github.com/sponsors/ctavan"
|
"https://github.com/sponsors/ctavan"
|
||||||
],
|
],
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"bin": {
|
"bin": {
|
||||||
|
<<<<<<< HEAD
|
||||||
"uuid": "dist/bin/uuid"
|
"uuid": "dist/bin/uuid"
|
||||||
|
=======
|
||||||
|
"uuid": "dist/esm/bin/uuid"
|
||||||
|
>>>>>>> 917b12bb273711b9117a93963c6ee0ff957376a8
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/vary": {
|
"node_modules/vary": {
|
||||||
|
@ -4867,6 +4971,7 @@
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
|
<<<<<<< HEAD
|
||||||
"node_modules/ws": {
|
"node_modules/ws": {
|
||||||
"version": "8.18.1",
|
"version": "8.18.1",
|
||||||
"resolved": "https://registry.npmjs.org/ws/-/ws-8.18.1.tgz",
|
"resolved": "https://registry.npmjs.org/ws/-/ws-8.18.1.tgz",
|
||||||
|
@ -4888,6 +4993,8 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
=======
|
||||||
|
>>>>>>> 917b12bb273711b9117a93963c6ee0ff957376a8
|
||||||
"node_modules/y18n": {
|
"node_modules/y18n": {
|
||||||
"version": "4.0.3",
|
"version": "4.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz",
|
||||||
|
|
|
@ -26,7 +26,10 @@
|
||||||
"dotenv": "^16.5.0",
|
"dotenv": "^16.5.0",
|
||||||
"express": "^4.21.2",
|
"express": "^4.21.2",
|
||||||
"firebase-admin": "^13.3.0",
|
"firebase-admin": "^13.3.0",
|
||||||
|
<<<<<<< HEAD
|
||||||
"googleapis": "^148.0.0",
|
"googleapis": "^148.0.0",
|
||||||
|
=======
|
||||||
|
>>>>>>> 917b12bb273711b9117a93963c6ee0ff957376a8
|
||||||
"nodejs": "^0.0.0",
|
"nodejs": "^0.0.0",
|
||||||
"ping": "^0.4.4",
|
"ping": "^0.4.4",
|
||||||
"pm2": "^6.0.5",
|
"pm2": "^6.0.5",
|
||||||
|
|
61
test-firebase.js
Normal file
61
test-firebase.js
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
const admin = require('firebase-admin');
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
// Get path to service account file
|
||||||
|
const serviceAccountPath = path.join(__dirname, 'firebase-service-account.json');
|
||||||
|
|
||||||
|
// Log the path to verify
|
||||||
|
console.log(`Loading Firebase service account from: ${serviceAccountPath}`);
|
||||||
|
|
||||||
|
// Initialize Firebase Admin SDK
|
||||||
|
try {
|
||||||
|
const serviceAccount = require(serviceAccountPath);
|
||||||
|
|
||||||
|
admin.initializeApp({
|
||||||
|
credential: admin.credential.cert(serviceAccount)
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log("Firebase Admin SDK initialized successfully");
|
||||||
|
|
||||||
|
// Function to send FCM notification
|
||||||
|
async function sendTestNotification() {
|
||||||
|
try {
|
||||||
|
// Send to both topics to test both scenarios
|
||||||
|
const topics = ['service_online', 'service_offline'];
|
||||||
|
|
||||||
|
for (const topic of topics) {
|
||||||
|
// Correctly format the message for Firebase Cloud Messaging
|
||||||
|
const message = {
|
||||||
|
topic: topic,
|
||||||
|
notification: {
|
||||||
|
title: 'Test Notification',
|
||||||
|
body: `This is a test notification to the ${topic} topic`
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
type: 'test',
|
||||||
|
timestamp: Date.now().toString()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
console.log(`Sending test notification to topic: ${topic}`);
|
||||||
|
// Use the send method instead of sendToTopic
|
||||||
|
const response = await admin.messaging().send(message);
|
||||||
|
console.log(`Successfully sent message to ${topic}:`, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("All test notifications sent successfully!");
|
||||||
|
process.exit(0);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error sending notification:', error);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Execute the test
|
||||||
|
sendTestNotification();
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error initializing Firebase Admin SDK:", error);
|
||||||
|
console.error("Make sure firebase-service-account.json exists in the repository root");
|
||||||
|
process.exit(1);
|
||||||
|
}
|
Loading…
Reference in a new issue