The Community Forums

Interact with an entire community of cPanel & WHM users!
  1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

API call from within CustomEventHandler

Discussion in 'cPanel Developers' started by tizoo, May 31, 2011.

  1. tizoo

    tizoo Well-Known Member

    Joined:
    Jan 6, 2004
    Messages:
    66
    Likes Received:
    0
    Trophy Points:
    6
    Hi all,

    I need to call the Email::listpopswithdisk API function from an event inside the CustomEventHandler.

    Certainly due to my lack of Perl knowledge, I just do the following :



    Code:
    package Cpanel::CustomEventHandler;
    
    use strict;
    use Cpanel::Logger ();
    
    sub event {
        my ($apiv, $type, $module, $event, $cfgref, $dataref) = @_;
    
        return 1 if $module ne "email";
    
        if ($event eq 'addpop' && $type eq 'pre') {
            my $domain = $cfgref->{'domain'};
    
            # Get the free space for this account
            my $list = Cpanel::Email::listpopswithdisk($domain, 0, 1);
    
            print(STDERR "[CustomEventHandler] $module $event $type\n");
            print(STDERR "[CustomEventHandler] $email" . '@' . "$domain ($quota, $password)\n");
        }
        return 1;
    }
    1;
    
    But this doesn't work.

    Is it possible to call API function from within CustomEventHandler.pm script ?
    If yes, could someone give me some tips ?

    Thanks in advance for any help,

    Philippe
     
  2. cPanelDavidN

    cPanelDavidN Integration Developer
    Staff Member

    Joined:
    Dec 17, 2009
    Messages:
    571
    Likes Received:
    1
    Trophy Points:
    18
    Location:
    Houston, TX
    cPanel Access Level:
    Root Administrator
    Hi Philippe,

    I far as I know, any Perl modules in the Cpanel namespace should be available to you, at least in general. I wouldn't be surprised if there were a few out there that don't load as expected (due to compile time issues).

    The thing to do is try on a non-production box. CustomEventHandlers have the capability to stop a cPanel API call, and if you make an error (syntax or otherwise), then it's very likely all the 'pre' events will be evaluated as 'false' and thus will not let the API call continue...all cPanel UI and API calls will cease to function...

    Another gotcha of using the Cpanel modules directly is that there are several functions/subroutines that use 'print' statements, which under normal runtime conditions is fine, but if called out of context will likely render to the output buffer, aka STDOUT, aka whatever STDOUT is for the invocation method. This will cause UI styling to break, parsed API calls (used by the frontend) to not render data, and remote calls to be mal-formed (JSON or XML). In particular, I'm thinking about API1 calls. Granted, in somes cases (like Email.pm) the module is compiled and you won't be able to actually look at the module's subroutines to determine if they return data (with "return") or if they simply print the data (in hopes that it renders to the correct buffer). In fact the direct use of 'listpopswithdisk' as you have it in your example would be considered an API1 invocation of that function-set provided by our APIs (despite the fact that listpopwithdisk is not a real API1 function, it's only API2, but the invocation pattern holds true). However, that particular subroutine does the decent thing and returns data (ie, no 'print' statements). So, it safe in that regard.

    ...But anyway, I think in your case, the first step is to include the Email module.
    Code:
    # Get the free space for this account
    use Cpanel::Email ();
    my $list = Cpanel::Email::listpopswithdisk($domain, 0, 1);
    
    Technically, you probably want to place the include closer to the top, with the rest of the includes.

    Last gotcha, you will find using compiled modules particularly difficult since you cannot verify the input, and the ordering, that is required. Our documentation (cPanel & WHM's SDK) covers all the detail necessary to use the APIs. However, just because there's an API module named 'Alphabet' and function name 'xyz' that takes '1,2,3' doesn't always mean there's a literal Perl module/function like 'Cpanel::Alphabet::xyz(1,2,3)'. For instance, if you call Cpanel::Email::listpopswithdisk(), as it so happens the input ordering is a little different than the documentation. Our API parser handles this when you make an actual API request. But if you call this directly, you'll want the following order: "domain", "nearquoteonly", "regex", "no_validate".

    Ideally, you'd use something like PublicAPI to make a real API call. PublicAPI lets you make an API request (as a separate, independent call); you'd actually call and API function (as documented) and not a literal module/function. I.e., no stabbing in the dark. The downside to this approach is the overhead of making the API call. But honestly, I'd do some benchmarks just to satisfy yourself that the overhead is negligible compared to the development and maintenance nightmare it can be to code against a compile, undocumented codebase (ie, Email.pm and friends).

    The Perl PublicAPI package is available at our GitHub account, on CPAN, and as of 11.30 it ships in the product.

    If you have an questions about PublicAPI, I'd be glad to answer them (most likely in a separate thread).

    Best Regards,
    -DavidN
     
  3. tizoo

    tizoo Well-Known Member

    Joined:
    Jan 6, 2004
    Messages:
    66
    Likes Received:
    0
    Trophy Points:
    6
    Hi DavidN,

    Thanks a lot for your quick answer.

    The direct call seems not to be the solution. I effectively forgot to load the Email module but when I load it I have the following error :

    Code:
    [2011-06-02 16:49:32 +0200] warn [cpanel] Unable to run [Cpanel::Email::api2_addpop(4/8)]; No such file or directory at /usr/local/cpanel/Cpanel/Api2/Exec.pm line 90
    	Cpanel::Api2::Exec::api2_exec('Email', 'addpop', HASH(0x180973c0), HASH(0x18094890)) called at cpanel line 876
    	main::docpanelaction(HASH(0x18094900)) called at cpanel line 4984
    	main::run_fast_json_mode() called at cpanel line 413
    
    The PublicAPI seems to be the solution. But my development box is a WHM 11.28.87 on CentOS 5.5 x86_64 in a Xen VM and as stated in the documentation, the PublicAPI is not installed before 11.30. I then try to install the needed modules, but this seems a little bit hard to do for me as a non perl guru. In particular with MIME::Base64 certainly due to a version mismatch. Maybe the PublicAPI is more easy to call from CustomEventHandler since version 11.30 of WHM.

    I will try some other way to get the data I need for now. And maybe in a near future I will try on a 11.30 version with integrated PublicAPI.

    Thanks again for your answer DavidN and have a nice week-end.

    Best Regards,
    Philippe
     
Loading...

Share This Page