#!/usr/bin/perl -w use strict; use HTML::Form; use HTML::Entities; use HTTP::Request; use LWP; use Getopt::Long; use Data::Dumper; my $username; my $password; my $contacts = 0; my $message; my @recipients = (); my $DELAY = 1; if ($^O eq "darwin") { # Log in once to webtext under safari and this will work # you need to allow the security program to access the keychain open(IN, "security find-internet-password -g -s www.vodafone.ie -r htps 2>&1 |") || die "$!"; while() { if (m/"acct"="(.*)"/) { $username = $1; } if (m/password: "(.*)"/) { $password = $1; } } close(IN); } else { my $rcfile=$ENV{HOME} . "/.webtextrc"; if (-f $rcfile) { if (open(IN, "<$rcfile")) { while() { chomp; if (m/username=(.*)/) { $username = $1; } if (m/password=(.*)/) { $password = $1; } } close(IN); } } } # use something else, or program the passwords here $username="username" if (!defined($username)); $password="password" if (!defined($password)); die "Please configure the username and password" if ($username eq "username"); my $webtext_url="https://www.vodafone.ie/myv/messaging/webtext/index.jsp"; sub usage { print "$0 [-c] [-t [-t ...] Message]\n"; exit 0 } my $result = GetOptions("to|t=s" => \@recipients, "contacts|c" => \$contacts); usage() if ($contacts == 0) && ((scalar(@recipients) == 0) || (scalar(@recipients) > 5) || (scalar(@ARGV) == 0)); $message = join(" ", @ARGV); if (length($message) > 160) { die "Message too long.\n Shorten to: \"" . substr($message, 0, 160) . "\""; } my $ua = LWP::UserAgent->new; push @{ $ua->requests_redirectable }, 'POST'; $ua->cookie_jar({ }); $ua->agent('Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en) AppleWebKit/523.10.3 (KHTML, like Gecko) Version/3.0.4 Safari/523.10'); my $response = $ua->get($webtext_url); #print Dumper($response); my @forms = HTML::Form->parse($response->content, $response->base); my $form = undef; foreach (@forms) { if (defined($_->{'attr'}) && lc($_->{'attr'}{'name'}) eq "login") { $form=$_; } } die "Could not get Login Form" unless $form; $form->value('username', $username); $form->value('password', $password); $response = $ua->request($form->click); die "Login Failed" if (!$response->is_success || $response->base =~ /Login.shtml/); $response->as_string() =~ /emaining messages this month.*>(\d+)as_string() . " Couldn't determine number of remaining texts"; my $remaining = $1; #print Dumper($response); @forms = HTML::Form->parse($response->content, $response->base); $form = undef; foreach (@forms) { if (defined($_->{'attr'}) && lc($_->{'attr'}{'name'}) eq "webtext") { $form=$_; } } die "Could not get Webtext Form" unless $form; sub trim($) { my $string = shift; $string =~ s/^\s+//; $string =~ s/\s+$//; return $string; } # walk the label for=... -> form id=... matches my %chk_labels; my %address_book; my %lc_address_book; %chk_labels = $response->content =~ m/label for="chk_box_(\d*)">([^<]*)find_input("chk_box_$_"); my $name = trim(decode_entities($chk_labels{$_})); $address_book{$name} = $iv->{menu}[1]{'value'}; $lc_address_book{lc($name)} = $iv->{menu}[1]{'value'}; } if ($contacts == 1) { foreach(sort(keys(%address_book))) { print "$_ on " . $address_book{$_} . "\n"; } exit (0); } $form->value('message', $message); my $i = 0; print "Sending: $message to "; foreach (@recipients) { my $phone = $_; if (!($phone =~ /^[0-9]/)) { $phone = $lc_address_book{lc($phone)}; } $form->value("recipients[$i]", $phone); print $phone . " "; $i++; } print "\n"; sleep($DELAY); $response = $ua->request($form->click); die "Message was not sent correctly" . Dumper($response) if (!($response->as_string() =~ /Your message was sent to:/)); $response = $ua->get($webtext_url); $response->as_string() =~ /emaining messages this month.*>(\d+)as_string() . " Couldn't determine number of remaining texts"; if ($remaining == $1) { die "Even though the message was sent, the number of available messages didn't reduce"; } print "Remaining Messages: $1\n"; exit 0