How to send SMS message with Python

I can’t beleive all the things that you can do with Python. Obviously, whatever you can do with Python, you can do with a whole bunch of programming languages out there. What I am really impressed with, is the ease.

Few weeks ago I was looking for a way to programatically send myself SMS on certain occasions. I was (and still) developing a system that would check for certain conditions on a server and alert me when something is wrong.

Eventually, I came up with a Python script, 40 lines long :-) Note that you have to pay for the messages, but thats just few pennies. I bet there’s a way to plug into ICQ’s protocol and send SMS for free, but I don’t think you can do this with only 40 lines of code.

Here is the idea. There are firms on the internet, that provide service called SMS gateway. These firms has special devices plugged into GSM network on one end and has some programmable interface on the other end.

Here’s what you do. You open an account with such a firm. Then you either pay for one message or buy some credits and then spend them by sending messages.

SMS gateway I used called world-text. Please, by all means I have nothing to do with these guys. I found them on the internet, just as you would.

There are couple of nice things about this particular company, although I bet if you spend some time researching you will find a better and probably cheaper one.

I don’t think there’s a standard for SMS gateways. Each company does something of its own. World-text provide web based gateway and this is what makes it so easy to use with Python.

Python code that I’ve written, simply sends properly formatted HTTP request to their web interface. Here’s the code.

#!/usr/bin/python

import sys
import time
import glob
import httplib
import urllib

recepients = []

recepients.append("-------------")

world_text_username = "your@email.com"
world_text_password = "your password"

def usage():
    print "alertme.py <message to send>"
    sys.exit(0)

def send_sms(msg):
    global recepients, world_text_username, world_text_password

    print "Asked to send sms: %s" % msg

    for r in recepients:
        params = ""
        params = params + "username=" + world_text_username
        params = params + "&password=" + world_text_password
        params = params + "&" + urllib.urlencode({'message': msg})
        params = params + "&sourceaddr=SMSAlert"
        params = params + "&mobile=" + r
        headers = {"Content-Type": "application/x-www-form-urlencoded"}
        conn = httplib.HTTPConnection("sms.world-text.com:1081")
        conn.request("POST", "/sendsms", params, headers)
        conn.close();

if len(sys.argv) != 2:
    usage()

send_sms(sys.argv[1])

To use the script, just append your phone number, including country and regional code to the recepients list – make sure to delete the “———-” from it. Next change world_text_username and world_text_password to something meaningful and you are ready to bombard yourself with SMS messages :-)

In case you have further questions, email me at alex@alexonlinux.com.

Have fun! :D

Did you know that you can receive periodical updates with the latest articles that I write right into your email box? Alternatively, you subscribe to the RSS feed!

Want to know how? Check out
Subscribe page

18 Comments

  1. Oh. Here we have an example of bad programming. usage() by all means should not do sys.exit(0) :D

  2. sparc86 says:

    Pretty interesting!

    I may try it later. :)

  3. Just FYI, I’ve found Clickatell to be an inexpensive SMS gateway, especially if you’re sending to the US (4 cents/msg Clickatell, > 8p per message world-text). I use them, but I don’t work for them, and that’s not an affiliate link.

  4. @Rick Copeland
    Thanks for the info. I’ll keep this in mind :-)

  5. Thomas Bennett says:

    To just send sms why not use smtp and skip third party services? And you don’t have to pay to send the message. The recipient’s cost is based on their contract with the carrier.

    ====================================

    #!/usr/local/bin/python
    # -*- coding: iso-8859-1 -*-
    
    import sys
    import os
    import smtplib
    import string
    import datetime
    
    fromaddr = "me@my.mail.server"
    toaddr = "my_phone_number@vtext.com"
    
    msg = """From: me@my.mail.server\r\nTo: my_gamil@gmail.com,  my_phone_number@vtext.com>\r\nSubject: server disk report\r\n\r\n"""
    msg = msg + "\r\n SERVER DISK IS GETTING FULL\r\n"
    msg = msg + string.join(os.popen('df -h').readlines())[111:132]
    when=datetime.datetime.time(datetime.datetime.now())
    # if time is not between 11:00pm and 7:00 am then continue (don't wake me up)
    if ( (int(when.hour)>23) or (int(when.hour)<7) ):
      pass
    else:
       Run "df -h" command and check available space on / and if it is less than 28 Gb send a text message to me
      if int(string.join(os.popen('df -h').readlines())[123:126])<28:
        print "Message length is " + repr(len(msg))
        server = smtplib.SMTP('mail.appstate.edu')
        #server.set_debuglevel(1)    # not debugging during live action
        server.sendmail(fromaddr,toaddr,msg)
        server.quit()
      else:
        pass
    

    ===========================================

    I think they have another page for other cell carriers.

    T-Mobile:phonenumber@tmomail.net
    Virgin Mobile:phonenumber@vmobl.com
    Cingular:phonenumber@cingularme.com
    Sprint:phonenumber@messaging.sprintpcs.com
    Verizon: phonenumber@vtext.com
    Nextel: phonenumber@messaging.nextel.com

    where phonenumber = your 10 digit phone number

    (above copied from
    http://www.tech-recipes.com/rx/939/sms_email_cingular_nextel_sprint_tmobile_verizon_virgin )

  6. @Thomas Bennett
    You’re right of course. However, there are couple of reasons not to work with services you suggested.
    1. Such services are not available everywhere. Even if they are, they usually have limitations – number of messages and recipients.
    2. If you’re looking for reliable service you better pay for it – with free services you get as much as you pay.

  7. Eric says:

    While I agree that using those particular carriers isn’t necessarily a good idea (mostly since who knows how well each carrier will continue to support it and whether you’ll get any indication when they’re changed or dropped), your second point is completely ridiculous.

    You’re writing Python (free) and you use Linux (free); this site is or was built in WordPress (free)… yet despite building your professional life and web presence on free products, you “get as much as you pay” for free services. Open-source development is a free service provided to the community; was your kernel work worthless just because people who may have used it didn’t pay you for it?

    Anyway, it seems to me you could make far better arguments against sending messages directly through carriers than taking a largely-unrelated, overgeneralized pot shot at free services.

  8. @Eric
    I see your point, but you took what I said to some place where I didn’t mean it to be. By saying “you get as much as you pay” I didn’t mean to trample entire open source community. It is sort of a way to say

    mostly since who knows how well each carrier will continue to support it and whether you’ll get any indication when they’re changed or dropped

    in one sentence.
    So in essence I meant to say that you get no guarantee of service, no guarantee of quality of service. You may be disconnected from the service any moment for whatever reason the carrier will come up with (abuse for example). Etc.

  9. Madhukar says:

    Hi Alex,

    That’s a very nice code to send SMS i have tried thanks, But I am looking for receive a SMS through python.
    Will you please suggest me something if you can to receive SMS?

  10. Richard T says:

    I found this very useful. I’ve updated it to work on python 3.2 and here it is:

    import sys
    import time
    import glob
    import http.client
    import urllib.request, urllib.parse, urllib.error
    from datetime import datetime

    WORLD_TEXT_USERNAME = “your_username”
    WORLD_TEXT_PASSWORD = “your_password”

    def send_sms(msg, phone_no, source=’SMSAlert’, simulation = 1):
    ”’The Source address must match one setup on the account being used.
    Put ‘&sim’ at the end of each phone number to use their simulator.
    ”’
    params = “username=” + WORLD_TEXT_USERNAME
    params += “&password=” + WORLD_TEXT_PASSWORD
    params += “&” + urllib.parse.urlencode({‘message’: msg})
    params +=”&sourceaddr=” + source
    params += “&mobile=” + phone_no
    if simulation == 1:
    params += ‘&sim’
    #print(‘Params: ‘, params)
    headers = {“Content-Type”: “application/x-www-form-urlencoded”}
    conn = http.client.HTTPConnection(“sms.world-text.com:1081”)
    conn.request(“POST”, “/sendsms”, params, headers)
    conn.close();
    print(‘Sent to: ‘, phone_no, ‘at ‘, str(datetime.now()), ‘ Message: ‘,msg)
    return #It would be good to have this return a sent/fail respsonse

  11. kaka says:

    please stop talk something like that.is it go for everyone?

  12. Hamish says:

    Hi,

    Thanks for the guide. The script can be improved, and made shorter as well by replacing lines

    26 params = “”
    27 params = params + “username=” + world_text_username
    28 params = params + “&password=” + world_text_password
    29 params = params + “&” + urllib.urlencode({‘message’: msg})
    30 params = params + “&sourceaddr=SMSAlert”
    31 params = params + “&mobile=” + r

    with one line,

    params = params + “&” + urllib.urlencode({ ‘username’:world_text_username, ‘password’:world_text_password, ‘message’: msg, ‘sourceaddr’:’SMSAlert’,’mobile’:r})

  13. Hamish says:

    @Hamish

    my bad,

    params = urllib.urlencode({ ‘username’:world_text_username, ‘password’:world_text_password, ‘message’: msg, ‘sourceaddr’:’SMSAlert’,’mobile’:r})

  14. Ty says:

    You guys’ code makes mine look like it was made by a 5 year old. If someone replies to your message it may (only tested on Gmail) go into your account’s inbox.

    Anyway:

    import sys
    import smtplib

    phone = raw_input(‘Phone number: ‘)

    print ‘\n1) AT&T’
    print ‘2) Boost Mobile’
    print ‘3) Verizon’
    print ‘4) T-Mobile’
    print ‘5) Sprint\n’

    choice = int(raw_input(‘Choose carrier: ‘))

    if choice == 1:
    carrier = ‘%s@txt.att.net’ % phone
    if choice == 2:
    carrier = ‘%s@myboostmobile.com’ % phone
    if choice == 3:
    carrier = ‘%s@vtext.com’ % phone
    if choice == 4:
    carrier = ‘%s@tmomail.net’ % phone
    if choice == 5:
    carrier = ‘%s@messaging.sprintpcs.com’ % phone

    try:
    SMS = smtplib.SMTP(‘smtp.website.com’, port) #no quotes around port number
    SMS.starttls()
    except IOError:
    sys.exit(1)

    try:
    SMS.login(‘you@whatever.com’, ‘password’)
    except BaseException:
    sys.exit(1)

    From = None
    To = carrier
    message = raw_input(“\nMessage: “)
    SMS.sendmail(From, To, message)

  15. Text Blast says:

    We all live a busy life and often we forget about important tasks or events at hand. This is why businesses use text blasts to send out reminders to the clients or customers in real-time to ensure they never miss out. Plus, this also builds a positive relationship with your audience.

  16. Free janam kundli analysis by date of birth and time. Janak kundali help your to know everything about your future, and planet effects on your life. Get online kundli in Hindi and English. Janam Kundli also known as birth chart, Janma Patrika.

  17. lana says:

    params = params + “&” + urllib.urlencode({ ‘username’:world_text_username, ‘password’:world_text_password, ‘message’: msg, ‘sourceaddr’:’SMSAlert’,’mobile’:r})

  18. Hello
    I meant to say that you get no guarantee of service, no guarantee of quality of service. You may be disconnected from the service any moment for whatever reason the carrier will come up with (abuse for example). Etc.

Leave a Reply to Thomas Bennett

Prove you are not a computer or die *