initial pass at integration, everything that can be done without a test server, RT...
authorIvan Kohler <ivan@freeside.biz>
Sun, 12 Jan 2014 06:11:09 +0000 (22:11 -0800)
committerIvan Kohler <ivan@freeside.biz>
Sun, 12 Jan 2014 06:11:09 +0000 (22:11 -0800)
Changes
Makefile.PL
README
lib/Net/Indosoft/QSuite.pm

diff --git a/Changes b/Changes
index fd23fe5..ebb0414 100644 (file)
--- a/Changes
+++ b/Changes
@@ -1,5 +1,5 @@
 Revision history for Net-Indosoft-QSuite
 
-0.01    Date/time
+0.01    unreleased
         First version, released on an unsuspecting world.
 
index 20a3a0a..5ad63c1 100644 (file)
@@ -8,9 +8,8 @@ WriteMakefile(
     AUTHOR           => q{Ivan Kohler <ivan-indosoft at freeside.biz>},
     VERSION_FROM     => 'lib/Net/Indosoft/QSuite.pm',
     ABSTRACT_FROM    => 'lib/Net/Indosoft/QSuite.pm',
-    LICENSE          => 'Artistic_2_0',
+    LICENSE          => 'Perl',
     PL_FILES         => {},
-    MIN_PERL_VERSION => 5.006,
     CONFIGURE_REQUIRES => {
         'ExtUtils::MakeMaker' => 0,
     },
@@ -18,8 +17,8 @@ WriteMakefile(
         'Test::More' => 0,
     },
     PREREQ_PM => {
-        #'ABC'              => 1.6,
-        #'Foo::Bar::Module' => 5.0401,
+        'Net::HTTPS::Any' => 0.10,
+        'JSON'            => 2,
     },
     dist  => { COMPRESS => 'gzip -9f', SUFFIX => 'gz', },
     clean => { FILES => 'Net-Indosoft-QSuite-*' },
diff --git a/README b/README
index 09d9c82..731922f 100644 (file)
--- a/README
+++ b/README
@@ -1,15 +1,7 @@
 Net-Indosoft-QSuite
 
-The README is used to introduce the module and provide instructions on
-how to install the module, any machine dependencies it may have (for
-example C compilers and installed libraries) and any other information
-that should be provided before the module is installed.
-
-A README file is required for CPAN modules since CPAN extracts the README
-file from a module distribution so that people browsing the archive
-can use it to get an idea of the module's uses. It is usually a good idea
-to provide version information here so that people can decide whether
-fixes for the module are worth downloading.
+This is an interface to the Indosoft Q-Suite API for wholesale PBX (and call
+center) tenant provisioning.
 
 
 INSTALLATION
@@ -21,6 +13,7 @@ To install this module, run the following commands:
        make test
        make install
 
+
 SUPPORT AND DOCUMENTATION
 
 After installing, you can find documentation for this module with the
@@ -45,41 +38,18 @@ You can also look for information at:
 
 LICENSE AND COPYRIGHT
 
-Copyright (C) 2014 Ivan Kohler
+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 terms of the the Artistic License (2.0). You may obtain a
-copy of the full license at:
-
-L<http://www.perlfoundation.org/artistic_license_2_0>
-
-Any use, modification, and distribution of the Standard or Modified
-Versions is governed by this Artistic License. By using, modifying or
-distributing the Package, you accept this license. Do not use, modify,
-or distribute the Package, if you do not accept this license.
-
-If your Modified Version has been derived from a Modified Version made
-by someone other than you, you are nevertheless required to ensure that
-your Modified Version complies with the requirements of this license.
-
-This license does not grant you the right to use any trademark, service
-mark, tradename, or logo of the Copyright Holder.
-
-This license includes the non-exclusive, worldwide, free-of-charge
-patent license to make, have made, use, offer to sell, sell, import and
-otherwise transfer the Package with respect to any patent claims
-licensable by the Copyright Holder that are necessarily infringed by the
-Package. If you institute patent litigation (including a cross-claim or
-counterclaim) against any party alleging that the Package constitutes
-direct or contributory patent infringement, then this Artistic License
-to you shall terminate on the date that such litigation is filed.
-
-Disclaimer of Warranty: THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER
-AND CONTRIBUTORS "AS IS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES.
-THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
-PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY
-YOUR LOCAL LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR
-CONTRIBUTOR WILL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR
-CONSEQUENTIAL DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE,
-EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+under the same terms as Perl itself.
+
+
+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/
 
index 176eb67..def7b75 100644 (file)
@@ -1,12 +1,14 @@
 package Net::Indosoft::QSuite;
 
-use 5.006;
 use strict;
-use warnings FATAL => 'all';
+use warnings;
+use vars qw( $AUTOLOAD );
+use JSON;
+use Net::HTTPS::Any qw( https_post );
 
 =head1 NAME
 
-Net::Indosoft::QSuite - The great new Net::Indosoft::QSuite!
+Net::Indosoft::QSuite - Interface to Indosoft Q-Suite API
 
 =head1 VERSION
 
@@ -19,34 +21,382 @@ our $VERSION = '0.01';
 
 =head1 SYNOPSIS
 
-Quick summary of what the module does.
+    use Net::Indosoft::QSuite;
 
-Perhaps a little code snippet.
+    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.
 
-    use Net::Indosoft::QSuite;
+=over 4
 
-    my $foo = Net::Indosoft::QSuite->new();
-    ...
+=item host (required)
 
-=head1 EXPORT
+=item gateway_key - A valid API gateway key (required)
 
-A list of functions that can be exported.  You can delete this section
-if you don't export anything, such as for a purely object-oriented module.
+=item debug (optional)
 
-=head1 SUBROUTINES/METHODS
+=back
 
-=head2 function1
+=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 function1 {
+sub errstr {
+  #my $class = shift;
+  #return $errstr
+  #  unless ref($class) && $class->isa('Net::VoIP_Innovations');
+
+  my $self = shift; #$class;
+  $self->{errstr};
 }
 
-=head2 function2
+=head2 editTenant
+
+=head2 assignTrunkToTenant
+
+=head2 editDID
+
+=head2 editAutoAttendant
 
 =cut
 
-sub function2 {
+#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
@@ -59,9 +409,6 @@ Please report any bugs or feature requests to C<bug-net-indosoft-qsuite at rt.cp
 the web interface at L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Net-Indosoft-QSuite>.  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.
@@ -97,45 +444,20 @@ L<http://search.cpan.org/dist/Net-Indosoft-QSuite/>
 
 =head1 LICENSE AND COPYRIGHT
 
-Copyright 2014 Ivan Kohler.
+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 terms of the the Artistic License (2.0). You may obtain a
-copy of the full license at:
-
-L<http://www.perlfoundation.org/artistic_license_2_0>
-
-Any use, modification, and distribution of the Standard or Modified
-Versions is governed by this Artistic License. By using, modifying or
-distributing the Package, you accept this license. Do not use, modify,
-or distribute the Package, if you do not accept this license.
-
-If your Modified Version has been derived from a Modified Version made
-by someone other than you, you are nevertheless required to ensure that
-your Modified Version complies with the requirements of this license.
-
-This license does not grant you the right to use any trademark, service
-mark, tradename, or logo of the Copyright Holder.
-
-This license includes the non-exclusive, worldwide, free-of-charge
-patent license to make, have made, use, offer to sell, sell, import and
-otherwise transfer the Package with respect to any patent claims
-licensable by the Copyright Holder that are necessarily infringed by the
-Package. If you institute patent litigation (including a cross-claim or
-counterclaim) against any party alleging that the Package constitutes
-direct or contributory patent infringement, then this Artistic License
-to you shall terminate on the date that such litigation is filed.
-
-Disclaimer of Warranty: THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER
-AND CONTRIBUTORS "AS IS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES.
-THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
-PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY
-YOUR LOCAL LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR
-CONTRIBUTOR WILL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR
-CONSEQUENTIAL DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE,
-EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+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; # End of Net::Indosoft::QSuite
+1;