#!/usr/bin/perl =pod A perl version of the so-called "php" API for use on www.m4u.com.au By picoSpace PTY LTD (spammagnet@picospace.com.au - www.picospace.com.au). Permission is given to anyone wishing to use this software unconditionally, provided that: 1) They do not claim credit for writing this software, and appropriately attribute credit when asked (either in conversations or email). 2) Do not attempt to hold picoSpace PTY LTD (Australia) or any of its directors, members or employees responsible for anything negative that occurs through the use of this software. This code is based around the following transcript of interaction between client and server (try it by telnet-ing to smsmaster.m4u.com.au port 80): POST / HTTP/1.0 Host: smsmaster.m4u.com.au m4u USER=YourUsername PASSWORD=YourPassword VER=PHP1.0 MESSAGES2.0 0 61mobileWithoutLeadingZero 0 169 0 This is a test. . HTTP/1.0 200 OK Connection: close Date: Wed, 06 Oct 2004 03:58:23 GMT Content-Type: text/html Content-Length: 105 M4U SMSMASTER 100 OK 45 credits remaining . any parsing or protocol writing is based on the fact that this particular sequence worked OK. Of note: 1) The line 0 mobileNumber 0 169 0 can be multiple lines, each line should contain a single SMS message. The fields are: messageID (for later tracking), mobile number in country-number format delay, validityPeriod, deliveryReport(bool) I've decided to pike and ignore delay, messageID and deliveryReport. The validityPeriod was lifted from the PHP version. Since I'm mainly focusing on getting outgoing messages working, I'll focus on those now. To start, create the M4U object, passing it your username and password, which will be used to login: my $sms=new M4U('my username', 'my password'); to begin sending messages, run startMessages(): $sms->startMessages(); you can either use addMessage to queue up your messages: $sms->addMessage('61455555555', 'This is a test to a non-existant phone'); $sms->addMessage('61455555555', 'As many messages as m4u supports'); or the convenience function send_au for Australian mobiles: $sms->send_au('0455555555', 'This is a test to a non-existant phone'); $sms->send_au('0455555555', 'As many messages as m4u supports'); I suspect to can also put various other commands in, but I haven't tried to yet. To finish, call commit(), prompts m4u to print the return text shown in the transcript above, before closing the connection. Run getReply() to get the return info: $sms->commit(); my ($rvNumber, $text, $creditsLeft)=$sms->getReply(); I don't think that the object can still be used at this stage, so I would create another one if you need to use it again after a commit(). The object's destructor closes the socket, although it would have probably already have been terminated by the sms server. LICENSING: Copyright (C) 2004 Voon-Li Chung. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA The author can be contacted through the following means: Email: vlchung@earthling.net Post: Voon-Li Chung PO Box 149 GLENGARRY WA 6023 AUSTRALIA =cut use IO::Socket; # only dependency, _should_ be part of any Perl installation package M4U; return true; sub new { my $className = $_[0]; my $self = {}; my $login=$_[1]; my $password=$_[2]; my $sock = new IO::Socket::INET ( PeerAddr => 'smsmaster.m4u.com.au', PeerPort => '80', Proto => 'tcp', ) or die ("Getting a connection to the server"); print $sock "POST / HTTP/1.0\nHost: smsmaster.m4u.com.au\n\nm4u\nUSER=$login\nPASSWORD=$password\nVER=picoSpace.com.au-perl-1.0\n" or die ("Logging in"); $self->{'socket'}=$sock; bless ($self, $className); return $self; } sub DESTROY { my $self=$_[0]; close($self->{'socket'}); } sub send_au { my $self=$_[0]; my $newNumber = "61".substr ($_[1], 1, 9); $self->addMessage($newNumber, $_[2]); return; } sub startMessages { my $self=$_[0]; my $sock=$self->{'socket'}; print $sock "MESSAGES2.0\n" or die ("Starting messages header"); return; } sub commit { my $self=$_[0]; my $sock=$self->{'socket'}; print $sock ".\n" or die ("Ending message list"); return; } sub addMessage { my $self=$_[0]; my $sock=$self->{'socket'}; my $number=$_[1]; my $message=$_[2]; print $sock "0 $number 0 169 0 $message\n" or die ("Adding message to $number"); return; } sub getReply { my $self=$_[0]; my $sock=$self->{'socket'}; @reply=<$sock>; foreach $i(@reply) { #print STDERR "$i"; # uncomment the above line if you want to see the server return text if ($i =~ m/^[0-9]+/) # the transcript suggests that the only line we are interested in is # also the only one that starts with a number { my $s=$i; chomp $s; my @line=split(/ /, $s); if ($line[0] => 100 && $line[0] <= 199) { return ($line[0], $line[1], $line[2]); } return ($line[0], $i, 0); } } }