Retrieving Debian Server Information VIA SMS with Google Voice

This my little project to retrieve information from my home server via text. The basic structure of this is: SMS Google Voice number with commands and an identifier (like a password) >> Set Google Voice to forward all SMS to email >> use a user crontab and getmail on the server to check for mail every minute (or other user defined amount of time) >> If there’s an email, a script looks for the Identifier >> figure out the information wanted >> use a ruby script to send text.

The Prerequisites:

sudo apt-get install ruby1.8 getmail4 curl

Setting Up Google Voice and Gmail

Personally I created a new account for this because both getmail and the Google SMS script require saving your username and password in an un-encrypted text document. Go to your Gmail settings >> Forwarding and POP/IMAP and change “2. When messages are accessed with POP” to “archive Gmail’s copy”.

Then go to and set up a new number for Google Voice to use. Go to settings >> Voicemail & Text >> and ensure that ” Forward text messages to my email” is checked.

Configuring Getmail

My guide for this part is based on this tutorial. First create a folder called “mail” under your home directory along with four sub folders : “bak”, “cur”, “new”, “tmp”.

mkdir mail ; mkdir ~/mail/bak ; mkdir ~/mail/cur ; mkdir ~/mail/new ; mkdir ~/mail/tmp

This is where the SMSs (In the form of emails) will be stored. Then create a folder under home called “.getmail”

mkdir ~/.getmail

In this folder create a text file named “”


Open this with your favorite text editor

nano ~/.getmail/

And fill it in with the following (note: you must supply your Gmail username and password at this point):

type = SimplePOP3SSLRetriever
server =
username =

type = Maildir
path = ~/mail/

# print messages about each action (verbose = 2)
# Other options:
# 0 prints only warnings and errors
# 1 prints messages about retrieving and deleting messages only
verbose = 2
message_log = ~/.getmail/gmail.log

Setting Up the Scripts

I use two scrips. One that’s written in bash that recieves and interprets the SMS and one that’s written in ruby and sends out the SMS. The ruby script is written by Brett Terpstra over at You can find the tutorial for this script here.

I created a folder called .text under my home directory to put these two scripts.

mkdir ~/.text

Name the first one voicemail.sms

#!/usr/bin/env ruby -Ku

require 'net/http'
require 'net/https'
require 'open-uri'
require 'cgi'
require 'optparse'
require 'jcode' if RUBY_VERSION < '1.9'

ACCOUNT = 'YOURGMAILACCOUNT' # Set to Google Voice account email for default account
PASSWORD = 'YOURPASSWORD' # Set to Google Voice account password for default account
NUMBERS = ['+1555444333','+1555444222'] # Set one or more numbers for default destination(s)

options = {}
optparse = do|opts|
opts.banner = "Usage: voicesms.rb -n +15554443333[,+15554442222] -m \"Message to send\" [-u Username:Password]"

options[:numbers] = NUMBERS
opts.on( '-n', '--numbers NUM[,NUM]', 'Phone numbers to SMS (separate multiples with comma)' ) do|numbers|
options[:numbers] = numbers.split(',')

options[:message] = false
opts.on( '-m', '--message MESSAGE', 'Message to send' ) do|msg|
options[:message] = msg

options[:username] = ACCOUNT
options[:password] = PASSWORD
opts.on( '-u', '--user USERNAME:PASSWORD', 'Google Voice username and password' ) do|creds|
parts = creds.split(':')
options[:username] = parts[0]
options[:password] = parts[1]

opts.on( '-h', '--help', 'Display this screen' ) do
puts opts


unless options[:message]
puts "Message required. Use -m \"MESSAGE\"."
puts "Enter `voicesms.rb -h` for help."

def postit(uri_str, data, header = nil, limit = 3)
raise ArgumentError, 'HTTP redirect too deep' if limit == 0
url = URI.parse(uri_str)
http =,443)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
response,content =,data,header)
case response
when Net::HTTPSuccess then content
when Net::HTTPRedirection then postit(response['location'],data,header, limit - 1)
puts response.inspect

def getit(uri_str, header, limit = 3)
raise ArgumentError, 'HTTP redirect too deep' if limit == 0
url = URI.parse(uri_str)
http =,url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
response,content = http.get(url.path,header)
case response
when Net::HTTPSuccess then content
when Net::HTTPRedirection then getit(response['location'],header, limit - 1)

data = "accountType=GOOGLE&Email=#{options[:username]}&Passwd=#{options[:password]}&service=grandcentral&source=brettterpstra-CLISMS-2.0"
res = postit('',data)
if res
authcode = res.match(/Auth=(.+)/)[1]
header = {'Authorization' => "GoogleLogin auth=#{authcode.strip}",'Content-Length' => '0'}
newres = getit('',header)
if newres
rnrse = CGI.escape(newres.match(/'_rnr_se': '([^']+)'/)[1])
#rnrse = CGI.escape(newres.match(/'_rnr_se': '([^']+)'/)[1])
options[:numbers].each {|num|
data = "_rnr_se=#{rnrse}&phoneNumber=#{num.strip}&text=#{CGI.escape(options[:message])}&id="
finalres = postit('',data,header)
if finalres["ok"]
puts "Message sent to #{num}"
puts "Error sending to #{num}"

Then make a text file called and copy these contents in to it.

# A program to listen for SMS, with the aid of crontab, from Google Voice and
#reply with some system, internet, or other data

#Uses a getmail script to grab emails
getmail -r ~/.getmail/

#Checks for mail and if there is none it doesn't run the rest of the script.
if [ -f ~/mail/new/* ]

#Removes and recreates any old tmp file if ones exists
if [ -f ~/.text/tmp ]
rm ~/.text/tmp
echo "Deleted Old tmp File"
touch ~/.text/tmp #Recreates tmp

#Searches incoming mail for a the string ##! which denotes the message intended for
#recieving. Saves output to the previously created tmp file.
cat ~/mail/new/* | grep -m 1 '##!' >> ~/.text/tmp

#Defines TEXTER as the sender of the text
TEXTER=$(grep "SMS from" ~/mail/new/* | grep -o [0-9] | tr -d '\n')


#If ip is contained in the text store the ip to tmp
if grep -q ip ~/.text/tmp
curl >> ~/.text/tmp

#If date is contained in the text store it to tmp
if grep -q date ~/.text/tmp
date >> ~/.text/tmp

#If space is contained in the text store it to tmp
if grep -q space ~/.text/tmp
df -h / >> ~/.text/tmp

#If who is contained in the text store it to tmp
if grep -q who ~/.text/tmp
w >> ~/.text/tmp

#If uptime is contained in the text store it to tmp
if grep -q who ~/.text/tmp
uptime >> ~/.text/tmp


#Stores the contents of tmp to SMS
SMS=$(cat ~/.text/tmp)

#Backs up emails to ~/mail/bak
mv ~/mail/new/* ~/mail/bak/

#Uses a ruby script to send a $SMS if there is new mail
ruby ~/.text/voicesms.rb -n +"$TEXTER" -m "$SMS"

To copy these with formatting you can get them at:

Make sure to put your email address and password in the voicesms.rb!

From here you just need to make a cron job to process this script at given times.


crontab -e

and add the line :

* * * * * sh ~/.text/

This will check for new texts once a minute. if you want to make that time longer simply add a /<number of minutes to check> to the first asterisk. So every five minutes would be:

*/5 * * * * sh ~/.text/

And you should be set up to send commands to your server via text message! To set up your own commands use this template:

if grep -q KEYWORD_FOR_COMMAND ~/.text/tmp
COMMAND_TO_OUTPUT &gt;&gt; ~/.text/tmp

Where KEYWORD_FOR_COMMAND would be something like “whatdayisit?” and the COMMAND_TO_OUTPUT would be the BASH command “date”. Put your snippet of code in the “DEFINE USER VARIABLE” section of

Another thing to note is I use ##! to denote to the this is a text that I want a reply to. This serves two purposes: one is to filter out the line of the email that it important to me (using grep); two is to make sure no one can just send texts to my server and get replies, it acts as sort of a password. If you want to change this just change the ##! in line 22.

If you have any questions feel free to reply here!


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s