#!/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);
}
}
}