Skip to content

Commit f85c286

Browse files
committed
🦔 Initial commit
0 parents  commit f85c286

File tree

7 files changed

+1597
-0
lines changed

7 files changed

+1597
-0
lines changed

.env.example

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+

.gitignore

+133
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
data/
2+
.wwebjs_cache/
3+
4+
# Logs
5+
logs
6+
*.log
7+
npm-debug.log*
8+
yarn-debug.log*
9+
yarn-error.log*
10+
lerna-debug.log*
11+
.pnpm-debug.log*
12+
13+
# Diagnostic reports (https://nodejs.org/api/report.html)
14+
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
15+
16+
# Runtime data
17+
pids
18+
*.pid
19+
*.seed
20+
*.pid.lock
21+
22+
# Directory for instrumented libs generated by jscoverage/JSCover
23+
lib-cov
24+
25+
# Coverage directory used by tools like istanbul
26+
coverage
27+
*.lcov
28+
29+
# nyc test coverage
30+
.nyc_output
31+
32+
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
33+
.grunt
34+
35+
# Bower dependency directory (https://bower.io/)
36+
bower_components
37+
38+
# node-waf configuration
39+
.lock-wscript
40+
41+
# Compiled binary addons (https://nodejs.org/api/addons.html)
42+
build/Release
43+
44+
# Dependency directories
45+
node_modules/
46+
jspm_packages/
47+
48+
# Snowpack dependency directory (https://snowpack.dev/)
49+
web_modules/
50+
51+
# TypeScript cache
52+
*.tsbuildinfo
53+
54+
# Optional npm cache directory
55+
.npm
56+
57+
# Optional eslint cache
58+
.eslintcache
59+
60+
# Optional stylelint cache
61+
.stylelintcache
62+
63+
# Microbundle cache
64+
.rpt2_cache/
65+
.rts2_cache_cjs/
66+
.rts2_cache_es/
67+
.rts2_cache_umd/
68+
69+
# Optional REPL history
70+
.node_repl_history
71+
72+
# Output of 'npm pack'
73+
*.tgz
74+
75+
# Yarn Integrity file
76+
.yarn-integrity
77+
78+
# dotenv environment variable files
79+
.env
80+
.env.development.local
81+
.env.test.local
82+
.env.production.local
83+
.env.local
84+
85+
# parcel-bundler cache (https://parceljs.org/)
86+
.cache
87+
.parcel-cache
88+
89+
# Next.js build output
90+
.next
91+
out
92+
93+
# Nuxt.js build / generate output
94+
.nuxt
95+
dist
96+
97+
# Gatsby files
98+
.cache/
99+
# Comment in the public line in if your project uses Gatsby and not Next.js
100+
# https://nextjs.org/blog/next-9-1#public-directory-support
101+
# public
102+
103+
# vuepress build output
104+
.vuepress/dist
105+
106+
# vuepress v2.x temp and cache directory
107+
.temp
108+
.cache
109+
110+
# Docusaurus cache and generated files
111+
.docusaurus
112+
113+
# Serverless directories
114+
.serverless/
115+
116+
# FuseBox cache
117+
.fusebox/
118+
119+
# DynamoDB Local files
120+
.dynamodb/
121+
122+
# TernJS port file
123+
.tern-port
124+
125+
# Stores VSCode versions used for testing VSCode extensions
126+
.vscode-test
127+
128+
# yarn v2
129+
.yarn/cache
130+
.yarn/unplugged
131+
.yarn/build-state.yml
132+
.yarn/install-state.gz
133+
.pnp.*

README.md

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# WhatsApp Watchdog
2+
3+
WhatsApp Watchdog is a Node.js application to monitor Python scripts/services on Windows and send alerts via WhatsApp if the script/service is down. It regularly checks if a specified service (like a Python script) is running on the system and sends an alert through WhatsApp if the service is down.
4+
5+
6+
## Motivation
7+
This project was born out of a personal need to monitor `update_sheets.py`, a Python script on my Windows machine that neede to be running 24/7. Therefore, I created this project to monitor the script and send me a WhatsApp alert (because it's more convenient for me) if the script is down.
8+
9+
## Installation
10+
11+
1. Clone the repository:
12+
```bash
13+
git clone https://github.com/MeshalAlamr/whatsapp-watchdog.git
14+
cd whatsapp-watchdog
15+
```
16+
17+
2. Install dependencies:
18+
```bash
19+
npm ci
20+
```
21+
22+
3. Set up alert recipient:
23+
- Copy `.env.example` and rename it to `.env`.
24+
- Update the `.env` file with the WhatsApp chat ID you want to send alerts to. (e.g., `[email protected]`)
25+
26+
4. Configure monitoring settings:
27+
- Modify `config.js` to set the monitoring schedule and specific Python script/service to monitor.
28+
- The default configuration is set to check `main.py` every hour.
29+
30+
## Usage
31+
1. Start the application:
32+
```bash
33+
npm start
34+
```
35+
36+
2. Link WhatsApp:
37+
- Scan the QR code in the terminal using WhatsApp on your phone (WhatsApp -> Linked Devices).
38+
- Once you see "WhatsApp Watchdog is ready!", the monitoring starts.
39+
40+
## Contributing
41+
Contributions to WhatsApp Watchdog are greatly appreciated. If you have suggestions for improvements or want to contribute to the project, please feel free to do so. Expanding the project to support other operating systems is a good place to start.
42+
43+
## License
44+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
45+
46+
## Disclaimer
47+
This application is not affiliated with or endorsed by WhatsApp.

config.js

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Load environment variables from a .env file
2+
require('dotenv').config();
3+
4+
module.exports = {
5+
// Python service/script name to monitor
6+
serviceName: `main.py`,
7+
8+
// Schedule setting for cron job (every 1 hour in this example)
9+
schedule: '1 * * * *',
10+
11+
// WhatsApp Chat ID for sending messages
12+
chatId: process.env.CHATID,
13+
14+
// Path to store authentication data for WhatsApp
15+
dataPath: './data',
16+
17+
// Puppeteer arguments for running headless Chrome
18+
puppeteerArgs: [
19+
"--no-sandbox",
20+
"--disable-setuid-sandbox",
21+
"--disable-dev-shm-usage",
22+
"--shm-size=3gb"
23+
]
24+
};

index.js

+74
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
const schedule = require('node-schedule');
2+
const qrcode = require("qrcode-terminal");
3+
const { Client, LocalAuth } = require("whatsapp-web.js");
4+
const puppeteer = require('puppeteer');
5+
const { exec } = require('child_process');
6+
const config = require('./config');
7+
8+
class WhatsAppService {
9+
constructor() {
10+
this.client = new Client({
11+
authStrategy: new LocalAuth({ dataPath: config.dataPath }),
12+
puppeteer: {
13+
executablePath: puppeteer.executablePath(),
14+
headless: true,
15+
args: config.puppeteerArgs,
16+
},
17+
});
18+
19+
this.initializeClient();
20+
}
21+
22+
initializeClient() {
23+
this.client.initialize();
24+
25+
this.client.on("qr", (qr) => {
26+
qrcode.generate(qr, { small: true });
27+
});
28+
29+
this.client.on("ready", () => {
30+
console.log("WhatsApp Watchdog is ready!");
31+
});
32+
}
33+
34+
sendMessage(chatId, message) {
35+
this.client.sendMessage(chatId, message).catch(error => {
36+
console.error("Error sending message:", error);
37+
});
38+
}
39+
}
40+
41+
class WindowsSystemMonitor {
42+
static checkPythonService(callback) {
43+
const psCommand = `get-wmiobject Win32_process -filter "Name='python.exe'" | foreach-object {$_.CommandLine}`;
44+
exec(`powershell.exe -command "${psCommand.replace(/"/g, '\\"')}"`, callback);
45+
}
46+
}
47+
48+
function main() {
49+
console.log('Starting WhatsApp service...')
50+
const whatsAppService = new WhatsAppService();
51+
52+
schedule.scheduleJob(config.schedule, () => {
53+
WindowsSystemMonitor.checkPythonService((err, stdout, stderr) => {
54+
if (err) {
55+
console.error("Error:", err);
56+
return;
57+
}
58+
59+
if (stderr) {
60+
console.error("Stderr:", stderr);
61+
return;
62+
}
63+
64+
if (!stdout.includes(config.serviceName)) {
65+
console.log('Service is not running');
66+
whatsAppService.sendMessage(config.chatId, config.serviceName + " is not running, please check!");
67+
} else {
68+
console.log('Service is running');
69+
}
70+
});
71+
});
72+
}
73+
74+
main();

0 commit comments

Comments
 (0)