File Coverage

blib/lib/SMS/Send/AU/MyVodafone.pm
Criterion Covered Total %
statement 38 85 44.7
branch 6 34 17.6
condition 6 12 50.0
subroutine 10 14 71.4
pod 2 2 100.0
total 62 147 42.1


line stmt bran cond sub pod time code
1             package SMS::Send::AU::MyVodafone;
2              
3             =pod
4              
5             =head1 NAME
6              
7             SMS::Send::AU::MyVodafone - An SMS::Send driver for the myvodafone.com.au website
8              
9             =head1 SYNOPSIS
10              
11             # Get the sender and login
12             my $sender = SMS::Send->new('AU::MyVodafone',
13             _login => '04 444 444', # Whitespace is ignored
14             _password => 'abcdefg',
15             );
16            
17             # Send a message to ourself
18             my $sent = $sender->send_sms(
19             text => 'Messages have a limit of 160 chars',
20             to => '+61 4 444 444',
21             );
22            
23             # Did it send?
24             if ( $sent ) {
25             print "Sent test message\n";
26             } else {
27             print "Test message failed\n";
28             }
29              
30             =head1 DESCRIPTION
31              
32             L is an regional L driver for
33             Australia that delivers messages via the L
34             website Web2TXT feature.
35              
36             Using your phone number as a login, and your existing password, this
37             driver allows any Australian with a Vodafone to send SMS messages (with
38             the message cost added to your account).
39              
40             =head2 Preparing to Use This Driver
41              
42             As well as setting up your myvodfone.com.au account and password, the
43             Web2TXT feature requires acceptance of an additional disclaimer and
44             conditions of use form.
45              
46             You C manually accept this disclaimer and conditions before you
47             will be able to use this driver.
48              
49             While we certainly could make the driver do it for you, acceptance
50             of the terms of use implies you understand the cost structure and
51             rules surrounding the use of the Web2TXT feature.
52              
53             =head2 Disclaimer
54              
55             Other than dieing on encountering the terms of use form, no other
56             protection is provided, and the authors of this driver take no
57             responsibility for any costs accrued on your phone bill by using
58             this module.
59              
60             Using this driver will cost you money. B
61              
62             =head1 METHODS
63              
64             =cut
65              
66 2     2   39560 use 5.006;
  2         6  
  2         77  
67 2     2   47 use strict;
  2         5  
  2         65  
68 2     2   22 use SMS::Send::Driver ();
  2         3  
  2         26  
69 2     2   2688 use WWW::Mechanize ();
  2         396888  
  2         64  
70              
71 2     2   24 use vars qw{$VERSION @ISA};
  2         5  
  2         167  
72             BEGIN {
73 2     2   6 $VERSION = '1.04';
74 2         1935 @ISA = 'SMS::Send::Driver';
75             }
76              
77             # Starting URI
78             my $START = 'https://www.myvodafone.com.au/knox/login_handler.jsp';
79             my $FORM = 'https://www.myvodafone.com.au/yrweb2txt/enter.do';
80              
81             # Detection regexs
82             my $RE_BADLOGIN = qr/Sorry you have entered an incorrect username or password/;
83              
84              
85              
86              
87              
88             #####################################################################
89             # Constructor
90              
91             =pod
92              
93             =head2 new
94              
95             # Create a new sender using this driver
96             my $sender = SMS::Send->new(
97             _login => '04 444 444',
98             _password => 'abcdefg',
99             );
100              
101             The C constructor takes two parameters, which should be passed
102             through from the L constructor.
103              
104             The params are driver-specific for now, until L adds a standard
105             set of params for specifying the login and password.
106              
107             =over
108              
109             =item _login
110              
111             The C<_login> param should be your phone number. That is, the phone to send
112             from and to be billed to for the messages.
113              
114             The login should be an Australian-format number. That is, starting with
115             zero-four "04".
116              
117             =item _password
118              
119             The C<_password> param should be your myvodafone.com.au password.
120              
121             =back
122              
123             During construction, the driver will actively log in to the
124             myvodafone.com.au website using the credentials provided, to verify
125             they are correct.
126              
127             It will not check for your acceptance of the terms and conditions at
128             this point. That is done at C-time.
129              
130             Returns a new C object, or dies on error.
131              
132             =cut
133              
134             sub new {
135 2     2 1 801 my $class = shift;
136 2         9 my %params = @_;
137              
138             # Get the login
139 2         10 my $login = $class->_LOGIN ( delete $params{_login} );
140 1         5 my $password = $class->_PASSWORD( delete $params{_password} );
141              
142             # Create our mechanise object
143 1         11 my $mech = WWW::Mechanize->new;
144              
145             # Create the object, saving any private params for later
146 1         24041 my $self = bless {
147             mech => $mech,
148             login => $login,
149             password => $password,
150             private => \%params,
151              
152             # State variables
153             logged_in => '',
154             }, $class;
155              
156 1         6 $self;
157             }
158              
159             sub _get_login {
160 1     1   1737 my $self = shift;
161              
162             # Get to the login form
163 1         8 $self->{mech}->get( $START );
164 0 0       0 unless ( $self->{mech}->success ) {
165 0         0 Carp::croak("HTTP Error: Failed to connect to MyVodafone website");
166             }
167              
168 0         0 return 1;
169             }
170              
171             sub _send_login {
172 0     0   0 my $self = shift;
173              
174             # Shortcut if logged in
175 0 0       0 return 1 if $self->{logged_in};
176              
177             # Get to the login page
178 0         0 $self->_get_login;
179              
180             # Submit the login form
181 0         0 $self->{mech}->submit_form(
182             form_name => 'loginForm',
183             fields => {
184             txtUserID => $self->{login},
185             txtPassword => $self->{password},
186             btnLogin => 'submit',
187             },
188             );
189              
190             # Did we login?
191 0 0       0 if ( $self->{mech}->content =~ $RE_BADLOGIN ) {
192 0         0 Carp::croak("Invalid login and password");
193             }
194              
195 0         0 $self->{logged_in} = 1;
196 0         0 return 1;
197             }
198              
199             sub send_sms {
200 0     0 1 0 my $self = shift;
201 0         0 my %params = @_;
202              
203             # Get the message and destination
204 0         0 my $message = $self->_MESSAGE( delete $params{text} );
205 0         0 my $recipient = $self->_TO ( delete $params{to} );
206              
207             # Make sure we are logged in
208 0         0 $self->_send_login;
209              
210             # Get to the Web2TXT form
211 0         0 $self->{mech}->get( $FORM );
212 0 0       0 unless ( $self->{mech}->content =~ /Compose a message/ ) {
213 0         0 Carp::croak("Could not locate the SMS send form");
214             }
215              
216             # Fill out the message form
217 0 0       0 my $form = $self->{mech}->form_name('sendMessageForm')
218             or Carp::croak("Failed to find sendMessageForm on message page");
219 0         0 $form->push_input('text', {
220             name => 'recipients',
221             value => "adhoc$recipient",
222             } );
223 0         0 $form->value( messageBody => $message );
224              
225             # Hack some values otherwise changed by JavaScript.
226             # Disable warnings when changing hidden inputs.
227 0         0 SCOPE: {
228 0         0 local $^W = 0;
229 0         0 $form->value( action => 'send' );
230 0         0 $form->value( counter => 160 - length($message) );
231 0         0 $form->value( msg_counter => 1 );
232 0         0 $form->value( totalMsgs => 1 );
233             }
234              
235             # Send the form
236 0         0 $self->{mech}->submit();
237 0 0       0 unless ( $self->{mech}->success ) {
238 0         0 Carp::croak("HTTP request returned failure when sending SMS request");
239             }
240              
241             # Fire-and-forget, we don't know for sure.
242 0         0 return 1;
243             }
244              
245              
246              
247              
248              
249             #####################################################################
250             # Support Functions
251              
252             sub _LOGIN {
253 2 50   2   7 my $class = ref $_[0] ? ref shift : shift;
254 2         4 my $number = shift;
255 2 50 66     22 unless ( defined $number and ! ref $number and length $number ) {
      66        
256 1         258 Carp::croak("Did not provide a login number");
257             }
258 1         7 $number =~ s/\s//g;
259 1 50       6 unless ( $number =~ /^04\d{8}$/ ) {
260 0         0 Carp::croak("Login must be a 10-digit number starting with 04");
261             }
262 1         4 return $number;
263             }
264              
265             sub _PASSWORD {
266 1 50   1   4 my $class = ref $_[0] ? ref shift : shift;
267 1         3 my $password = shift;
268 1 50 33     12 unless ( defined $password and ! ref $password and length $password ) {
      33        
269 0         0 Carp::croak("Did not provide a password");
270             }
271 1 50       4 unless ( length($password) >= 5 ) {
272 0         0 Carp::croak("Password must be at least 5 characters");
273             }
274 1         3 return $password;
275             }
276              
277             sub _MESSAGE {
278 0 0   0     my $class = ref $_[0] ? ref shift : shift;
279 0           my $message = shift;
280 0 0         unless ( length($message) <= 160 ) {
281 0           Carp::croak("Message length limit is 160 characters");
282             }
283 0           return $message;
284             }
285              
286             sub _TO {
287 0 0   0     my $class = ref $_[0] ? ref shift : shift;
288 0           my $to = shift;
289              
290             # International numbers need their + removed
291 0 0         if ( $to =~ s/^\+// ) {
292 0           return $to;
293             }
294              
295             # Domestic numbers start with 04
296 0 0         unless ( $to =~ /^04\d{8}$/ ) {
297 0           Carp::croak("Regional number is not an Australian mobile phone number");
298             }
299              
300 0           return $to;
301             }
302              
303             1;
304              
305             =pod
306              
307             =head1 SUPPORT
308              
309             Bugs should be reported via the CPAN bug tracker at
310              
311             L
312              
313             For other issues, contact the author.
314              
315             =head1 AUTHOR
316              
317             Adam Kennedy Eadamk@cpan.orgE
318              
319             =head1 COPYRIGHT
320              
321             Copyright 2005 - 2008 Adam Kennedy.
322              
323             This program is free software; you can redistribute
324             it and/or modify it under the same terms as Perl itself.
325              
326             The full text of the license can be found in the
327             LICENSE file included with this module.
328              
329             Additionally, you are again reminded that this software comes with
330             no warranty of any kind, including but not limited to the implied
331             warranty of merchantability.
332              
333             ANY use of this module may result in charges on your phone bill,
334             and you should use this software with care. The author takes no
335             responsibility for any such charges accrued.
336              
337             =cut