Integration options

While using the software as described in the "Usage" document might be enough for most users, you might want to take it further and introduce some specific actions to be run when your domain ownership gets verified or when you receive your domain certificate. This can be easily done with the external modules.

Client options related to external modules

Provided client supports the following options to integrate with third-party external modules:

  • handle-with <Some::Module> - Module name to handle challenges with.
  • handle-as <http|dns|tls|...> - Type of challenge to request, by default 'http'.
  • handle-params <{json}|file> - JSON (or name of the file containing it) with parameters for the challenge-handling module.
  • complete-with <Another::Module> - Module name to handle process completion with.
  • complete-params <{json}|file> - JSON (or name of the file containing it) with parameters for the completion-handling module.

External modules structure

Challenge handling modules

The module named in "handle-with" parameter will be handling the domain ownership pre- and post-verification. For example, for the challenge type of 'http' you might create required verification files either locally or remotely before the verification and then remove it after verification. For the challenge type of 'dns' you might do the same with the DNS records.

The structure of the module requires some methods defined for the challenge type of your choosing. On success, those methods should return a true value. For example, below are the methods which might be used for handling 'http' verification:

sub handle_challenge_http {
    my $self = shift;
    my ($challenge, $params) = @_;
    print "Challenge for '$challenge->{domain}'\n";
    print "Create a file '$challenge->{token}' in '/.well-known/acme-challenge/'\n";
    print "The text should be: '$challenge->{token}.$challenge->{fingerprint}'\n";
    print "Press <Enter>";
    return 1;

sub handle_verification_http {
    my $self = shift;
    my ($verification, $params) = @_;
    print "Domain $verification->{domain} " . ($verification->{valid} ?
          "has been verified successfully." : "has NOT been verified.") . "\n";
    print "You can now delete '$verification->{token}' file\n";
    return 1;

In a similar way, for other types of challenge, you will need appropriate methods defined, such as: handle_challenge_dns, handle_verification_dns, handle_challenge_tls, handle_verification_tls. You can use the provided example module as a template.

Completion handling modules

The module named in "complete-with" parameter will be handling the process completion. It will be getting the certificate and the file names of both the domain certificate and the domain key, so you could for example upload those to the location of your choosing.

The structure of the module requires just one method defined - "complete". On success, this method should return a true value. For example, the method could look like the code below:

sub complete {
    my $self = shift;
    my ($data, $params) = @_;
    print "Domain Certificate '$data->{certificate_file}':\n$data->{certificate}\n";
    print "Issuer's Certificate:\n$data->{issuer}\n";
    print "Key file: '$data->{key_file}'.\n";
    return 1;

You can use the provided example module as a template. You can also put the "complete" method into the challenge-handling module and use it for both tasks.

Passing parameters to external modules

As you could see in the examples above, the methods are receiving not only the data related to the challenge or completion, but also additional parameters through the use of '$params' variable. Those parameters for the external modules are defined with "handle-params" and "complete-params" client options. You can either pass them as a JSON document directly in the command line or save them into a file and give that file name instead.

Let's say you want a parameter "upload_to" with the value of "" to be available to both the challenge-handling and the completion-handling modules. To illustrate the different ways to do so, we will pass this parameter to the challenge-handling module directly in the command line, but to the completion-handling module we pass it as a file.

Let's create a file myparameters.json with the following content:

  "upload_to": ""

Then we pass the parameters in the command line like this: ... --handle-with Crypt::LE::Challenge::Simple --handle-params '{"upload_to": ""}' --complete-with Crypt::LE::Complete::Simple --complete-params myparameters.json

Despite the different methods of passing the parameters, the methods shown above could then use "$params->{'upload_to'}" to get the value of "".

Running commands from the external modules

If you need some complex action to be run by the external module but you do not know Perl well enough to implement that, then you might use the language you are familiar with instead and just run your program from the module. The easiest way to do that is to use the "system" command with arguments. See executing external commands guide for details.

Prev: Usage