1 package WebService::Northern911;
3 use Digest::MD5 'md5_hex';
5 use XML::Compile::WSDL11;
6 use XML::Compile::SOAP11;
7 use XML::Compile::Transport::SOAPHTTP;
8 use File::ShareDir 'dist_dir';
10 use WebService::Northern911::Response;
16 WebService::Northern911 - Interface to the Northern 911 ALI database
20 use WebService::Northern911;
22 my $n911 = WebService::Northern911->new( vendor_code => '007',
23 password => '280fip1@' );
25 my $result = $n911->AddorUpdateCustomer(
26 PHONE_NUMBER => '4015559988',
29 STREET_NUMBER => 1024,
30 STREET_NAME => 'Main St',
32 PROVINCE_STATE => 'AB',
33 POSTAL_CODE_ZIP => 'Z1A A2Z',
35 if ($result->is_success) {
36 print "Updated customer."
38 print $result->error_message;
47 Creates an object to access the API. OPTIONS must include C<vendor_code>
48 and C<password>. By default, this will connect to the development API;
49 for access to the live service, pass C<live> => 1.
56 my $vendor_code = $opt{vendor_code} or die "WebService::Northern911::new() requires vendor_code\n";
57 my $password = $opt{password} or die "WebService::Northern911::new() requires password\n";
59 # create the interface
60 # expensive, so reuse this object as much as possible
61 my $schema = dist_dir('WebService-Northern911') . '/schema';
68 # yes, that's right, we have to distribute the schema with this module.
69 # XML::Compile::WSDL11 makes the argument that
70 my $client = XML::Compile::WSDL11->new("$schema/wsdl");
71 for my $xsd (<$schema/xsd*>) {
72 $client->importDefinitions($xsd);
75 $client->compileCalls;
77 vendor_code => $vendor_code,
78 password => $password,
84 # internal method: returns the authentication string (referred to as the
90 my $now = DateTime->now;
91 $now->set_time_zone('UTC');
92 md5_hex($self->{vendor_code} .
94 $now->strftime('%Y%m%d')
98 # internal method: dispatch a request to the service
102 $self->{client}->call(@_);
105 =item AddorUpdateCustomer OPTIONS
107 Adds or updates a customer. Note the idiosyncratic capitalization; this
108 is the spelling of the underlying API method. OPTIONS may include:
110 - PHONE_NUMBER: 10 digits, no punctuation
111 - FIRST_NAME: customer first name, up to 38 characters
112 - LAST_NAME: customer last name or company name, up to 100 characters
113 - STREET_NUMBER: up to 10 characters
114 - STREET_NAME: up to 84 characters
115 - CITY: up to 38 characters
116 - PROVINCE_STATE: 2 letter code
117 - POSTAL_CODE_ZIP: Canadian postal code or U.S. zip code
118 - OTHER_ADDRESS_INFO: up to 250 characters
120 Returns a L<WebService::Northern911::Result> object.
124 sub AddorUpdateCustomer {
127 my %customer = map { $_ => $opt{$_} }
128 qw( PHONE_NUMBER FIRST_NAME LAST_NAME STREET_NUMBER STREET_NAME
129 CITY PROVINCE_STATE POSTAL_CODE_ZIP OTHER_ADDRESS_INFO
131 # according to Northern 911 support, this is for a future feature,
132 # and should always be 'N' for now
133 $customer{ENHANCED_CAPABLE} = 'N';
135 $customer{VENDOR_CODE} = $self->{vendor_code};
137 my ($answer, $trace) = $self->_call( 'AddorUpdateCustomer',
138 hash => $self->_auth,
139 customer => \%customer,
142 WebService::Northern911::Response->new($answer);
145 =item DeleteCustomer PHONE
147 Deletes a customer record. PHONE must be the phone number (10 digits,
148 as in C<AddorUpdateCustomer>).
156 my ($answer, $trace) = $self->_call( 'DeleteCustomer',
157 vendorCode => $self->{vendor_code},
158 hash => $self->_auth,
159 phoneNumber => $phone,
162 WebService::Northern911::Response->new($answer);
165 =item QueryCustomer PHONE
167 Queries a customer record. PHONE must be the phone number. The response
168 object will have a "customer" method which returns a hashref of customer
169 information, in the same format as the arguments to C<AddorUpdateCustomer>.
177 my ($answer, $trace) = $self->_call( 'QueryCustomer',
178 vendorCode => $self->{vendor_code},
179 hash => $self->_auth,
180 phoneNumber => $phone,
183 WebService::Northern911::Response->new($answer);
186 =item GetVendorDumpURL
188 Returns a URL to download a CSV dump of your customer data. The response
189 object will have a 'url' method to return the URL.
191 Note that this feature is heavily throttled (at most once per week, unless
192 you pay for more frequent access) and the URL can only be used once.
196 sub GetVendorDumpURL {
199 my ($answer, $trace) = $self->_call( 'GetVendorDumpURL',
200 vendorCode => $self->{vendor_code},
201 hash => $self->_auth,
204 WebService::Northern911::Response->new($answer);
211 Mark Wells, <mark@freeside.biz>
213 Commercial support is available from Freeside Internet Services, Inc.
217 Copyright (c) 2014 Mark Wells