package Net::Indosoft::QSuite; use strict; use warnings; use vars qw( $AUTOLOAD ); use JSON; use Net::HTTPS::Any qw( https_post ); =head1 NAME Net::Indosoft::QSuite - Interface to Indosoft Q-Suite API =head1 VERSION Version 0.01 =cut our $VERSION = '0.01'; =head1 SYNOPSIS use Net::Indosoft::QSuite; my $qsuite = Net::Indosoft::QSuite->new( host => 'server.example.com', gateway_key => '09ad8f6b692717316913809f9903fd08', ); ### # Manage Tenant ### my $uuid = $qsuite->editTenant( mode => 'create', name => 'Tenant One', shortname => 'one', hostname => 'one.tenant.com', callerid_name => 'Tenant One', callerid_number => '5551112222', ) or die "can't create tenant: ". $qsuite->errstr; my $uuid = $qsuite->editTenant( mode => 'edit', uuid => 'Tenant UUID', name => 'Tenant Name', shortname => 'Tenant shortname', hostname => 'Tenant hostname', callerid_name => 'Nailup caller ID name', callerid_number => 'Nailup caller ID number', ) or die "can't edit tenant: ". $qsuite->errstr; $qsuite->editTenant( mode => 'delete', uuid => 'Tenant UUID', ) or die "can't delete tenant: ". $qsuite->errstr; ### # Manage Trunk Assignments ### my $uuid = $qsuite->assignTrunkToTenant( mode => 'assign', tenant_uuid => 'f269fa3480e739d77e4fee61f94575e2', trunk_id => '1', #provided by indosoft ) or die "can't assign trunk to tenant ". $qsuite->errstr; my $uuid = $qsuite->assignTrunkToTenant( mode => 'unassign', tenant_uuid => 'Tenant UUID', trunk_id => 'trunk ID, #provided by indosoft ) or die "can't trunk from tenant: ". $qsuite->errstr; ### # Manage DID ### my $number = $qsuite->editDID( mode => 'create', tenant_uuid => 'f269fa3480e739d77e4fee61f94575e2', number => '4445550011', auto_attendant_uuid => 'c4367c52bf45525bfbb7614b167a5335', ) or die "can't create DID: ". $qsuite->errstr; my $number = $qsuite->editDID( mode => 'edit' tenant_uuid => 'Tenant UUID', number => 'The DID number', auto_attendant_uuid => 'UUID of the assigned auto attendant', ) or die "can't edit DID: ". $qsuite->errstr; my $number = $qsuite->editDID( mode => 'delete' tenant_uuid => 'Tenant UUID', ) or die "can't delete DID: ". $qsuite->errstr; ### # Manage Auto Attendant ### my $uuid = $qsuite->editAutoAttendant( mode => 'create', tenant_uuid => 'f269fa3480e739d77e4fee61f94575e2', name => 'Auto F. Atttendant', repeat_limit => 54, response_limit => 32, allow_extension_dialing => 0, # 0 or 1 ) or die "can't create auto attendant: ". $qsuite->errstr; my $uuid = $qsuite->editAutoAttendant( mode => 'edit' tenant_uuid => 'Tenant UUID', uuid => 'UUID of the assigned auto attendant', name => 'Auto Attenant name', repeat_limit => 54, # The number of time to attempt to gather input response_limit => 32, # The timeout on the response allow_extension_dialing => 0, # "Allow the caller to dial extensions with the menu ) or die "can't edit auto attendant: ". $qsuite->errstr; my $uuid = $qsuite->editAutoAttendant( mode => 'delete' tenant_uuid => 'Tenant UUID', uuid => 'UUID of the assigned auto attendant', ) or die "can't delete auto attendant: ". $qsuite->errstr; ### # Manage Ring Group ### my $uuid = $qsuite->editRingGroup( mode => 'create', tenant_uuid => 'f269fa3480e739d77e4fee61f94575e2', #docs say uuid ('ring group uuid') for create, but prob. wrong name => 'Ring Group', timeout => 54, extension_uuids => '432789473febdf00fe1ee77777777777,ab98342efabc43', ) or die "can't create ring group: ". $qsuite->errstr; my $uuid = $qsuite->editRingGroup( mode => 'edit' tenant_uuid => 'Tenant UUID', uuid => 'Ring group UUID', name => 'Ring group name', timeout => 54, # Ring group timeout extension_uuids => '1234abc,999fefefefe', # Comma-separated list of extension UUIDs that make up the ring group ) or die "can't edit ring group: ". $qsuite->errstr; my $uuid = $qsuite->editRingGroup( mode => 'delete' tenant_uuid => 'Tenant UUID', uuid => 'Ring group UUID', ) or die "can't delete ring group: ". $qsuite->errstr; ### # Manage Employee/User ### my $uuid = $qsuite->editEmployee( mode => 'create', tenant_uuid => 'f269fa3480e739d77e4fee61f94575e2', #docs say uuid ('employee uuid') for create, but prob. wrong username => 'tofub', password => 'beast1', firstname => 'Tofu', lastname => 'Beast', ) or die "can't create employee: ". $qsuite->errstr; my $uuid = $qsuite->editEmployee( mode => 'edit' tenant_uuid => 'Tenant UUID', uuid => 'Employee UUID', username => 'tofub', password => 'beast1', firstname => 'Tofu', lastname => 'Beast', ) or die "can't edit employee: ". $qsuite->errstr; my $uuid = $qsuite->editEmployee( mode => 'delete' tenant_uuid => 'Tenant UUID', uuid => 'Employee UUID', ) or die "can't delete employee: ". $qsuite->errstr; ### # Manage Extension ### #or does this return an "extension uuid"? its wanted for devices... my $number = $qsuite->editExtension( mode => 'create', tenant_uuid => 'f269fa3480e739d77e4fee61f94575e2', number => '101', ) or die "can't create extension: ". $qsuite->errstr; #this is documented but seems to make no sense #my $number = $qsuite->editExtension( # mode => 'edit' # tenant_uuid => 'Tenant UUID', # number => '101', # ) # or die "can't edit extension: ". $qsuite->errstr; #or does this want an "extension uuid"? my $number = $qsuite->editExtension( mode => 'delete' tenant_uuid => 'Tenant UUID', number => '101', ) or die "can't delete extension: ". $qsuite->errstr; ### # Manage Device ### my $uuid = $qsuite->editDevice( mode => 'create', tenant_uuid => 'f269fa3480e739d77e4fee61f94575e2', employee_uuid => 'f269fa3480e739d77e4fee61f94575e2', extension_uuid => 'f269fa3480e739d77e4fee61f94575e2', #docs say "device uuid" for create, but i doubt it protocol => 'sip', #sip iax or dahdi ) or die "can't create device: ". $qsuite->errstr; my $uuid = $qsuite->editDevice( mode => 'edit' tenant_uuid => 'Tenant UUID', employee_uuid => 'Employee UUID', extension_uuid => 'Extension UUID', uuid => 'Device UUID', protocol => 'sip', #sip iax or dahdi ) or die "can't edit device: ". $qsuite->errstr; #docs for required fields here appear to be on crack (tenant_uuid only?), # so my best guess my $uuid = $qsuite->editDevice( mode => 'delete' #perhaps? tenant_uuid => 'Tenant UUID', #perhaps? employee_uuid => 'Employee UUID', #perhaps? extension_uuid => 'Extension UUID', uuid => 'Device UUID', ) or die "can't delete device: ". $qsuite->errstr; ### # Manage Voicemail Settings ### my $uuid = $qsuite->editVoicemailSettings( extension_uuid => 'f269fa3480e739d77e4fee61f94575e2', pin => '5454', ) or die "can't edit voicemail: ". $qsuite->errstr; ### # Manage Extension Forwarding Settings ### my $uuid = $qsuite->editForwardingSettings( #perhaps? docs say yes, exampe no tenant_uuid => 'f269fa3480e739d77e4fee61f94575e2', extension_uuid => 'f269fa3480e739d77e4fee61f94575e2', number => '555-888-2222', ) or die "can't edit forwarding: ". $qsuite->errstr; =head1 METHODS =head2 new Creates a new Net::Indosoft:QSuite object. Options may be passed as a hash reference or a flat list of names and values. =over 4 =item host (required) =item gateway_key - A valid API gateway key (required) =item debug (optional) =back =cut sub new { my $proto = shift; my $class = ref($proto) || $proto; my $self = ref($_[0]) ? shift : { @_ }; $self->{'debug'} ||= 0; bless($self, $class); } =head2 errstr =cut sub errstr { #my $class = shift; #return $errstr # unless ref($class) && $class->isa('Net::VoIP_Innovations'); my $self = shift; #$class; $self->{errstr}; } =head2 editTenant =head2 assignTrunkToTenant =head2 editDID =head2 editAutoAttendant =cut #our %return = ( # 'Tenant' => 'uuid', # 'DID' => 'number', # 'AutoAttendant' => 'uuid', # 'RingGroup' => 'uuid', #? its undocumented # 'Employee' => 'uuid', # 'Extension' => 'number', # 'Device' => 'uuid', # 'VoicemailSettings' => 'uuid', # 'ForwardingSettings' => 'uuid', #); sub AUTOLOAD { my $self = shift; my $opts = ref($_[0]) ? shift : { @_ }; $AUTOLOAD =~ /(^|::)(\w+)$/ or die "unparsable AUTOLOAD: $AUTOLOAD"; my $func = $2; my $path = "/cti/api/external/$func.json"; my ( $page, $https_response, %reply_headers ) = https_post({ host => $self->{host}, port => 443, path => $path, }); unless ( $https_response =~ /^200/i ) { #this is a lower-layer communication error, so it warrants an exception die "Error POSTing to https://". $self->{host}. "$path : $https_response\n"; #$self->{'errstr'} = $https_response; #return ''; } my $response = decode_json( $page ); #use Data::Dumper; #warn Dumper($response); #if $self->{debug}; unless ( $response->{success} ) { # == 1 $self->{errstr} = $response->{error}; return ''; } $self->{errstr} = ''; # use %return if it gets more complicated if ( $func =~ /(DID|Extension)$/ ) { return $response->{data}{number}; } else { return $response->{data}{uuid}; } } =head1 AUTHOR Ivan Kohler, C<< >> =head1 BUGS Please report any bugs or feature requests to C, or through the web interface at L. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes. =head1 SUPPORT You can find documentation for this module with the perldoc command. perldoc Net::Indosoft::QSuite You can also look for information at: =over 4 =item * RT: CPAN's request tracker (report bugs here) L =item * AnnoCPAN: Annotated CPAN documentation L =item * CPAN Ratings L =item * Search CPAN L =back =head1 ACKNOWLEDGEMENTS =head1 LICENSE AND COPYRIGHT Copyright (C) 2014 Freeside Internet Services, Inc. (http://freeside.biz/) This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =head1 ADVERTISEMENT Need a complete, open-source back-office and customer self-service solution? The Freeside software includes support for Indosoft integration, CDR rating, invoicing, credit card and electronic check processing, integrated trouble ticketing, and customer signup and self-service web interfaces. http://freeside.biz/freeside/ =cut 1;