The perl implementation of the Asterisk's Manager Interface, Asterisk::AMI was used to initiate call monitoring for sales extensions, and was responsible for adding Zoho records and uploading the recordings. A feature code was added to Asterisk to disable call monitoring with '*4'.

Zoho's documentation of their UploadFile() API call is a little terse, but I was able to get it working by sniffing a network dump of the php implementation and match it the corresponding implementation in perl.

# $LOGGER is an implementation of Log::Log4perl
# XML::Simple is the xml parsing library

sub zoho_upload_file {
        my ($type, $id, $file) = @_;
        $LOGGER->debug('zoho_upload_file('. $type .', '. $id .', '. $file .')');

        # Build up xml for the call recording
        $url = "https://crm.zoho.com/crm/private/xml/$type".
                "/uploadFile?authtoken=$ZHPASSWORD&scope=crmapi";

        # Post a new call recording
        $LOGGER->debug('zoho_upload_file() post: '. $url.', id: '. $id .', content['. $file .', '. basename($file) .', "Content-type" => "audio/wav"]');

        my $ua = LWP::UserAgent->new;
        push @{ $ua->requests_redirectable }, 'POST';
        my $req = $ua->request(POST $url,
                Content_Type => 'form-data',
                Content => [
                        id => $id,
                        content => [$file, basename($file), "Content-type" => "audio/wav"]
                ]
        );

        # Assert success
        my $ref = XMLin($req->content);
        if (! exists $ref->{'result'}->{'message'} ) {
                $LOGGER->error('Unexpected result');
                $LOGGER->debug(Dumper($ref));
                # TODO: send alert to nagios
                return 0;
        } elsif ($ref->{'result'}->{'message'} !~ /success/) {
                $LOGGER->error($ref->{'result'}->{'message'});
                return 1;
        } else {
                $LOGGER->info($ref->{'result'}->{'message'});
                return 0;
        }
}
Start: 
2017
End: 
2017