File Coverage

blib/lib/SMS/Send/DE/Sipgate.pm
Criterion Covered Total %
statement 11 13 84.6
branch n/a
condition n/a
subroutine 5 5 100.0
pod n/a
total 16 18 88.8


line stmt bran cond sub pod time code
1             package SMS::Send::DE::Sipgate;
2             BEGIN {
3 1     1   25879 $SMS::Send::DE::Sipgate::VERSION = '0.03';
4             }
5             # ABSTRACT: SMS::Send driver to send via sipgate.de
6              
7 1     1   8 use strict;
  1         2  
  1         30  
8 1     1   5 use warnings;
  1         2  
  1         23  
9              
10 1     1   899 use HTTP::Cookies;
  1         14187  
  1         30  
11 1     1   456 use XMLRPC::Lite;
  0            
  0            
12              
13             use parent qw(SMS::Send::Driver);
14              
15             =head1 NAME
16              
17             SMS::Send::DE::Sipgate - An SMS::Send driver for the sipgate.de service.
18              
19             =head1 VERSION
20              
21             version 0.03
22              
23             =head1 SYNOPSIS
24              
25             # create the sender object
26             my $sender = SMS::Send::->new('DE::Sipgate',
27             _login => '123',
28             _password => '456',
29             );
30             # send a message
31             my $sent = $sender->send_sms(
32             text => 'You message may use up to 160 chars',
33             to' => '0555 4444', # only german numbers allowed for this driver
34             );
35            
36             if ( $sent ) {
37             print "Sent message\n";
38             } else {
39             print "Failed to send test message\n";
40             }
41            
42             =head1 DESCRIPTION
43              
44             L<SMS::Send::DE::Sipgate> is an regional L<SMS::Send> driver for
45             the Sipgate.de service.
46              
47             =head2 Preparing to use this driver
48              
49             You need to sign-up on L<http://www.sipgate.de> and get an Account as well
50             as a local number.
51              
52             =head2 Disclaimer
53              
54             The authors of this driver take no responibility for any cost accured on your bill
55             by using this module.
56              
57             Using this driver will cost you money. B<YOU HAVE BEEN WARNED>
58              
59             =head1 METHODS
60              
61             =head2 new
62              
63             # Create new sender using this driver.
64             my $sender = SMS::Send::->new(
65             'DE::Sipgate',
66             _login => '123',
67             _password => '456',
68             );
69            
70             The C<new> constructor takes two parameter, which should be passed
71             throuh from the L<SMS::Send> constructor.
72              
73             =over
74              
75             =item _login
76              
77             The C<_login> param is your sipgate.de username.
78              
79             =item _password
80              
81             The C<_password> param is your sipgate.de password.
82              
83             Returns a new C<SMS::Send::DE::Sipgate> object, or dies on error.
84              
85             =back
86              
87             =cut
88              
89             sub new {
90             my $class = shift;
91             my %params = @_;
92             exists $params{_login}
93             or die $class."->new requires _login parameter\n";
94             exists $params{_password}
95             or die $class."->new requires _password parameter\n";
96             exists $params{_verbose}
97             or $params{_verbose} = 1;
98             my $self = \%params;
99             bless $self, $class;
100            
101             $self->{_url} = 'https://'.$self->{_login}.':'.$self->{_password}.'@samurai.sipgate.net/RPC2';
102             $self->{_cookies} = HTTP::Cookies::->new( ignore_discard => 1, );
103             return $self;
104             }
105              
106             =head2 client
107              
108             Lazy initialization of the XMLRPC client.
109              
110             =cut
111              
112             sub client {
113             my $self = shift;
114            
115             if(!$self->{_client}) {
116             $self->{_client} = $self->_init_client();
117             }
118            
119             return $self->{_client};
120             }
121              
122             sub _init_client {
123             my $self = shift;
124              
125             my $Client = XMLRPC::Lite::->proxy( $self->{_url} );
126             $Client->transport()->cookie_jar( $self->{_cookies} );
127             if ( $Client->transport()->can('ssl_opts') ) {
128             $Client->transport()->ssl_opts( verify_hostname => 0, );
129             }
130            
131             my $resp = $Client->call(
132             'samurai.ClientIdenfity',
133             {
134             'ClientName' => 'SMS::Send::DE::Sipgate',
135             'ClientVersion' => '0.1',
136             'ClientVendor' => 'CPAN',
137             }
138             );
139             # ignore the result of this call since it seems not to be essential
140              
141             return $Client;
142             }
143              
144             =head2 responses
145              
146             List all known response codes with their explaination.
147              
148             =cut
149              
150             sub responses {
151             my $self = shift;
152            
153             if(!$self->{_responses}) {
154             $self->{_responses} = $self->_init_responses();
155             }
156            
157             return $self->{_responses};
158             }
159              
160             sub _init_responses {
161             my $self = shift;
162            
163             # see http://www.sipgate.de/beta/public/static/downloads/basic/api/sipgate_api_documentation.pdf, page 30ff.
164             my $resp_ref = {
165             '200' => 'Method success',
166             '400' => 'Method not supported',
167             '401' => 'Request denied (no reason specified)',
168             '402' => 'Internal error',
169             '403' => 'Invalid arguments',
170             '404' => 'Resources exceeded',
171             '405' => 'Invalid parameter name',
172             '406' => 'Invalid parameter type',
173             '407' => 'Invalid parameter value',
174             '408' => 'Attempt to set a non-writable parameter',
175             '409' => 'Notification request denied',
176             '410' => 'Parameter exceeds maximum size',
177             '411' => 'Missig parameter',
178             '412' => 'Too many requests',
179             '500' => 'Date out of range',
180             '501' => 'URI does not belong to user',
181             '502' => 'Unknown type of service',
182             '503' => 'Selected payment method failed',
183             '504' => 'Selected currecy not supported',
184             '505' => 'Amount exceeds limit',
185             '506' => 'Malformed SIP URI',
186             '507' => 'URI not in list',
187             '508' => 'Format is not valid E.164',
188             '509' => 'Unknown status',
189             '510' => 'Unknown ID',
190             '511' => 'Invalid timevalue',
191             '512' => 'Referenced session not found',
192             '513' => 'Only single value per TOS allowed',
193             '514' => 'Malformed VCARD format',
194             '515' => 'Malformed PID format',
195             '516' => 'Presence information not available',
196             '517' => 'Invalid label name',
197             '518' => 'Label not assigned',
198             '519' => "Label doesn't exist",
199             '520' => 'Parameter includes invalid characters',
200             '521' => 'Bad password. (Rejected due to security concerns)',
201             '522' => 'Malformed timezone format',
202             '523' => 'Delay exceeds limit',
203             '524' => 'Requested VPN type not available',
204             '525' => 'Requested TOS not available',
205             '526' => 'Unified messaging not available',
206             '527' => 'URI not available for registration',
207             };
208             for my $i (900 .. 999) {
209             $resp_ref->{$i} = 'Vendor defined status code';
210             }
211            
212             return $resp_ref;
213             }
214              
215             =head2 send_sms
216              
217             Send an SMS. See L<SMS::Send> for the details.
218              
219             =cut
220              
221             sub send_sms {
222             my $self = shift;
223             my %params = @_;
224            
225             my $destination = $self->_clean_number($params{'to'});
226             my $message = substr($params{'text'},0,159);
227            
228             my $resp = $self->client()->call(
229             'samurai.SessionInitiate',
230             {
231             'RemoteUri' => 'sip:'.$destination.'@sipgate.net',
232             'TOS' => 'text',
233             'Content' => $message,
234             }
235             );
236             my $result = $resp->result();
237            
238             if($result && $result->{'StatusCode'} == 200) {
239             print 'Sent '.$message.' to '.$destination."\n" if $self->{_verbose};
240             return 1;
241             } else {
242             my $errstr = $result->{'StatusCode'};
243             if($self->responses()->{$result->{'StatusCode'}}) {
244             $errstr .= ' ('.$result->responses()->{$result->{'StatusCode'}}.')';
245             }
246             $errstr .= ' - '.$result->{'StatusString'};
247             warn 'Failed to send '.$message.' to '.$destination.'. Error: '.$errstr if $self->{_verbose};
248             return;
249             }
250             }
251              
252             sub _clean_number {
253             my $self = shift;
254             my $number = shift;
255            
256             # strip all non-number chars
257             $number =~ s/\D//g;
258             # make sure to use the country prefix for germany
259             $number =~ s/^01/491/;
260             # never prefix country with 00
261             $number =~ s/^00491/491/;
262            
263             return $number;
264             }
265              
266             =head1 AUTHOR
267              
268             Dominik Schulz, C<< <dominik.schulz at gauner.org> >>
269              
270             =head1 BUGS
271              
272             Please report any bugs or feature requests to C<bug-sms-send-de-sipgate at rt.cpan.org>, or through
273             the web interface at L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=SMS-Send-DE-Sipgate>. I will be notified, and then you'll
274             automatically be notified of progress on your bug as I make changes.
275              
276              
277              
278              
279             =head1 SUPPORT
280              
281             You can find documentation for this module with the perldoc command.
282              
283             perldoc SMS::Send::DE::Sipgate
284              
285              
286             You can also look for information at:
287              
288             =over 4
289              
290             =item * RT: CPAN's request tracker
291              
292             L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=SMS-Send-DE-Sipgate>
293              
294             =item * AnnoCPAN: Annotated CPAN documentation
295              
296             L<http://annocpan.org/dist/SMS-Send-DE-Sipgate>
297              
298             =item * CPAN Ratings
299              
300             L<http://cpanratings.perl.org/d/SMS-Send-DE-Sipgate>
301              
302             =item * Search CPAN
303              
304             L<http://search.cpan.org/dist/SMS-Send-DE-Sipgate/>
305              
306             =back
307              
308              
309             =head1 ACKNOWLEDGEMENTS
310              
311              
312             =head1 LICENSE AND COPYRIGHT
313              
314             Copyright 2012 Dominik Schulz.
315              
316             This program is free software; you can redistribute it and/or modify it
317             under the terms of either: the GNU General Public License as published
318             by the Free Software Foundation; or the Artistic License.
319              
320             See http://dev.perl.org/licenses/ for more information.
321              
322              
323             =cut
324              
325             1; # End of SMS::Send::DE::Sipgate