Sending SMS via Skype w/ only 6 lines of code

Submitted by hellyeah@mit.edu on Tue, 03/17/2009 - 01:44.

Hey folks,
Skype and Python got a thing going on. Here's how you start it up.
1. Download and install the Skype client.
2. Create a Skype account and buy some Skype credit (like, $10 worth).
3. Download and install Python from python.org
3. Download and install Skype4Py from Sourceforge http://sourceforge.net/projects/skype4py/
3a. Skype4Py reference is here: https://developer.skype.com/wiki/Skype4Py
4. Start Skype and log in.
5. In your Skype client, add a phone number as a SkypeOut contact.
6. Create a python file with the code below.
7. In the code below, replace the dummy phone number (+16175551212) with the number you added in step 5.
8. Run your script! Under Linux, run with superuser permissions.

[ note: for code examples, see the attached files. I just wasted an hour trying to force Drupal (this blogging software) to preserve whitespace so it doesn't destroy all python code posted. Can the admin for this blog change the whitespace settings so we can share python code here? ]


import sys, Skype4Py
api = Skype4Py.Skype() # create a Skype API instance
api.Attach() # connect to Skype
message = api.CreateSms(Skype4Py.smsMessageTypeOutgoing, '+16175551212') # create SMS object. CHANGE THE PHONE NUMBER
message.Body = "Hello World!" # set value of body
message.Send() # send message

The Skype API under Linux has one complication: it will not run when invoked by other programs such as chron or mod_python. This is because it needs access to the XServer environment variables. My solution to this is to create a little Skype relay server that is invoked on the command line and runs perpetually. Other programs can send SMS messages by sending message data to the relay server via a UDP socket. The example below simply receives a message body (via UDP) and sends it (via the Skype API) to a hard-coded phone number list.

SkypeRelayServer.py:

import sys
import Skype4Py
import socket
api = Skype4Py.Skype() # create a Skype API instance
api.Attach() # connect to Skype
HOST = 'localhost' # The remote host
PORT = 52007 # The same port as used by the client
ipSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # create network socket
ipSock.bind((HOST, PORT)) # bind socket to host/port
ipSock.listen(1) # start listenin'
while 1: # do this forever (until program is terminated)
ipConn, ipAddr = ipSock.accept() # wait here until remote client program connects
body_str = ipConn.recv(160) # receive up to 160 characters from remote client program. this will be the SMS message body
pNums_l = ['+16175551212'] # list of phone numbers to send SMS to. in this case, only one number
for pNum_str in pNums_l: # loop through phone number list
message = api.CreateSms(Skype4Py.smsMessageTypeOutgoing, pNum_str) # create SMS object
message.Body = body_str # set value of body
message.Send() # send message
s.shutdown(socket.SHUT_RDWR) # do some network socket housekeeping.
s.close() # housekeeping

Here is an example of a client script that uses SkypeRelayServer.py to send SMS messages. It's a python script in the mod_python environment that reads an SMS message string submitted from a Web form and sends the data to SkypeRelayServer.py to be broadcast via SMS.


from mod_python import apache
from mod_python import util
import sys
import os
import socket
import time
def handler(req):
HOST = 'localhost' # The remote host
PORT = 52007 # The same port as used by the server
ipSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # create network socket
ipSock.settimeout(600)
ipSock.connect((HOST, PORT)) # connect to SkypeRelayServer.py
body_str = util.FieldStorage(req).list[0].value # get the value of the submitted SMS message body
ipSock.send(body_str) # send SMS message body to SkypeRelayServer.py
ipSock.shutdown(socket.SHUT_RDWR) # housekeeping
ipSock.close() # housekeeping
util.redirect(req, "send.html") # redirect the browser back to the Web form
return apache.OK # tell Apache this script is finished