domeneas

Active Member
Sep 20, 2013
44
6
58
cPanel Access Level
Root Administrator
I am trying to write a hook that changes the Mail Exchange to "Auto" after account creation as this is something Cpanel still hasn't given us the ability to do as standard from what I can tell.

I have written this:
Code:
#!/usr/bin/perl

# Package this module.
package mxauto;

# Return errors if Perl experiences problems.
use strict;
use warnings;

# Use cPanel's error logging module.
use Cpanel::Logger;

# Use the core Perl module with file-copying functionality.
use Cpanel::LiveAPI ();

# Properly decode JSON.
use JSON;

# Instantiate the cPanel logging object.
my $logger = Cpanel::Logger->new();

# Embed hook attributes alongside the action code.
sub describe {
    my $hooks = [
        {
            'category' => 'Whostmgr',
            'event'    => 'Accounts::Create',
            'stage'    => 'post',
            'hook'     => 'mxauto::setmxauto',
            'exectype' => 'module',
        }
    ];
    return $hooks;
}

# Set the file names.

sub _more_logging {
    my ( $context, $data ) = @_;
    my $pretty_json = JSON->new->pretty;
}

sub setmxauto {
    # Get the data that the system passes to the hook.

    my ( $context, $data ) = @_;

#    Add a log entry for debugging.
    $logger->info("*** Dumping relevant data $data->{user} $data->{domain} ***");

#Set Mail Exchanger to AUTO

my $cpliveapi = Cpanel::LiveAPI->new(); # Connect to cPanel - only do this once.

# Set example.com's mail exchanger type.
my $set_mx_type = $cpliveapi->uapi(
    'Email', 'set_always_accept',
    {
        'domain'        => 'tullball.no',
        'mxcheck'       => 'auto',
        'alwaysaccept'  => '1',
    }
);    $logger->info("*** MX for {domain} set to AUTO. ***");

};

1;
I receive the following error.


[2021-05-12 12:29:19 +0200] warn [whostmgr5] Can't call method "uapi" on an undefined value at /usr/local/cpanel/mxauto.pm line 56.
at /usr/local/cpanel/Cpanel/Hooks.pm line 545.


This is driving me nuts. I can find one other thread on the forum here specifically for Cpanel::LiveAPI and the same issue, but that was only resolved when the user abandoned this approach and used other methods apart from LiveAPI in hooks.

Running this in shell works fine:
Code:
uapi --user=tulluser Email set_always_accept domain=tullball.no mxcheck=auto
 
Last edited by a moderator:

cPRex

Jurassic Moderator
Staff member
Oct 19, 2014
6,984
922
313
cPanel Access Level
Root Administrator
Hey there! I'm wondering if this is an issue with the following statement we note in our documentation:

"This parameter is redundant with the mxcheck parameter. Do not enter the mxcheck and alwaysaccept parameters at the same time. Undefined behavior may occur if this happens."


Can you try tweaking that area to see if that gets things working? I removed the "'alwaysaccept' => '1'," entry on my side with a test and the hook ran without errors.
 

domeneas

Active Member
Sep 20, 2013
44
6
58
cPanel Access Level
Root Administrator
I read that as well and have tried both without luck. Your documentation includes both, just as a note. It's quite unclear to me what the difference actually is. With the CLI command "alwaysaccept" does not do anything, while "mxcheck" works.


When I run the code, the only difference beeing the removal of "'alwaysaccept' => '1',", as is done in my Command Line example, I get the exact same error.

Could you post an example of running a UAPI command from a hook? I find examples of hooks and UAPI, but never together.

Or even better, point to where my code is wrong.

Here is the important bit I changed, removing the "alwaysaccept" and changing the lines calling the actual function "Email::set_always_accept" after the "my $set_mx_type = $cpliveapi->uapi(" line that tosses the error, to match your example in the new documentation: I also tried without changing the 2 lines calling the function and just removing "alwaysaccept" as in the example in the first post with the exact same result.

Code:
# Set example.com's mail exchanger type.
my $set_mx_type = $cpliveapi->uapi(
    q/Email/,
    q/set_always_accept/,
        {
        'domain'        => 'tullball.no',
        'mxcheck'       => 'auto',
        }
    );    
    $logger->info("*** MX for {domain} set to AUTO. ***");
    $cpliveapi->end();
 

cPRex

Jurassic Moderator
Staff member
Oct 19, 2014
6,984
922
313
cPanel Access Level
Root Administrator
I talked to one of our developers and was provided with this example:

Code:
#!/usr/local/cpanel/3rdparty/bin/perl
package mxremote;

use strict;
use warnings;

sub setmxremote {
  my ( $context, $data ) = @_;
  my $set_mx_type = qx[ uapi Email set_always_accept --user=$data->{user} domain=$data->{domain}
  mxcheck=remote ];
  };

1;
Can you try working with that to see if that provides better results? Please keep in mind our support for custom code is very limited.
 
  • Like
Reactions: domeneas

domeneas

Active Member
Sep 20, 2013
44
6
58
cPanel Access Level
Root Administrator
Thank you. That worked.

I set it to "auto" instead of "remote", allthough it seems to have had the same result in both cases oddly enough. Both setting it to "Auto" when viewing the setting in cpanel.

Would love to see some of this in the documentation as I am sure it is reusable in many cases.

I have attached my final working hook incase anyone should find this thread in the future.

Thanks again.

Code to run a UAPI command in a hook (post account creation, set mail exchange to auto)
Code:
#!/usr/bin/perl

# Package this module.
package mxauto;

# Return errors if Perl experiences problems.
use strict;
use warnings;

# Use cPanel's error logging module.
use Cpanel::Logger;

# Properly decode JSON.
use JSON;

# Instantiate the cPanel logging object.
my $logger = Cpanel::Logger->new();

# Embed hook attributes alongside the action code.
sub describe {
    my $hooks = [
        {
            'category' => 'Whostmgr',
            'event'    => 'Accounts::Create',
            'stage'    => 'post',
            'hook'     => 'mxauto::setmxauto',
            'exectype' => 'module',
        }
    ];
    return $hooks;
}

sub _more_logging {
    my ( $context, $data ) = @_;
    my $pretty_json = JSON->new->pretty;
}

sub setmxauto {
    # Get the data that the system passes to the hook.
    my ( $context, $data ) = @_;

#    Add a log entry for debugging.
    $logger->info("*** Attempting to change mail exchanger to auto for user $data->{user} $data->{domain} ***");

#    Set mail exchange to auto  
    my $set_mx_type = qx[ uapi Email set_always_accept --user=$data->{user} domain=$data->{domain}
    mxcheck=auto ];

#    Confirmation of good run in log
    $logger->info("*** MX for $data->{domain} set to AUTO. ***");
   
};

1;
 
  • Like
Reactions: cPRex