summaryrefslogtreecommitdiff
path: root/FS/bin/freeside-cdr-conexiant-import
blob: a79477c51ab4e59b3222a72cc8b2828144454a0a (plain)
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
125
126
127
#!/usr/bin/perl

use strict;

use Cpanel::JSON::XS;
use Getopt::Long;
use LWP::UserAgent;
use MIME::Base64;
use Net::HTTPS::Any qw(https_post https_get);

use FS::UID qw(adminsuidsetup);
use FS::Record qw(qsearchs);
use FS::cdr;
use FS::cdr_batch;

sub usage {
"Usage:
freeside-cdr-conexiant-import -h -u username -p apikey [-v] freesideuser

Downloads any existing CDR files with the BilledCallsOnly flag and 
imports records that have not been imported yet.  Silently skips 
records that have already been imported.
";
}

# should really be using a module for this
`which unzip` or die "can't find unzip executable";

my ($username,$password,$verbose);
GetOptions(
  "password=s"  => \$password,
  "username=s"  => \$username,
  "verbose"     => \$verbose,
);

my $fsuser = $ARGV[-1];

die usage() unless $fsuser;

adminsuidsetup($fsuser);

my ( $page, $response, %reply_headers ) = https_post(
  'host'    => 'api.conexiant.net',
  'port'    => '443',
  'path'    => '/v1/Cdrs/SearchCdrsDownloads',
  'headers' => {
    'Authorization' => 'Basic ' . MIME::Base64::encode("$username:$password",'')
  },
  'content' => '{}',
);

die "Bad response from conexiant server: $response"
  unless $response =~ /^200/;

my $result = decode_json($page);

die "Error from conexiant: " . ($result->{'ErrorInfo'} || 'No error message')
  unless $result->{'Success'};

my $files = $result->{'Data'}->{'Result'};

die "Unexpected results from conexiant, not an array"
  unless ref($files) eq 'ARRAY';

my $dir = $FS::UID::cache_dir. "/cache.". $FS::UID::datasrc;
my $ua  = LWP::UserAgent->new;

# Download files are created automatically at regular frequent intervals,
# but they contain overlapping data.
#
# FS::cdr::conexiant automatically skips previously imported cdrs,
# though if it does so for all records in a file, 
# then batch_import thinks the file is empty
foreach my $file (@$files) {
  next unless $file->{'BilledCallsOnly'};
  my $cdrbatch = 'conexiant-' . $file->{'Identifier'};
  # files that were "empty" will unfortunately be re-downloaded,
  # but the alternative is to leave an excess of empty batches in system,
  # and re-downloading is harmless (all files expire after 48 hours anyway)
  if (qsearchs('cdr_batch',{ 'cdrbatch' => $cdrbatch })) {
    print "$cdrbatch already imported\n" if $verbose;
    next;
  }
  if ($verbose) {
    print "Downloading $cdrbatch\n".
          "  Created ".$file->{'CreatedOn'}."\n".
          "  Start   ".$file->{'QueryStart'}."\n".
          "  End     ".$file->{'QueryEnd'}."\n".
          "  Link    ".$file->{'ValidLink'}."\n";
  }
  my $zfh = new File::Temp( TEMPLATE => 'conexiant.XXXXXXXX',
                           SUFFIX   => '.zip',
                           DIR      => $dir,
                         )
    or die "can't open temporary file to store download: $!\n";
  my $cfh = new File::Temp( TEMPLATE => 'conexiant.XXXXXXXX',
                           SUFFIX   => '.csv',
                           DIR      => $dir,
                         )
    or die "can't open temporary file to unzip download: $!\n";
  # yeah, these files ain't secured in any way
  my $response = $ua->get($file->{'ValidLink'}, ':content_file' => $zfh->filename);
  unless ($response->is_success) {
    die "Error downloading $cdrbatch: ".$response->status_line;
  }
  my $zfilename = $zfh->filename;
  print $cfh `unzip -p $zfilename 'Conexiant Cdrs.csv'`;
  seek($cfh,0,0);
  print "Importing batch $cdrbatch\n" if $verbose;
  my $error = FS::cdr::batch_import({
    'batch_namevalue' => $cdrbatch,
    'file'            => $cfh->filename,
    'format'          => 'conexiant'
  });
  if ($error eq 'Empty file!') {
    print "File contains no new cdrs, no batch created\n" if $verbose;
    $error = '';
  } elsif ($verbose && !$error) {
    print "File successfully imported\n";
  }
  die "Error importing $cdrbatch: $error" if $error;
}

exit;