Send Linux commands to a remote PC(or server) from WhatsApp

Send Linux commands to a remote PC(or server) from WhatsApp

·

4 min read

Inspiration

Some years back, I wanted to link two systems talking to each other through Linux commands. It was just a project out of curiosity, and wasn't even a serious one. I didn't know Twilio or Plivo or any other platform related. I tried to die hard, but guess what! it was hard indeed :) I learnt about Twilio and built many other related projects. You can do the same, or even start building your very own next Twilio. Yes! It's possible. Hell, yess !

You can learn from this project, going further and building something tremendous! From the concept of this project (of-course you need to improve and add few other things) you can:

  • Deploy your docker replicas just by sending WhatsApp text
  • You can monitor your IoT devices remotely
  • Send commands to your K8's engine for some orchestration processes

In fact you can do a lot, the sky is not a limit :) Let's set up our project.

Setup a project in Twilio

In this article, we will focus more on how to interact these technologies and accomplish what we want. Our focus won't be more on Twilio.

  • To setup a sandbox and obtain a WhatsApp number (sender id) follow this link

  • Obtain ACCOUNT_SID and AUTH_TOKEN from the platform. Click here

  • Now let's proceed with the project.

Flow of our project

architecture flow(3).jpg

Building a server in Python

Now that we have already setup our project in Twilio platform and obtained ACCOUNT_SID and AUTH_TOKEN its time to build our server. We will use Flask for this project.

Create a file, name it command.py. This is the file where we will write our server-side application to and establish a connection between the machine (which will receive the commands) and WhatsApp through Twilio.

Install the required packages and make them available in the requirements.txt file.

$ pip install flask, twilio
$ pip freeze > requirements.txt

In the file command.py import the libraries:

import os
from flask import Flask, request
from twilio.twiml.messaging_response import MessagingResponse

From the import, Flask will help us to setup the server, request will enable us to send requests from WhatsApp via the Twilio sandbox to this server we're building.

MessagingResponse is the Twilio Python class whose object helps to manage responses, that is incoming and outgoing messages or even calls. In short, MessagingResponse helps to starts the TwiML

We will use os to make our WhatsApp text be excuted on the remote terminal (can be your remote Linux machine or the Server) as Linux commands (not just text).

Now lets write our first function to handle incomming commands sent from a phone (via WhatsApp) to the Twilio number we obtained early.

@app.route("/command", methods=['GET', 'POST'])
def command():
    # get the message body which sent to the Twilio number
    body = request.values.get('Body', None)
    # Start our TwiML response
    resp = MessagingResponse()

Now MessagingResponse is well set, we can listen to the response coming to our Twilio number obtained. We can receive and process the message sent from any WhatsApp number (ofcourse, sent to our Twilio number). We can now start the chat, receive the commands and run them on the terminal.

# Determine the right reply for this message
    if body == 'command':
        resp.message('What command do you want to run on your machine?')

    # You can send any command
    elif body == 'init 0':
        resp.message('Shutting down your machine...')
        os.system('init 0')

    elif body != 'command':
        os.system(body)

Here's the command.py file

from flask import Flask, request, redirect
from twilio.twiml.messaging_response import MessagingResponse
import os
from decouple import config

app = Flask(__name__)

@app.route("/")
def home():
    # Just to make sure if flask server runs successfully
    return 'Hello, the server is running...'

@app.route("/command", methods=['GET', 'POST'])
def command():
     """
        Send a dynamic reply to an incoming text message
        Get the message the user sent our Twilio number
     """
    body = request.values.get('Body', None)
    # Start our TwiML response
    resp = MessagingResponse()

    if body == 'command':
        resp.message('What command do you want to run on your machine?')
    # You can send any command
    elif body == 'init 0':
        resp.message('Shutting down your machine...')
        os.system('init 0')
    elif body != 'command':
        os.system(body)
    return str(resp)

if __name__ == "__main__":
    # Run the script on port 5000
    app.run(debug=True, host='0.0.0.0', port='5000')

Send linux commands from your WhatsApp

Finally, we need to send commands and let them be processed by our server. But the server is currently running on localhost. We need to expose the server publicly and use its url as callback url in the Twilio platform. You can choose to deploy the app and continue, but for now i will use Ngrok for this task. Make sure you install ngrok before continue.

On the terminal, run this command:

$ ngrok http 5000

Running this command will expose port 5000 which is the same port where our server is running. Ngrok will return a url (a link) of our running server. Copy this url and fill in the Twilio platform in your project console as a callback url. Check this example below:

sandbox.jpg

If you followed all instructions up to now, then you're on the right track and ready to start sending commands from your WhatsApp.

Happy coding!

References