#!/usr/bin/perl # $Id: optus-websms,v 1.20 2011/12/08 09:18:30 suter Exp suter $ # Copyright (C) 2003,2011 Mark Suter # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see L. use strict; use warnings; use English qw( -no_match_vars ); use Getopt::Long; use Pod::Usage; use WWW::Mechanize; our ($VERSION) = '$Revision: 1.20 $' =~ m{ \$Revision: \s+ (\S+) }msx; ## Where we get the authentication details (also see --rc=file option) my @rc = ( "$ENV{HOME}/.optus-websmsrc", '/usr/local/etc/optus-websmsrc', '/etc/optus-websmsrc' ); ## Figure out what we're doing my ( $mobile, $password, $recipients, $message, $debug ) = process_input(); ## Do the work send_sms_now( $mobile, $password, $recipients, $message, $debug ); ## Notice weird things like "no space on device" END { close STDOUT or die "$PROGRAM_NAME: can't close stdout: $OS_ERROR\n" } ## Figure out the values for our work sub process_input { my ( $mobile, $password, $recipients, $message ); my %opt = ( version => 0, man => 0, help => 0, message => undef, stdin => 1, maxchars => 160, truncate => 0, test => 0, rc => undef, debug => 0, ); GetOptions( \%opt, 'version', 'man', 'help', 'message=s', 'stdin!', 'maxchars=i', 'truncate', 'test', 'rc=s', 'debug' ) or pod2usage(0); $opt{version} and do { print "optus-websms version $VERSION\n"; exit; }; $opt{man} and pod2usage( -exitval => 0, -verbose => 2 ); $opt{help} and pod2usage(0); ## Pick which config file to use my $rc = 'no-rc-file-found'; if ( defined $opt{rc} ) { $rc = $opt{rc}; } else { foreach (@rc) { -e $_ and do { $rc = $_; last }; } } ## Read $rc to get mobile number and password for http://www.optuszoo.com.au/ open my $file, '<', $rc or die "$PROGRAM_NAME: Can't open \"$rc\": $OS_ERROR\n"; chomp( $mobile = <$file> ); $mobile =~ m{ \A \d+ \Z }msix or die "$PROGRAM_NAME: Value \"$mobile\" from file $rc doesn't look like a mobile number.\n"; chomp( $password = <$file> ); close $file or die "$PROGRAM_NAME: error closing file: $OS_ERROR\n"; ## Get the list of recipients scalar @ARGV >= 1 or pod2usage(1); $recipients = join q{,}, map { /^(\d{6,})$/ or die "$PROGRAM_NAME: Argument \"$_\" is not a phone number.\n"; $1 } @ARGV; ## Get the text of the message, starting with the option $message = defined( $opt{message} ) ? clean( $opt{message} ) : q{}; if ( $opt{stdin} ) { while ( read STDIN, my $buffer, $opt{maxchars} ) { $message .= clean( $buffer ); last if length $message >= $opt{maxchars}; } } ## Check the length if ( length $message > $opt{maxchars} ) { $opt{truncate} or die "$PROGRAM_NAME: your message exceeds $opt{maxchars} characters. Consider --maxchars or --truncate options.\n"; $message = substr( $message, 0, $opt{maxchars} ); } ## Is this for real? if ( $opt{test} ) { print 'Message is ', length $message, " characters:\n$message\n"; exit; } return $mobile, $password, $recipients, $message, $opt{debug}; } ## Filter a message fragment sub clean { my ($string) = @_; $string =~ s/[^[:print:][:space:]]+//go; # Only allow safe characters $string =~ s/[[:space:]]+/ /go; # Squash duplicate spaces return $string; } ## Send the message immediately sub send_sms_now { my ( $mobile, $password, $recipients, $message, $debug ) = @_; eval { ## Ready the Mechanize UserAgent for use my $mech = WWW::Mechanize->new( autocheck => 1, keep_alive => undef, timeout => 30 ); $mech->agent_alias('Windows Mozilla'); ## Add debugging handlers if ($debug) { $mech->add_handler( "request_send", sub { shift->dump( maxlength => 0 ); return } ); $mech->add_handler( "response_done", sub { shift->dump( maxlength => 0 ); return } ); } ## Login $mech->get('http://www.optuszoo.com.au/login'); $mech->content =~ m{ Log \s on \s to \s myZoo }msix or die "get login page failed\n"; $mech->submit_form( form_id => 'login_form', fields => { j_username => $mobile, j_password => $password } ); $mech->content =~ m{ Welcome .+? Sign \s Out }msix or die "login failed\n"; ## Send our SMS $mech->get('http://msc.optuszoo.com.au/smssend'); $mech->content =~ m{ Send \s SMS \s via \s the \s web }msix or die "get smssend page failed\n"; $mech->submit_form( form_id => 'smssend', fields => { recipient => $recipients, message => $message } ); $mech->content =~ m{ SMS \s has \s successfully \s been \s delivered }msix or die "SMS may not have been sent\n"; ## Logout $mech->get('http://www.optuszoo.com.au/logout'); 1; } or do { ## Report any errors from inside the eval { }; chomp $EVAL_ERROR; die "$PROGRAM_NAME: $EVAL_ERROR - Manually login to http://www.optuszoo.com.au/ and check.\n"; }; return; } __END__ =head1 NAME optus-websms - send a SMS using Optus' http://www.optuszoo.com.au/ website =head1 SYNOPSIS echo message | optus-websms B =head1 ARGUMENTS =over 8 =item B Arguments should contain only digits. No spaces, hyphens or other punctuation should be used. You may give several mobile numbers. The Optus Web SMS allows sending to many networks, including Optus, Telstra, Orange and Vodafone within Australia and many networks outside Australia. See http://www.optuszoo.com.au/ for more details. =item B The message is accepted from standard input and/or from the B<--message> option and is then filtered: =over 8 =item Only printable characters and spaces are accepted =item Repeated spaces are suppressed. =item Other characters are silently ignored. =back =back =head1 OPTIONS =over 8 =item B<--message=B> Use the provided string as the message. Anything from standard input will be placed after this string (unless B<--no-stdin> is given). =item B<--no-stdin> Ignore standard input completely. =item B<--maxchars>=B<> The maximum number of characters in the message. The default of 160 is the common size for a single SMS "segment". Larger numbers are supported by the Optus Web SMS; however, they may incur higher charges and/or result in multiple SMSes. =item B<--truncate> Silently trucate the message at the maximum length rather then exiting with an error message. =item B<--test> Don't send the message, just display the character count and the message as it would have been sent. =item B<--rc=B> Use the named files for our config. See B below. =item B<--version> Print the version string and exit. =item B<--man> Print the manual page and exit. =item B<--help> Print a brief help message and exit. =back =head1 DESCRIPTION B is a simple interface to the Optus Web SMS service available to authorized users from the http://www.optuszoo.com.au/ website. The Optus Web SMS service has Terms and Conditions and you should understand these before your configure this tool to use your account. =head1 EXIT CODES B will exit with a zero exit status upon success. No output is produced on stdout. B will exit with a non-zero exit status if there was an error, with details on standard error. =head1 FILES If no file is given with the B<--rc> option, the following locations are checked (in order) and the first match is used. =over 8 =item B<$HOME/.optus-websmsrc> =item B =item B =back This two line file must contain your phone number (all digits, no spaces) on the first line and your password (accepted as-is) on the second line. =head1 EXAMPLES Send a congratulatory message to the author: echo Congratulations, Mark | optus-websms 0411262316 Same as above, but using --message option: optus-websms --message "Congratulations, Mark" 0411262316 Announce a meeting to a three phones: echo Meeting at 2pm in room 42 | optus-websms 0411111111 0422222222 0433333333 Report a disk space problem to the sysadmin, with part of the df output, truncated to fit in a single SMS: df | optus-websms --truncate --message "Space low: " 0411111111 See what that message would look like: df | optus-websms --test --truncate --message "Space low: " 0411111111 =head1 SEE ALSO http://www.optuszoo.com.au/ =head1 THANKS =over 8 =item Brian Meilak Very good suggestions for improving this documentation. =item AusCERT staff Several features, including the --message and ---rc options. =item Garth Douglass Updates to the script when Optus changed their site. =item Indy Siva Updates to the script when Optus changed their site. =back =head1 AUTHOR Mark Suter EFE =head1 LICENSE AND COPYRIGHT Copyright (C) 2003,2011 Mark Suter EFE This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see L. =cut