File Coverage

blib/lib/WWW/Namecheap/API.pm
Criterion Covered Total %
statement 19 21 90.4
branch n/a
condition n/a
subroutine 7 7 100.0
pod n/a
total 26 28 92.8


line stmt bran cond sub pod time code
1             package WWW::Namecheap::API;
2              
3 11     11   295977 use 5.006;
  11         48  
  11         463  
4 11     11   64 use strict;
  11         24  
  11         395  
5 11     11   60 use warnings;
  11         25  
  11         319  
6 11     11   59 use Carp();
  11         21  
  11         216  
7 11     11   12424 use LWP::UserAgent ();
  11         623822  
  11         338  
8 11     11   126 use URI::Escape;
  11         25  
  11         978  
9 11     11   18248 use XML::Simple;
  0            
  0            
10              
11             # For convenience methods
12             use WWW::Namecheap::Domain ();
13             use WWW::Namecheap::DNS ();
14              
15             =head1 NAME
16              
17             WWW::Namecheap::API - Perl interface to the Namecheap API
18              
19             =cut
20              
21             our $VERSION = '0.05';
22             our %APIURL = (
23             prod => 'https://api.namecheap.com/xml.response',
24             test => 'https://api.sandbox.namecheap.com/xml.response',
25             );
26              
27             =head1 SYNOPSIS
28              
29             Perl interface to the Namecheap API. API details at:
30              
31             https://www.namecheap.com/support/api/api.aspx
32              
33             Actual API calls happen in the other modules in the distribution, which
34             can be accessed via convenience methods from an API object. Brief
35             example:
36              
37             use WWW::Namecheap::API;
38            
39             my $api = WWW::Namecheap::API->new(
40             System => 'test',
41             ApiUser => 'wwwnamecheapapi',
42             ApiKey => 'keyhere',
43             DefaultIp => '1.2.3.4',
44             );
45            
46             my $result = $api->domain->check(Domains => ['example.com']);
47            
48             if ($result->{'example.com'}) {
49             $api->domain->create(
50             DomainName => 'example.com',
51             Years => 1,
52             Registrant => {
53             OrganizationName => 'Foo Bar Inc.',
54             FirstName => 'Joe',
55             LastName => 'Manager',
56             Address1 => '123 Fake Street',
57             City => 'Univille',
58             StateProvince => 'SD',
59             PostalCode => '12345',
60             Country => 'US',
61             Phone => '+1.2125551212',
62             EmailAddress => 'joe@example.com',
63             },
64             );
65             }
66              
67             =head1 GLOBAL PARAMETERS
68              
69             There are a few parameters that can be included in any of the individual
70             methods within the Namecheap API modules. These are listed below.
71              
72             =head2 ClientIp
73              
74             The client IP address for which this request is effective. If a DefaultIp
75             was not provided when setting up the parent API object, this parameter
76             is required, otherwise it is optional.
77              
78             =head2 UserName
79              
80             A sub-user (see L) under which the command should
81             be performed. A DefaultUser may be specified at API object creation
82             time; if one is not specified there, the default is to use the ApiUser
83             unless a UserName is provided for the specific command being issued.
84              
85             =head1 SUBROUTINES/METHODS
86              
87             =head2 WWW::Namecheap::API->new(%hash)
88              
89             Instantiate a new API object. Example:
90              
91             my $api = WWW::Namecheap::API->new(
92             System => 'test', # or 'prod' for production, default test
93             ApiUser => 'username',
94             ApiKey => 'apikey',
95             DefaultIp => '1.2.3.4', # optional
96             DefaultUser => 'otheruser', #optional, default ApiUser
97             ApiUrl => 'https://foo.bar/', # overrides URL chosen by System
98             Agent => 'My API Agent/1.0', # optional, overrides default UA
99             );
100              
101             Only ApiUser and ApiKey are required, in which case System will default
102             to 'test' and Agent defaults to 'WWW::Namecheap::API/$VERSION'. This
103             API object will be passed to the constructors of the other classes in
104             the distribution (or you can use its built-in convenience methods to
105             get objects of those classes directly).
106              
107             =cut
108              
109             sub new {
110             my $class = shift;
111            
112             my $params = _argparse(@_);
113            
114             for (qw(ApiUser ApiKey)) {
115             Carp::croak("${class}->new(): Mandatory parameter $_ not provided.") unless $params->{$_};
116             }
117            
118             my $ua = LWP::UserAgent->new(
119             agent => $params->{'Agent'} || "WWW::Namecheap::API/$VERSION",
120             );
121            
122             my $apiurl;
123             if ($params->{'ApiUrl'}) {
124             $apiurl = $params->{'ApiUrl'}; # trust the user?!?!
125             } else {
126             if ($params->{'System'}) {
127             $apiurl = $APIURL{$params->{'System'}};
128             } else {
129             $apiurl = $APIURL{'test'};
130             }
131             }
132            
133             my $self = {
134             ApiUrl => $apiurl,
135             ApiUser => $params->{'ApiUser'},
136             ApiKey => $params->{'ApiKey'},
137             DefaultUser => $params->{'DefaultUser'} || $params->{'ApiUser'},
138             DefaultIp => $params->{'DefaultIp'},
139             _ua => $ua,
140             };
141            
142             return bless($self, $class);
143             }
144              
145             =head2 $api->request(%hash)
146              
147             Send a request to the Namecheap API. Returns the XML response parsed into
148             Perl form by XML::Simple. Intended for use by sub-classes, not outside
149             calls. Parameters should be of the type and quantity required by the
150             Namecheap API for the given Command. Example:
151              
152             my $xml = $api->request(
153             Command => 'namecheap.domains.check',
154             DomainList => 'example.com,example2.net',
155             ClientIp => '1.2.3.4', # required if no DefaultIp in $api
156             );
157              
158             =cut
159              
160             sub request {
161             my $self = shift;
162             my %reqparams = @_;
163            
164             unless ($reqparams{'Command'}) {
165             Carp::carp("No command specified, bailing!");
166             return;
167             }
168            
169             my $clientip = delete($reqparams{'ClientIp'}) || $self->{'DefaultIp'};
170             unless ($clientip) {
171             Carp::carp("No Client IP or default IP specified, cannot perform request.");
172             return;
173             }
174             my $username = delete($reqparams{'UserName'}) || $self->{'DefaultUser'};
175            
176             map { delete($reqparams{$_}) unless defined($reqparams{$_}) } keys %reqparams;
177            
178             my $ua = $self->{_ua}; # convenience
179             my $url = sprintf('%s?ApiUser=%s&ApiKey=%s&UserName=%s&Command=%s&ClientIp=%s&',
180             $self->{'ApiUrl'}, $self->{'ApiUser'}, $self->{'ApiKey'},
181             $username, delete($reqparams{'Command'}), $clientip);
182             $url .= join('&', map { join('=', map { uri_escape($_) } each %reqparams) } keys %reqparams);
183             #print STDERR "Sent URL $url\n";
184             my $response = $ua->get($url);
185            
186             unless ($response->is_success) {
187             Carp::carp("Request failed: " . $response->message);
188             return;
189             }
190            
191             my $xml = XMLin($response->content);
192            
193             if ($xml->{Status} eq 'ERROR') {
194             $self->{_error} = $xml;
195             return;
196             }
197             return $xml;
198             }
199              
200             =head2 $api->domain()
201              
202             Helper method to create and return a WWW::Namecheap::Domain object utilizing
203             this API object. Always returns the same object within a given session via
204             internal caching.
205              
206             =cut
207              
208             sub domain {
209             my $self = shift;
210            
211             if ($self->{_domain}) {
212             return $self->{_domain};
213             }
214            
215             return $self->{_domain} = WWW::Namecheap::Domain->new(API => $self);
216             }
217              
218             =head2 $api->dns()
219              
220             Helper method to create and return a WWW::Namecheap::DNS object utilizing
221             this API object. Always returns the same object within a given session via
222             internal caching.
223              
224             =cut
225              
226             sub dns {
227             my $self = shift;
228            
229             if ($self->{_dns}) {
230             return $self->{_dns};
231             }
232            
233             return $self->{_dns} = WWW::Namecheap::DNS->new(API => $self);
234             }
235              
236             =head2 $api->error()
237              
238             Returns the full XML response from the API if an error occurred during
239             the request. Most likely key of interest is $xml->{Errors} and below.
240              
241             =cut
242              
243             sub error {
244             return $_[0]->{_error};
245             }
246              
247             sub _argparse {
248             my $hashref;
249             if (@_ % 2 == 0) {
250             $hashref = { @_ }
251             } elsif (ref($_[0]) eq 'HASH') {
252             $hashref = \%{$_[0]};
253             }
254             return $hashref;
255             }
256              
257             =head1 AUTHOR
258              
259             Tim Wilde, C<< >>
260              
261             =head1 BUGS
262              
263             Please report any bugs or feature requests to C, or through
264             the web interface at L. I will be notified, and then you'll
265             automatically be notified of progress on your bug as I make changes.
266              
267              
268              
269             =head1 SUPPORT
270              
271             You can find documentation for this module with the perldoc command.
272              
273             perldoc WWW::Namecheap::API
274              
275              
276             You can also look for information at:
277              
278             =over 4
279              
280             =item * RT: CPAN's request tracker (report bugs here)
281              
282             L
283              
284             =item * AnnoCPAN: Annotated CPAN documentation
285              
286             L
287              
288             =item * CPAN Ratings
289              
290             L
291              
292             =item * Search CPAN
293              
294             L
295              
296             =back
297              
298              
299             =head1 ACKNOWLEDGEMENTS
300              
301              
302             =head1 LICENSE AND COPYRIGHT
303              
304             Copyright 2011 Tim Wilde.
305              
306             This program is free software; you can redistribute it and/or modify it
307             under the terms of either: the GNU General Public License as published
308             by the Free Software Foundation; or the Artistic License.
309              
310             See http://dev.perl.org/licenses/ for more information.
311              
312              
313             =cut
314              
315             1; # End of WWW::Namecheap::API