1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
package FS::part_export::bulkvs_e911;
use strict;
use vars qw(%info $me $DEBUG);
use base 'FS::part_export';
use FS::svc_phone;
use Tie::IxHash;
use SOAP::Lite;
use Digest::MD5 'md5_hex';
use Data::Dumper;
$DEBUG = 2;
$me = '['.__PACKAGE__.']';
tie my %options, 'Tie::IxHash', (
'apikey' => { label=>'Bulkvs.com API key' },
'password' => { label=>'Bulkvs.com website password' },
);
%info = (
'svc' => 'svc_phone',
'desc' => 'Provision e911 services via BulkVS',
'notes' => <<END
<p>Provision e911 services via BulkVS. Currently does not support provisioning
phone numbers, only e911 service itself.</p>
<p><i>apikey</i> is available through the web interface (look under the E911
Portal submenu). <i>password</i> is your password for the website, which will
be used to calculate your API password.</p>
END
,
'no_machine' => 1,
'options' => \%options,
);
my $client;
sub client {
my $self = shift;
my $endpoint = 'https://portal.bulkvs.com/api';
my $wsdl = $endpoint . '?wsdl';
# it's expensive to create but completely stateless, so cache it freely
$client ||= SOAP::Lite->service( $wsdl )->proxy( $endpoint );
}
sub login {
my $self = shift;
my $apikey = $self->option('apikey')
or die "no Bulkvs.com API key configured";
my $pass = $self->option('password')
or die "no Bulkvs.com password configured";
( $apikey, md5_hex($pass) );
}
sub _export_insert {
my ($self, $svc_phone) = @_;
my @login = $self->login;
my $location = $svc_phone->cust_location_or_main
or return 'no e911 location defined for this phone service';
warn "$me validating address for svcnum ".$svc_phone->svcnum."\n"
if $DEBUG;
my $result = $self->client->e911validateAddress( @login,
$location->address1,
$location->address2,
$location->city,
$location->state,
$location->zip,
);
warn Dumper $result if $DEBUG > 1;
if ( $result->{'faultstring'} ) {
return "E911 provisioning error: ".$result->{'faultstring'};
} elsif ( !exists($result->{entry0}->{addressid}) ) {
return "E911 provisioning error: server returned no address ID";
}
my $caller_name = $svc_phone->cust_linked ?
$svc_phone->cust_main->name_short :
'unknown';
warn "$me provisioning address for svcnum ".$svc_phone->svcnum."\n"
if $DEBUG;
$result = $self->client->e911provisionAddress( @login,
'1'.$svc_phone->phonenum,
$caller_name,
$result->{entry0}->{addressid},
);
warn Dumper $result if $DEBUG > 1;
if ( $result->{'faultstring'} ) {
return "E911 provisioning error: ".$result->{'faultstring'};
}
'';
}
sub _export_delete {
my ($self, $svc_phone) = @_;
my @login = $self->login;
warn "$me removing address for svcnum ".$svc_phone->svcnum."\n"
if $DEBUG;
my $result = $self->client->e911removeRecord( @login,
'1'.$svc_phone->phonenum
);
warn Dumper $result if $DEBUG > 1;
if ( $result->{'faultstring'} ) {
return "E911 unprovisioning error: ".$result->{'faultstring'};
}
'';
}
sub _export_replace {
my ($self, $new, $old) = @_;
# BulkVS says that to change an address for an existing number,
# we should reprovision it without removing the old record.
if ( $new->phonenum ne $old->phonenum ) {
my $error = $self->_export_delete($old);
return $error if $error;
}
$self->_export_insert($new);
}
1;
|