#!/usr/bin/perl ############################################################################################# ## BeVocal Sample Code # ## (C) Copyright BeVocal, Inc. 2003, All rights reserved. # ## # ## This Sample Code is provided for your reference purposes, and carries no # ## warranty whatsoever. Use of this code is restricted to use in connection # ## with the BeVocal Cafe developer's program. # ## # ## BeVocal disclaims and excludes any and all warranties of merchantability, # ## title and fitness for a particular purpose. BeVocal does not warrant that the # ## software will satisfy your requirements, or that the software is without # ## defect or error. You are using the software at your own risk. # ## # ## This sample fetches a large number of call logs, using the CDR Access Service, # ## the VoiceXML Log Access Service, and the Speech Vendor Log Access Service. # ## # ## Example usage: # ## getLogsInTimePeriod.pl -c production -s 2003-05-13T23:00:00Z -e 2003-05-13T23:59:00Z # ## # ## This script uses a store for security keys. See its documentation in # ## http://cafe.bevocal.com/resources/voicexml_samples/keyRing.pl # ############################################################################################# #use SOAP::Lite +trace => 'debug', xmlschema => 2001; use SOAP::Lite xmlschema => 2001; use strict; require "../keyRing.pl"; # Define global variables my $soapService = 'CDRAccessService_v2/services/CDRAccessService_v2'; my $soapCdrURL = 'CDRAccessService_v2/services/CDRAccessService_v2'; my $soapVXMLlogURL = 'LogAccessService_v1/services/LogAccessService_v1'; my $soapASRlogURL = 'SpeechVendorLogAccessService_v1/services/SpeechVendorLogAccessService_v1'; my $fileRoot = $ENV{'GETCALL_FILEROOT'}; my $fileDir = ''; my $orgId = ''; my $appId = ''; my $startTime = ''; my $endTime = ''; my $accessSystem = ''; my $soapServer = ''; my $myAccessKey = ''; my $soapURL = ''; my $cdrRecCount = 0; my $cdrFileCount = 0; my $misrecCount = 0; my $errorCount = 0; my $missingASRlogs = 0; my $missingVXMLlogs = 0; my $existingASRlogs = 0; my $existingVXMLlogs = 0; my $customer = 'production'; # Validate the user arguments processArgs(@ARGV); #-----------------------------------------------------------# # main -- Get all logs in a time range # #-----------------------------------------------------------# print "Fetching logs starting: ", $startTime, "\n ending: ", $endTime, "\n customer: ", $accessSystem, "\n orgID: ", $orgId, "\n appID: ", $appId, "\n customer: ", $customer, "\n server: ", $soapServer, # "\n fileroot: ", $fileRoot, # "\n key: ", $myAccessKey, "\n"; $cdrRecCount = getCDRcount($orgId, $appId, $startTime, $endTime); if ($cdrRecCount gt 0) { print "\n. . .Expecting to find logs for $cdrRecCount calls. . .\n\n"; makeStorageArea(); } else { die("No records to get.\n"); } getCDRlogs(@{getCDRrecords($orgId, $appId, $startTime, $endTime)}); print "Number of calls found: ", $cdrRecCount, "\nNumber of calls fetched: ", $cdrFileCount, "\nMissRec Count: ", $misrecCount, "\nError Count: ", $errorCount, "\nVXML Logs not found: ", $missingVXMLlogs, "\nASR Logs not found: ", $missingASRlogs, "\nExisting VXML Logs: ", $existingVXMLlogs, "\nExisting ASR Logs: ", $existingASRlogs, "\n"; writeSummary(); exit(0); #-------------------------------------------------------------# # Supporting functions below this point # #-------------------------------------------------------------# sub usage { print "ERROR: $_[0]\n"; print "USAGE: getLogsInTimePeriod.pl [-c ] -s -e \n"; print " StartTime = YYYY-MM-DDTHH:MM:SSZ\n"; print " EndTime = YYYY-MM-DDTHH:MM:SSZ\n"; print " Example Date: 2003-05-13T23:42:00Z\n"; print "\n"; print " All call logs for the SOAP provider are placed in a directory.\n"; print " The directory is created if it does not exist. The path is:\n"; print " /orgId/appId/, is set with the\n"; print " environment variable GETCALL_FILEROOT.\n"; print "\n"; print " If a customer (provider) is not specified, 'production' is used.\n"; exit(1); } sub processArgs { if ($ENV{'GETCALL_FILEROOT'} eq '') { usage("Environment variable GETCALL_FILEROOT not set"); } # Process the rest of the params while ($#_ >= 0) { if ($_[0] eq '-s') { shift(@_); $startTime = $_[0]; $fileDir = "${startTime}CDR"; $fileDir =~ s/[TZ:-]/_/g; } elsif ($_[0] eq '-e') { shift(@_); $endTime = $_[0]; } elsif ($_[0] eq '-c') { shift(@_); $customer = $_[0]; } else { usage("Incorrect parameter given"); } shift(@_); } # Get the provider data or die ($accessSystem, $orgId, $appId, $soapServer, $myAccessKey) = getProviderData($customer); if ($accessSystem eq "NoProviderFound") { usage("No valid SOAP Provider given"); } if ($startTime eq '' || $endTime eq '') { usage("All required parameters were not found"); } } sub makeStorageArea { if (! -d $fileRoot) { print "Making $fileRoot\n"; mkdir $fileRoot, 0777; } if (! -d "$fileRoot/$orgId") { print "Making $fileRoot/$orgId\n"; mkdir "$fileRoot/$orgId", 0777; } if (! -d "$fileRoot/$orgId/$appId") { print "Making $fileRoot/$orgId/$appId\n"; mkdir "$fileRoot/$orgId/$appId", 0777; } if (! -d "$fileRoot/$orgId/$appId/$fileDir") { print "Making $fileRoot/$orgId/$appId/$fileDir\n"; mkdir "$fileRoot/$orgId/$appId/$fileDir", 0777; } print "Directories exist.\n\n"; } #---------------------------------------------------------------# # getCDRcount(orgID, appId, StartTime, EndTime) # # # # input: String organizationID # # input: String applicationID # # input: Date startTime # # input: Date endTime # # output: int CDR record count # # errors: if there is a SOAP fault, or a transport error, # # the perl process will die with an error message. # #---------------------------------------------------------------# sub getCDRcount { my ($orgId, $appId, $startTime, $endTime)= @_; $soapURL = "http://$soapServer/$soapCdrURL"; # Setup a pointer to the Service my $cdrCountRequest = SOAP::Lite ->proxy($soapURL) ->uri('http://www.bevocal.com/soap/services/') ->on_fault( sub { my($cdrCountRequest, $res) = @_; die "ERROR: Could not get call count: ", ref $res ? $res->faultstring : $cdrCountRequest->transport->status, "\n"; }); # To call this service, we need an Access Key, # passed in via the SOAP header, as per the W3C. my $head = SOAP::Header->name(platformServicesSessionID => $myAccessKey); # If there's a problem, print out fault or transport info and die. my $res1 = $cdrCountRequest->getCallDetailRecordCount( $head, SOAP::Data->type('string')->name(organizationID => $orgId), SOAP::Data->type('string')->name(applicationID => $appId), SOAP::Data->type('dateTime')->name(startTime => $startTime), SOAP::Data->type('dateTime')->name(endTime => $endTime) ); return $res1->result(); } #---------------------------------------------------------------# # getCDRrecords(orgID, appId, StartTime, EndTime) # # # # input: String organizationID # # input: String applicationID # # input: Date startTime # # input: Date endTime # # output: Array CDR records # # errors: if there is a SOAP fault, or a transport error, # # the perl process will die with an error message. # #---------------------------------------------------------------# sub getCDRrecords { my ($orgId, $appId, $startTime, $endTime)= @_; my $extendedData = 'true'; $soapURL = "http://$soapServer/$soapCdrURL"; # Setup a pointer to the Service my $cdrFetchRequest = SOAP::Lite ->proxy($soapURL) ->uri('http://www.bevocal.com/soap/services/') ->on_fault( sub { my($cdrFetchRequest, $res) = @_; die "ERROR: Could not get CDR records: ", ref $res ? $res->faultstring : $cdrFetchRequest->transport->status, "\n"; }); # To call this service, we need an Access Key, # passed in via the SOAP header, as per the W3C. my $head = SOAP::Header->name(platformServicesSessionID => $myAccessKey); # If there's a problem, print out fault or transport info and die. my $res1 = $cdrFetchRequest->getCallDetailRecords( $head, SOAP::Data->type('string')->name(organizationID => $orgId), SOAP::Data->type('string')->name(applicationID => $appId), SOAP::Data->type('dateTime')->name(startTime => $startTime), SOAP::Data->type('dateTime')->name(endTime => $endTime), SOAP::Data->type('boolean')->name(requestExtendedData => $extendedData) ); return $res1->result(); } #---------------------------------------------------------------# # getCDRlogs(cdrResults[]) # # # # input: Array cdrResults[] # #---------------------------------------------------------------# sub getCDRlogs { my (@cdrResults) = @_; while ($#cdrResults >= 0) { my %hash = %{@cdrResults[0]}; # If there are logs get them if ($hash{'speechVendorCallLogAvailable'} eq 1 && $hash{'beVocalCallLogAvailable'} eq 1) { # Debug statement to be sure you are getting what you think you are # print "sessionId=", $hash{'sessionID'}, # " -- mediaGateway=", $hash{'mediaGatewayHostname'}, # "\n"; # Get the logs and write them out to the storage area # if the log exists already, skip it if (doesLogExist("vxml", $hash{'sessionID'}) eq 0) { # if the log is not available increment the counter if (getVXMLlog($hash{'sessionID'}) eq 0) { $missingVXMLlogs++; } } else { $existingVXMLlogs++; } # if the log exists already, skip it if (doesLogExist("log", $hash{'sessionID'}) eq 0) { # if the log is not available increment the missing count if (getASRlog($hash{'sessionID'}) eq 0) { $missingASRlogs++; } } else { $existingASRlogs++; } # Accumulate statistics about the call my @extendedData = @{$hash{'extendedData'}}; while ($#extendedData >= 0) { my $ekey; my %ehash = %{@extendedData[0]}; my $evalue = 0; foreach $ekey (keys %ehash) { if ($ekey eq 'value') { $evalue = scalar($ehash{$ekey}); } elsif ($ehash{$ekey} eq 'NUM_MIS_REC') { $misrecCount += $evalue; } elsif ($ehash{$ekey} eq 'NUM_ERROR') { $errorCount += $evalue; } } shift(@extendedData); } $cdrFileCount++; } shift(@cdrResults); } } #---------------------------------------------------------------# # getASRlog(sessionId) # # # # input: String sessionId # # errors: if there is a SOAP fault, or a transport error, # # the perl process will die with an error message. # #---------------------------------------------------------------# sub getASRlog { my ($sessionId)= @_; my ($soapStatus) = 1; my $vendorID = 'SPEECH_VENDOR_NUANCE'; my $requestedFormat = ''; $soapURL = "http://$soapServer/$soapASRlogURL"; # Setup a pointer to the Service my $asrLogRequest = SOAP::Lite ->proxy($soapURL) ->uri('http://www.bevocal.com/soap/services/') ->on_fault( sub { my($asrLogRequest, $res) = @_; warn "WARNING: Could not fetch ASR log for sessionId: ", $sessionId, " -- ", ref $res ? $res->faultstring : $asrLogRequest->transport->status, "\n"; $soapStatus = 0; }); # To call this service, we need an Access Key, # passed in via the SOAP header, as per the W3C. my $head = SOAP::Header->name(platformServicesSessionID => $myAccessKey); # If there's a problem, print out fault or transport info and die. my $res1 = $asrLogRequest->getCallLog ( $head, SOAP::Data->type('string')->name(sessionID => $sessionId), SOAP::Data->type('string')->name(vendorID => $vendorID), SOAP::Data->type('string')->name(requestedFormat => $requestedFormat), ); if ($soapStatus ne 0) { writeLog("log", $sessionId, $res1->result()); return $res1->result(); } else { return 0; } } #---------------------------------------------------------------# # getVXMLlog(sessionId) # # # # input: String sessionId # # errors: if there is a SOAP fault, or a transport error, # # the perl process will die with an error message. # #---------------------------------------------------------------# sub getVXMLlog { my ($sessionId) = @_; my ($soapStatus) = 1; $soapURL = "http://$soapServer/$soapVXMLlogURL"; # Setup a pointer to the Service my $vxmlLogRequest = SOAP::Lite ->proxy($soapURL) ->uri('http://www.bevocal.com/soap/services/') ->on_fault( sub { my($vxmlLogRequest, $res) = @_; warn "WARNING: Could not fetch VXML log for sessionId: ", $sessionId, " -- ", ref $res ? $res->faultstring : $vxmlLogRequest->transport->status, "\n"; $soapStatus = 0; }); # To call this service, we need an Access Key, # passed in via the SOAP header, as per the W3C. my $head = SOAP::Header->name(platformServicesSessionID => $myAccessKey); # If there's a problem, print out fault or transport info and die. my $res1 = $vxmlLogRequest->getCallLog ( $head, SOAP::Data->type('string')->name(sessionID => $sessionId) ); if ($soapStatus != 0) { writeLog("vxml", $sessionId, $res1->result()); return $res1->result(); } else { return 0; } } sub doesLogExist { my ($logType, $sessionId) = @_; if (-f "$fileRoot/$orgId/$appId/$fileDir/${sessionId}.$logType") { return 1; } else { return 0; } } sub writeLog { my ($logType, $sessionId, $logData) = @_; my $outPutFile = ">" . "$fileRoot/$orgId/$appId/$fileDir/${sessionId}.$logType"; open(OutFile, $outPutFile) || die ("Could not open output file $outPutFile\n"); print OutFile $logData; close(OutFile); } sub writeSummary { my $outPutFile = ">" . "$fileRoot/$orgId/$appId/$fileDir/fetchSummary.txt"; open(OutFile, $outPutFile) || die ("Could not open output file $outPutFile\n"); print OutFile "Customer: ", $accessSystem, "\nStart Time: ", $startTime, "\nEnd Time: ", $endTime, "\nNumber of calls found: ", $cdrRecCount, "\nNumber of calls fetched: ", $cdrFileCount, "\nMissRec Count: ", $misrecCount, "\nError Count: ", $errorCount, "\nVXML Logs not found: ", $missingVXMLlogs, "\nASR Logs not found: ", $missingASRlogs, "\nExisting VXML Logs: ", $existingVXMLlogs, "\nExisting ASR Logs: ", $existingASRlogs, "\n"; close(OutFile); }