There are often situations when server access is needed immediately. However, SSH connection is not always the most convenient method since an SSH client, server address, or user/password pair may not be readily available. Of course, there is , which simplifies administration, but it also doesn't provide instant access.
Therefore, I decided to implement a simple yet interesting solution. Specifically — to write a Telegram bot that, when running on the server, will execute the commands it receives and return the results. After studying resources on this topic, I realized that no one has described similar implementations yet.
I developed this project on Ubuntu 16.04, but I tried to make it universally applicable for easy deployment on other distributions.
Registering the bot
We register a new bot with @BotFather. We send him /newbot and continue with the text. We will need the token of the new bot and your id (you can get it, for example, from ).
Preparing Python
To run the bot, we will use the library telebot (pip install pytelegrambotapi). Using the library subprocess , we will execute commands on the server.
Launching the bot
On the server, create the file bot.py:
nano bot.py
And insert the following code:
from subprocess import check_output
import telebot
import time
bot = telebot.TeleBot("XXXXXXXXX:AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA") # bot token
user_id = 0 # your account id
@bot.message_handler(content_types=["text"])
def main(message):
if (user_id == message.chat.id): # check that the owner is writing
comand = message.text # message text
try: # if the command is not executable - check_output will raise an exception
bot.send_message(message.chat.id, check_output(comand, shell = True))
except:
bot.send_message(message.chat.id, "Invalid input") # if the command is incorrect
if __name__ == '__main__':
while True:
try: # adding try to ensure continuous operation
bot.polling(none_stop=True) # start the bot
except:
time.sleep(10) # in case of failure
Replace the bot token with the one given by @BotFather, and user_id with the value of your account id. Checking the user id is necessary for the bot to grant access to your server only to you. The function check_output() executes the command passed to it and returns the result.
All that's left is to launch the bot. To run processes on the server, I prefer to use screen (sudo apt-get install screen):
screen -dmS ServerBot python3 bot.py(where "ServerBot" is the process identifier)
The process will automatically start in the background. Let's go to the chat with the bot and check that everything is working as it should:

Congratulations! The bot is executing the commands sent to it. Now, to access the server, you just need to open a chat with the bot.
Command repetition
Often, to monitor the server's status, it is necessary to execute the same commands repeatedly. Therefore, implementing command repetition without resending them will be very useful.
We will implement this using inline buttons under the messages:
from subprocess import check_output
import telebot
from telebot import types # Import buttons
import time
bot = telebot.TeleBot("XXXXXXXXX:AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA") # Bot token
user_id = 0 # Your account id
@bot.message_handler(content_types=["text"])
def main(message):
if (user_id == message.chat.id): # Check that it is the owner writing
command = message.text # Message text
markup = types.InlineKeyboardMarkup() # Create the keyboard
button = types.InlineKeyboardButton(text="Repeat", callback_data=command) # Create a button
markup.add(button) # Add button to the keyboard
try: # If the command is not executable - check_output will raise an exception
bot.send_message(user_id, check_output(command, shell=True, reply_markup=markup)) # Call the command and send the message with the result
except:
bot.send_message(user_id, "Invalid input") # If the command is incorrect
@bot.callback_query_handler(func=lambda call: True)
def callback(call):
command = call.data # Read the command from the button data field
try: # If the command is not executable - check_output will raise an exception
markup = types.InlineKeyboardMarkup() # Create the keyboard
button = types.InlineKeyboardButton(text="Repeat", callback_data=command) # Create a button and pass the command in the data
markup.add(button) # Add button to the keyboard
bot.send_message(user_id, check_output(command, shell=True), reply_markup=markup) # Call the command and send the message with the result
except:
bot.send_message(user_id, "Invalid input") # If the command is incorrect
if __name__ == '__main__':
while True:
try: # Add try for uninterrupted operation
bot.polling(none_stop=True) # Start the bot
except:
time.sleep(10) # In case of failure
Restarting the bot:
killall python3
screen -dmS ServerBot python3 bot.py
Let's check again that everything is working correctly:

When the button under the message is pressed, the bot should repeat the command from which this message was sent.
In conclusion
Certainly, this method does not claim to replace traditional connection methods; however, it allows quickly to know the server's status and send it commands that do not require complicated output.
Source: habr.com
