From 7d157e513678d053dcb93a7cc6c280979a7bbd61 Mon Sep 17 00:00:00 2001 From: HornetMaidan Date: Sat, 5 Oct 2024 00:31:47 +0500 Subject: [PATCH 01/12] added tailscale subnet availability check --- lainmonitor.py | 35 ++++++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/lainmonitor.py b/lainmonitor.py index 5386e5a..178272b 100644 --- a/lainmonitor.py +++ b/lainmonitor.py @@ -3,9 +3,11 @@ #usage: python3 lainmonitor.py | or run it as a service #author: hornetmaidan import subprocess +import threading import telebot #define the variables status, hostname, uptime, zerotier, prosody, postgres, tailscale, disk, ping = 'unknown', 'unknown', 'unknown', 'unknown', 'unknown', 'unknown', 'unknown', 'unknown', 'unknown' +nodes, hostnames, reach, threads = [], [], [], [] #telegram bot token TOKEN = 'PLACE_YOUR_TOKEN_HERE' @@ -29,15 +31,30 @@ def getinfo(): status = 'online' return hostname, uptime, zerotier, prosody, postgres, tailscale, disk -#ping tailscale (change the IP address to the one you want or add more) +#function to ping tailscale nodes +def ping_node(node, hostname): + ping = subprocess.Popen(f"ping {node} -c 1 | grep '1 packets'", shell=True, stdout=subprocess.PIPE).stdout.read().decode().strip() + if '1 received' in ping: + reach.append(f'{node}/{hostname} is reachable') + else: + reach.append(f'{node}/{hostname} is unreachable') + +#ping tailscale nodes def check_tailscale(): - global ping - ping = subprocess.Popen("ping TAILSCALE_IP -c 1 | grep '1 packets'", shell=True, stdout=subprocess.PIPE).stdout.read().decode().strip() - if '1 received' in ping: - ping = 'connected' - else: - ping = 'unreachable' - return ping + global nodes, hostnames, reach, threads, ping + nodes_output = subprocess.Popen("tailscale status | grep '100'", shell=True, stdout=subprocess.PIPE).stdout.read().decode().strip() + nodes = [line.split()[0] for line in nodes_output.split('\n') if line] + hostnames = [line.split()[1] for line in nodes_output.split('\n') if line] + + for node, hostname in zip(nodes, hostnames): + thread = threading.Thread(target=ping_node, args=(node, hostname)) + threads.append(thread) + thread.start() + + for thread in threads: + thread.join() + + return reach #debug handler def check(): @@ -69,7 +86,7 @@ def handle(message): bot.reply_to(message, 'work in progress...') elif message.text == '/ping': check_tailscale() - bot.reply_to(message, f'ping status: {ping}') + bot.reply_to(message, f'ping status: \n\n{reach}') #polling bot.polling() \ No newline at end of file From a007405b4f219eee06136ec0053fae161411f23c Mon Sep 17 00:00:00 2001 From: HornetMaidan Date: Sat, 5 Oct 2024 00:35:18 +0500 Subject: [PATCH 02/12] add .gitignore --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7d7a845 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +test.py +venv/ \ No newline at end of file From edb0641889beec0a59ca5e01addf5c5945c84bca Mon Sep 17 00:00:00 2001 From: HornetMaidan Date: Sat, 5 Oct 2024 00:53:58 +0500 Subject: [PATCH 03/12] fixed the ping formatting --- lainmonitor.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lainmonitor.py b/lainmonitor.py index 178272b..0012e5c 100644 --- a/lainmonitor.py +++ b/lainmonitor.py @@ -86,7 +86,8 @@ def handle(message): bot.reply_to(message, 'work in progress...') elif message.text == '/ping': check_tailscale() - bot.reply_to(message, f'ping status: \n\n{reach}') + ping_status = '\n'.join(reach) + bot.reply_to(message, f'ping status:\n\n{ping_status}') #polling bot.polling() \ No newline at end of file From 5d0ce49d0c856cdcc80bc275ca206c8163088b70 Mon Sep 17 00:00:00 2001 From: HornetMaidan Date: Sat, 5 Oct 2024 01:08:41 +0500 Subject: [PATCH 04/12] hotfix --- lainmonitor.py | 1 + 1 file changed, 1 insertion(+) diff --git a/lainmonitor.py b/lainmonitor.py index 0012e5c..341c2de 100644 --- a/lainmonitor.py +++ b/lainmonitor.py @@ -88,6 +88,7 @@ def handle(message): check_tailscale() ping_status = '\n'.join(reach) bot.reply_to(message, f'ping status:\n\n{ping_status}') + ping_status = '' #polling bot.polling() \ No newline at end of file From f45bffd25eb5114b3ff55e3d9ec7d6da689195bc Mon Sep 17 00:00:00 2001 From: HornetMaidan Date: Sat, 5 Oct 2024 01:24:00 +0500 Subject: [PATCH 05/12] hotfix #2 --- lainmonitor.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lainmonitor.py b/lainmonitor.py index 341c2de..5086458 100644 --- a/lainmonitor.py +++ b/lainmonitor.py @@ -5,11 +5,13 @@ import subprocess import threading import telebot +import os + #define the variables status, hostname, uptime, zerotier, prosody, postgres, tailscale, disk, ping = 'unknown', 'unknown', 'unknown', 'unknown', 'unknown', 'unknown', 'unknown', 'unknown', 'unknown' nodes, hostnames, reach, threads = [], [], [], [] -#telegram bot token -TOKEN = 'PLACE_YOUR_TOKEN_HERE' + +TOKEN = os.getenv('TELEGRAM_BOT_TOKEN') #telegram bot token - set it in env: $TELEGRAM_BOT_TOKEN=your_token_here #bot init bot = telebot.TeleBot(TOKEN) @@ -89,6 +91,8 @@ def handle(message): ping_status = '\n'.join(reach) bot.reply_to(message, f'ping status:\n\n{ping_status}') ping_status = '' + global reach + reach.clear() #polling bot.polling() \ No newline at end of file From c0d02bb69a9b340d93b5d94b7105ebb7d3573955 Mon Sep 17 00:00:00 2001 From: HornetMaidan Date: Sat, 5 Oct 2024 01:32:33 +0500 Subject: [PATCH 06/12] hotfix #3 (MY FUCKING GOD) --- lainmonitor.py | 1 - 1 file changed, 1 deletion(-) diff --git a/lainmonitor.py b/lainmonitor.py index 5086458..fff42ac 100644 --- a/lainmonitor.py +++ b/lainmonitor.py @@ -91,7 +91,6 @@ def handle(message): ping_status = '\n'.join(reach) bot.reply_to(message, f'ping status:\n\n{ping_status}') ping_status = '' - global reach reach.clear() #polling From 29cc8aedd4733ac8ea20d81ad9a047c828d7e008 Mon Sep 17 00:00:00 2001 From: HornetMaidan Date: Sat, 5 Oct 2024 01:38:52 +0500 Subject: [PATCH 07/12] horfix #4 (fucking insanity) --- .env | 1 + lainmonitor.py | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) create mode 100644 .env diff --git a/.env b/.env new file mode 100644 index 0000000..e791c3a --- /dev/null +++ b/.env @@ -0,0 +1 @@ +YOUR_TOKEN_HERE \ No newline at end of file diff --git a/lainmonitor.py b/lainmonitor.py index fff42ac..1b23e61 100644 --- a/lainmonitor.py +++ b/lainmonitor.py @@ -5,16 +5,16 @@ import subprocess import threading import telebot -import os #define the variables status, hostname, uptime, zerotier, prosody, postgres, tailscale, disk, ping = 'unknown', 'unknown', 'unknown', 'unknown', 'unknown', 'unknown', 'unknown', 'unknown', 'unknown' nodes, hostnames, reach, threads = [], [], [], [] -TOKEN = os.getenv('TELEGRAM_BOT_TOKEN') #telegram bot token - set it in env: $TELEGRAM_BOT_TOKEN=your_token_here +#load the token +token = open('.env', 'r').read().strip() #bot init -bot = telebot.TeleBot(TOKEN) +bot = telebot.TeleBot(token) #get system info def getinfo(): From 7e3acb68ce5a354435903f46dc8b3dcd6247a2bf Mon Sep 17 00:00:00 2001 From: HornetMaidan Date: Sat, 5 Oct 2024 01:41:05 +0500 Subject: [PATCH 08/12] updoot README --- README.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index c00ed87..dbc6ff4 100644 --- a/README.md +++ b/README.md @@ -25,10 +25,9 @@ LainMonitor is a Telegram bot designed to monitor your system by providing real- ```bash pip install pyTelegramBotAPI ``` -3. Replace the placeholder in the code with your Telegram bot token: - ```python - TOKEN = 'PLACE_YOUR_TOKEN_HERE' - ``` +3. Replace the placeholder in the .env file with your Telegram bot token + +4. Add the .env file to .gitignore to prevent token overwriting 4. Set up permissions for the bot to check system services (run as a user with `sudo` access). From f28f291a493dd8ac185ac4c0093e5a1f9466a929 Mon Sep 17 00:00:00 2001 From: hornet Date: Sat, 5 Oct 2024 02:00:47 +0500 Subject: [PATCH 09/12] updoot readme --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index dbc6ff4..ca8827c 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -# LainMonitor +# lainmonitor -LainMonitor is a Telegram bot designed to monitor your system by providing real-time information about the system's status, services, and disk usage. It can also check connectivity to a specific Tailscale IP address. +lainmonitor is a Telegram bot designed to monitor your system by providing real-time information about the system's status, services, and disk usage. It can also check connectivity to a specific Tailscale IP address. ## Features - Retrieve system hostname, uptime, and status of essential services such as: @@ -69,10 +69,10 @@ To run LainMonitor as a service, follow these steps: - `/start`: Initialize the bot and receive a welcome message. - `/help`: Display available commands. - `/status`: Get the system hostname, status, uptime, and the status of monitored services. -- `/ping`: Ping a Tailscale IP and return the connectivity status. +- `/ping`: Ping a Tailscale IP subnet and return the connectivity status for each peer. - `/reboot`: (Work in progress) Placeholder for a reboot command. ## Author -Created by **hornetmaidan** +Created by **hornet** and **hax** Feel free to contribute or suggest features! \ No newline at end of file From 0afffee697ebdaec8bf7dbb7cb76aa82b843818a Mon Sep 17 00:00:00 2001 From: hornet Date: Thu, 17 Oct 2024 15:51:21 +0500 Subject: [PATCH 10/12] new functions(WIP) - /reboot and /restart service --- lainmonitor.py | 38 ++++++++++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/lainmonitor.py b/lainmonitor.py index 1b23e61..f053e0d 100644 --- a/lainmonitor.py +++ b/lainmonitor.py @@ -1,15 +1,19 @@ #description: telegram bot for monitoring the system #dependencies: telebot #usage: python3 lainmonitor.py | or run it as a service -#author: hornetmaidan +#authors: hornet import subprocess import threading +from time import sleep import telebot #define the variables status, hostname, uptime, zerotier, prosody, postgres, tailscale, disk, ping = 'unknown', 'unknown', 'unknown', 'unknown', 'unknown', 'unknown', 'unknown', 'unknown', 'unknown' nodes, hostnames, reach, threads = [], [], [], [] +#change this to your hostname +host = 'lainlounge' + #load the token token = open('.env', 'r').read().strip() @@ -58,6 +62,26 @@ def check_tailscale(): return reach +#restart services +def restart_service(service): + subprocess.Popen(f'sudo systemctl restart {service}', shell=True, stdout=subprocess.PIPE).stdout.read().decode().strip() + sleep(3) + service_status = subprocess.Popen(f'sudo systemctl status {service} | grep "Active"', shell=True, stdout=subprocess.PIPE).stdout.read().decode().strip() + message = f'{service} restarted! status: {service_status}' + +#restart services menu +def restart_menu(): + keyboard = telebot.types.ReplyKeyboardMarkup(resize_keyboard=True) + zerotier_button = telebot.types.KeyboardButton('zerotier-one', callback_data='zerotier') + prosody_button = telebot.types.KeyboardButton('prosody', callback_data='prosody') + postgres_button = telebot.types.KeyboardButton('postgresql', callback_data='postgresql') + tailscale_button = telebot.types.KeyboardButton('tailscaled', callback_data='tailscaled') + + return keyboard + +def reboot(): + subprocess.Popen('sudo reboot', shell=True, stdout=subprocess.PIPE).stdout.read().decode().strip() + #debug handler def check(): global status, hostname, uptime, zerotier, prosody, postgres, tailscale, disk @@ -73,7 +97,7 @@ def check(): return status, hostname, uptime, zerotier, prosody, postgres, tailscale, disk #message handling -@bot.message_handler(commands=['start', 'help', 'status', 'reboot', 'ping']) +@bot.message_handler(commands=['start', 'help', 'status', 'restart', 'reboot', 'ping']) def handle(message): if message.text == '/start': bot.reply_to(message, 'lainmonitor v1.0 --- standing by...') @@ -84,8 +108,14 @@ def handle(message): status_message = f'hostname: {hostname}\nsystem status: {status}\nuptime: {uptime}\nzerotier: {zerotier}\nprosody: {prosody}\npostgres: {postgres}\ntailscale: {tailscale}' bot.reply_to(message, status_message) bot.reply_to(message, f'filesystem info for {hostname}: \n\n{disk}') - elif message.text == '/reboot': - bot.reply_to(message, 'work in progress...') + elif message.text == f'/restart {host}': + if host == hostname: + bot.send_message(message.chat.id, 'select a service to restart:', reply_markup=restart_menu()) + else: + pass + elif message.text == f'/reboot {hostname}': + bot.reply_to(message, f'rebooting {host}...') + reboot() elif message.text == '/ping': check_tailscale() ping_status = '\n'.join(reach) From e68739966a4e48ce2a926f601098288af3af9a4a Mon Sep 17 00:00:00 2001 From: hornet Date: Fri, 18 Oct 2024 18:06:53 +0500 Subject: [PATCH 11/12] finished /reboot host and /restart host functions, added authorization for actions by telegram ID, added nginx to default services --- .authorized_users | 2 ++ lainmonitor.py | 82 ++++++++++++++++++++++++++++++++--------------- 2 files changed, 58 insertions(+), 26 deletions(-) create mode 100644 .authorized_users diff --git a/.authorized_users b/.authorized_users new file mode 100644 index 0000000..dbefc0c --- /dev/null +++ b/.authorized_users @@ -0,0 +1,2 @@ +AUTHORIZED_USER_ID_1 +AUTHORIZED_USER_ID_2 \ No newline at end of file diff --git a/lainmonitor.py b/lainmonitor.py index f053e0d..2550725 100644 --- a/lainmonitor.py +++ b/lainmonitor.py @@ -5,20 +5,27 @@ import subprocess import threading from time import sleep -import telebot +from telebot import * + #define the variables -status, hostname, uptime, zerotier, prosody, postgres, tailscale, disk, ping = 'unknown', 'unknown', 'unknown', 'unknown', 'unknown', 'unknown', 'unknown', 'unknown', 'unknown' +status, hostname, uptime, zerotier, prosody, postgres, tailscale, nginx, disk, ping = 'unknown', 'unknown', 'unknown', 'unknown', 'unknown', 'unknown', 'unknown', 'unknown', 'unknown', 'unknown' nodes, hostnames, reach, threads = [], [], [], [] -#change this to your hostname -host = 'lainlounge' +#change this to your instance's hostname +host = subprocess.check_output(['hostname']).decode().strip() +#print ('host:', host) # debug #load the token token = open('.env', 'r').read().strip() +#load the authorized users +authorized_users = [line.strip() for line in open('.authorized_users', 'r').readlines()] +#print('authorized users:', authorized_users) # debug + #bot init bot = telebot.TeleBot(token) +updater = bot.update_listener #get system info def getinfo(): @@ -30,12 +37,13 @@ def getinfo(): prosody = subprocess.Popen("sudo systemctl status prosody | grep 'Active'", shell=True, stdout=subprocess.PIPE).stdout.read().decode().strip() postgres = subprocess.Popen("sudo systemctl status postgresql | grep 'Active'", shell=True, stdout=subprocess.PIPE).stdout.read().decode().strip() tailscale = subprocess.Popen("sudo systemctl status tailscaled | grep 'Active'", shell=True, stdout=subprocess.PIPE).stdout.read().decode().strip() + nginx = subprocess.Popen("sudo systemctl status nginx | grep 'Active'", shell=True, stdout=subprocess.PIPE).stdout.read().decode().strip() disk = subprocess.check_output(['df', '-h']).decode().strip() if hostname == 'unknown': status = 'offline' else: status = 'online' - return hostname, uptime, zerotier, prosody, postgres, tailscale, disk + return hostname, uptime, zerotier, prosody, postgres, tailscale, nginx, disk #function to ping tailscale nodes def ping_node(node, hostname): @@ -64,27 +72,43 @@ def check_tailscale(): #restart services def restart_service(service): + print(f'restarting {service}...') subprocess.Popen(f'sudo systemctl restart {service}', shell=True, stdout=subprocess.PIPE).stdout.read().decode().strip() sleep(3) service_status = subprocess.Popen(f'sudo systemctl status {service} | grep "Active"', shell=True, stdout=subprocess.PIPE).stdout.read().decode().strip() - message = f'{service} restarted! status: {service_status}' + status_message = f'{service} restarted! status: {service_status}' + return status_message #restart services menu def restart_menu(): - keyboard = telebot.types.ReplyKeyboardMarkup(resize_keyboard=True) - zerotier_button = telebot.types.KeyboardButton('zerotier-one', callback_data='zerotier') - prosody_button = telebot.types.KeyboardButton('prosody', callback_data='prosody') - postgres_button = telebot.types.KeyboardButton('postgresql', callback_data='postgresql') - tailscale_button = telebot.types.KeyboardButton('tailscaled', callback_data='tailscaled') + keyboard = [ + [telebot.types.InlineKeyboardButton('zerotier-one', callback_data='zerotier-one')], + [telebot.types.InlineKeyboardButton('prosody', callback_data='prosody')], + [telebot.types.InlineKeyboardButton('postgresql', callback_data='postgresql')], + [telebot.types.InlineKeyboardButton('tailscaled', callback_data='tailscaled')], + [telebot.types.InlineKeyboardButton('nginx', callback_data='nginx')], + [telebot.types.InlineKeyboardButton('cancel', callback_data='cancel')] + ] + reply_markup = telebot.types.InlineKeyboardMarkup(keyboard) + return reply_markup - return keyboard +#callback query handler +@bot.callback_query_handler(func=lambda call: True) +def callback_query(call): + service = call.data + if service != 'cancel': + status_message = restart_service(service) + bot.send_message(call.message.chat.id, status_message) + else: + bot.edit_message_reply_markup(call.message.chat.id, call.message.message_id, reply_markup=None) + bot.send_message(call.message.chat.id, 'canceled') def reboot(): subprocess.Popen('sudo reboot', shell=True, stdout=subprocess.PIPE).stdout.read().decode().strip() #debug handler def check(): - global status, hostname, uptime, zerotier, prosody, postgres, tailscale, disk + global status, hostname, uptime, zerotier, prosody, postgres, tailscale, nginx, disk getinfo() print('system status:', status) print('hostname:', hostname) @@ -94,7 +118,7 @@ def check(): print('postgres:', postgres) print('tailscale:', tailscale) print('disk:', disk) - return status, hostname, uptime, zerotier, prosody, postgres, tailscale, disk + return status, hostname, uptime, zerotier, prosody, postgres, tailscale, nginx, disk #message handling @bot.message_handler(commands=['start', 'help', 'status', 'restart', 'reboot', 'ping']) @@ -102,26 +126,32 @@ def handle(message): if message.text == '/start': bot.reply_to(message, 'lainmonitor v1.0 --- standing by...') elif message.text == '/help': - bot.reply_to(message, 'commands: /start, /help, /status, /reboot, /ping') + bot.reply_to(message, 'commands: /start, /help, /status, /restart, /reboot, /ping') elif message.text == '/status': check() - status_message = f'hostname: {hostname}\nsystem status: {status}\nuptime: {uptime}\nzerotier: {zerotier}\nprosody: {prosody}\npostgres: {postgres}\ntailscale: {tailscale}' + status_message = f'hostname: {hostname}\nsystem status: {status}\nuptime: {uptime}\nzerotier: {zerotier}\nprosody: {prosody}\npostgres: {postgres}\ntailscale: {tailscale}\nnginx: {nginx}' bot.reply_to(message, status_message) bot.reply_to(message, f'filesystem info for {hostname}: \n\n{disk}') elif message.text == f'/restart {host}': - if host == hostname: + if message.text == f'/restart {host}' and str(message.from_user.id) in authorized_users: bot.send_message(message.chat.id, 'select a service to restart:', reply_markup=restart_menu()) else: - pass - elif message.text == f'/reboot {hostname}': - bot.reply_to(message, f'rebooting {host}...') - reboot() + bot.reply_to(message, 'you are not authorized to restart services on this host') + elif message.text == f'/reboot {host}': + if message.text == f'/reboot {host}' and str(message.from_user.id) in authorized_users: + bot.reply_to(message, f'rebooting {host}...') + reboot() + else: + bot.reply_to(message, 'you are not authorized to reboot this host') elif message.text == '/ping': - check_tailscale() - ping_status = '\n'.join(reach) - bot.reply_to(message, f'ping status:\n\n{ping_status}') - ping_status = '' - reach.clear() + if message.text == f'/restart {host}' and str(message.from_user.id) in authorized_users: + check_tailscale() + ping_status = '\n'.join(reach) + bot.reply_to(message, f'ping status:\n\n{ping_status}') + ping_status = '' + reach.clear() + else: + bot.reply_to(message, 'you are not authorized to view ping status') #polling bot.polling() \ No newline at end of file From 93fb4f93d064c5e48a80aff89f95c4f77d605a85 Mon Sep 17 00:00:00 2001 From: hax Date: Fri, 25 Oct 2024 00:43:54 +0000 Subject: [PATCH 12/12] Updoot README V1.1.0 :) --- README.md | 109 +++++++++++++++++++++++++++++------------------------- 1 file changed, 58 insertions(+), 51 deletions(-) diff --git a/README.md b/README.md index c00ed87..505b39f 100644 --- a/README.md +++ b/README.md @@ -1,54 +1,59 @@ # LainMonitor -LainMonitor is a Telegram bot designed to monitor your system by providing real-time information about the system's status, services, and disk usage. It can also check connectivity to a specific Tailscale IP address. +LainMonitor is a Telegram bot designed to monitor your system, providing real-time updates on the system’s status, essential services, and disk usage. It can also verify connectivity to a specific Tailscale IP address. +### Key Features: -## Features -- Retrieve system hostname, uptime, and status of essential services such as: - - Zerotier - - Prosody - - PostgreSQL - - Tailscale -- Check disk usage -- Ping a Tailscale IP to verify connectivity -- Use via Telegram commands like `/status`, `/ping`, and `/help` + Retrieve system information: + Hostname + Uptime + Status of critical services: + Zerotier + Prosody + PostgreSQL + Tailscale + Check disk usage + Ping a Tailscale IP for connectivity verification + Accessible via Telegram commands such as /status, /ping, and /help -## Dependencies -- [Telebot](https://github.com/eternnoir/pyTelegramBotAPI) - A Python library for Telegram bot API. +### Prerequisites: + + Python 3 + Telebot — Python library for interacting with the Telegram bot API. + +### Installation Guide: + +Clone the repository: -## Installation -1. Clone this repository: - ```bash git clone https://git.lainlounge.xyz/hornet/lainmonitor.git cd lainmonitor - ``` -2. Install the required Python library: - ```bash - pip install pyTelegramBotAPI - ``` -3. Replace the placeholder in the code with your Telegram bot token: - ```python - TOKEN = 'PLACE_YOUR_TOKEN_HERE' - ``` -4. Set up permissions for the bot to check system services (run as a user with `sudo` access). +Install dependencies: -## Usage + pip3 install pyTelegramBotAPI -### Running Directly -You can run the bot directly using Python: +Configure your bot token: Open the lainmonitor.py file and replace the placeholder with your Telegram bot token: -```bash -python3 lainmonitor.py -``` + TOKEN = 'YOUR_BOT_TOKEN' + +Set up service access: Ensure the bot can check system services by running it with sudo or appropriate permissions. + +### Usage: +#### Running the Bot Manually: + +You can run LainMonitor directly from the command line: + + python3 lainmonitor.py + +#### Running as a Systemd Service: + +To run the bot as a systemd service, follow these steps: + +Create a service file: -### Running as a Service -To run LainMonitor as a service, follow these steps: -1. Create a systemd service file: - ```bash sudo nano /etc/systemd/system/lainmonitor.service - ``` -2. Add the following configuration: - ```ini + +Add the following configuration: + [Unit] Description=LainMonitor Telegram Bot After=network.target @@ -59,21 +64,23 @@ To run LainMonitor as a service, follow these steps: [Install] WantedBy=multi-user.target - ``` -3. Enable and start the service: - ```bash + +Enable and start the service: + sudo systemctl enable lainmonitor sudo systemctl start lainmonitor - ``` -## Telegram Bot Commands -- `/start`: Initialize the bot and receive a welcome message. -- `/help`: Display available commands. -- `/status`: Get the system hostname, status, uptime, and the status of monitored services. -- `/ping`: Ping a Tailscale IP and return the connectivity status. -- `/reboot`: (Work in progress) Placeholder for a reboot command. +### Available Commands: -## Author -Created by **hornetmaidan** + /start — Initialize the bot and receive a welcome message. + /help — Display a list of available commands. + /status — Retrieve system hostname, uptime, and status of monitored services. + /ping — Ping a Tailscale IP and return connectivity status. + /reboot — (Work in progress) Placeholder for a system reboot command. -Feel free to contribute or suggest features! \ No newline at end of file +### Contributions: + +Created by hornetmaidan. +With Contributions from h@x. + +Any new features and suggestions are welcome! \ No newline at end of file