9 use Net::HTTPS::Any qw(https_post https_get);
11 use FS::UID qw(adminsuidsetup);
12 use FS::Record qw(qsearchs);
18 freeside-cdr-conexiant-import -h -u username -p apikey [-v] freesideuser
20 Downloads any existing CDR files with the BilledCallsOnly flag and
21 imports records that have not been imported yet. Silently skips
22 records that have already been imported.
26 # should really be using a module for this
27 `which unzip` or die "can't find unzip executable";
29 my ($username,$password,$verbose);
31 "password=s" => \$password,
32 "username=s" => \$username,
33 "verbose" => \$verbose,
36 my $fsuser = $ARGV[-1];
38 die usage() unless $fsuser;
40 adminsuidsetup($fsuser);
42 my ( $page, $response, %reply_headers ) = https_post(
43 'host' => 'api.conexiant.net',
45 'path' => '/v1/Cdrs/SearchCdrsDownloads',
47 'Authorization' => 'Basic ' . MIME::Base64::encode("$username:$password",'')
52 die "Bad response from conexiant server: $response"
53 unless $response =~ /^200/;
55 my $result = decode_json($page);
57 die "Error from conexiant: " . ($result->{'ErrorInfo'} || 'No error message')
58 unless $result->{'Success'};
60 my $files = $result->{'Data'}->{'Result'};
62 die "Unexpected results from conexiant, not an array"
63 unless ref($files) eq 'ARRAY';
65 my $dir = $FS::UID::cache_dir. "/cache.". $FS::UID::datasrc;
66 my $ua = LWP::UserAgent->new;
68 # Download files are created automatically at regular frequent intervals,
69 # but they contain overlapping data.
71 # FS::cdr::conexiant automatically skips previously imported cdrs
72 foreach my $file (@$files) {
73 next unless $file->{'BilledCallsOnly'};
74 my $cdrbatch = 'conexiant-' . $file->{'Identifier'};
75 # files that contained no new records will unfortunately be re-downloaded,
76 # but the alternative is to leave an excess of empty batches in system,
77 # and re-downloading is harmless (all files expire after 48 hours anyway)
78 if (qsearchs('cdr_batch',{ 'cdrbatch' => $cdrbatch })) {
79 print "$cdrbatch already imported\n" if $verbose;
83 print "Downloading $cdrbatch\n".
84 " Created ".$file->{'CreatedOn'}."\n".
85 " Start ".$file->{'QueryStart'}."\n".
86 " End ".$file->{'QueryEnd'}."\n".
87 " Link ".$file->{'ValidLink'}."\n";
89 my $zfh = new File::Temp( TEMPLATE => 'conexiant.XXXXXXXX',
93 or die "can't open temporary file to store download: $!\n";
94 my $cfh = new File::Temp( TEMPLATE => 'conexiant.XXXXXXXX',
98 or die "can't open temporary file to unzip download: $!\n";
99 # yeah, these files ain't secured in any way
100 my $response = $ua->get($file->{'ValidLink'}, ':content_file' => $zfh->filename);
101 unless ($response->is_success) {
102 die "Error downloading $cdrbatch: ".$response->status_line;
104 my $zfilename = $zfh->filename;
105 print $cfh `unzip -p $zfilename 'Conexiant Cdrs.csv'`;
107 print "Importing batch $cdrbatch\n" if $verbose;
108 my $error = FS::cdr::batch_import({
109 'batch_namevalue' => $cdrbatch,
110 'file' => $cfh->filename,
111 'format' => 'conexiant'
113 if ($error eq 'Empty file!') {
114 print "File contains no records\n" if $verbose;
116 } elsif ($error eq "All records in file were previously imported") {
117 print "File contains no new cdrs, no batch created\n" if $verbose;
119 } elsif ($verbose && !$error) {
120 print "File successfully imported\n";
122 die "Error importing $cdrbatch: $error" if $error;