Send Domain Renewal and Expiry Notifications using Namecheap API, Twilio SMS and PHP

June 12, 2019
Written by
Michael Jaroya
Contributor
Opinions expressed by Twilio contributors are their own

Send Domain Renewal and Expiry Notifications using Namecheap API, Twilio SMS and PHP.png

According to Domain Name Industry Brief a report by VeriSign,a global leader in domain names and Internet security, there were approximately 342.4 million domain name registrations across all top-level domains (TLDs)  by the third quarter of 2018, an increase of approximately 2.6 million compared to the second quarter of 2018. This means approximately 28000 domain names were registered per day, and recent projections show the numbers are expected to rise even further in 2019. The stakeholders in this sector, therefore, have to implement a number of systems to manage and automate the huge number of tasks and business processes involved. Domain name sellers, resellers, domain name managers and even individual users need to get domain name related notifications in a timely and reliable manner to efficiently manage their domains.

In this tutorial, we are going to discuss how to send domain name renewal and expiry notifications in Vanilla PHP using Namecheap API and Twilio SMS.

Prerequisites

To follow this tutorial, you need:

Setting up Namecheap Account

Create both sandbox and production Namecheap accounts if you haven’t already, and then request for API access.

The steps to enable API access are similar in both sandbox and production environments. To enable API access, follow these steps:

  • Login to your Namecheap account.
  • Go to the Profile > Tools menu.
  • Scroll down to the “Business & Dev Tools” section. Click MANAGE, next to Namecheap API Access.
  • Toggle ON/OFF, read the Terms of Service, enter your account password.

NOTE: You should test your API calls in the sandbox environment and only point them to production once you are sure they are working correctly.

For your Namecheap API calls to work, you need to allow your impacted IPs. These IPs are a list of IPs that are considered to be spam-free and trustworthy.

To add an IP, go to the API page described above, click EDIT and add the IP(s).

Setting up PHP Application

First, we need to install the Twilio PHP SDK using Composer. In your terminal, navigate to your project directory and run the command below:

$ composer require twilio/sdk

Next, we need to install the PHP dotenv package to avoid storing sensitive credentials in the codebase. The package loads configuration variables from the .env file and makes them accessible in our application. In the project directory, run the command below:

$ composer require vlucas/phpdotenv

Create an  .env file in the root directory of your PHP application and update it with credentials from your Twilio and Namecheap dashboards as shown below:

NAMECHEAP_KEY="Your Namecheap key"
NAMECHEAP_USERNAME="Your Namecheap username"
IP_ADDRESS="Your IP address"
TWILIO_SID="Your Twilio SID"
TWILIO_AUTH_TOKEN="Your Twilio Auth Token"
TWILIO_PHONE_NUMBER="Your Twilio SMS enable phone number"

Creating Our Application

Now that we are done with configurations, let's create our application. We are going to use the Namecheap PHP SDK by Maksym Karazieiev. The SDK is simple and easy to use.

Clone the repository and copy the contents of src/Namecheap into your application.

Since the tests are done in a sandbox environment, we need to create virtual domain names to simulate how our API calls would work in production.

Just like in production, you first need to check for domain name availability before purchase and thereafter proceed to register it.

Create a file create.php in the root directory of your application. Open the file and add the code below:

<?php

require_once( 'vendor/autoload.php' );
include_once( 'Api.php' );

// load .env files
$dotenv = Dotenv\Dotenv::create( __DIR__ );
$dotenv->load();

/**
* check domain name availability
*
* @param $config
* @param $domain_names array
*
* @return \Namecheap\Namecheap\Command\ACommand
*/
function checkAvailability( $config, $domain_names ) {
  try {
     $command = Namecheap\Api::factory( $config, 'domains.check' );
     $command->domainList( $domain_names )->dispatch();
  } catch ( \Exception $e ) {
     die( $e->getMessage() );
  }

  return $command;
}

/**
* Register a domain name
*
* @param $params
* @param $config
*
* @return string
*/
function createDomain( $config, $params ) {
  try {
     $command = Namecheap\Api::factory( $config, 'domains.create' );
     $command->setParams( $params )->dispatch();
  } catch ( \Exception $e ) {
     die( $e->getMessage() );
  }

  return $command;
}
// code for checking domain name availability and domain name registration
$config = new \Namecheap\Config();
$config->apiUser( getenv( 'NAMECHEAP_USERNAME' ) )
      ->apiKey( getenv( 'NAMECHEAP_KEY' ) )
      ->clientIp( getenv( 'IP_ADDRESS' ) )
      ->sandbox( true );
$domain_list  = array( 'twilio.com', 'sendgrid.com' );
$check_create = checkAvailability( $config, $domain_list );
foreach ( $check_create->domains as $domain => $available ) {
  if ( $available === true ) {
     // all parameters are mandatory
     $domain_details = array(
        'DomainName'              => $domain,
        'RegistrantFirstName'     => 'Twilio',
        'RegistrantLastName'      => 'Inc',
        'RegistrantAddress1'      => '0000',
        'RegistrantCity'          => 'San Francisco',
        'RegistrantStateProvince' => 'California',
        'RegistrantPostalCode'    => '00000',
        'RegistrantCountry'       => 'UNITED STATES',
        'RegistrantPhone'         => '+1.555555555',
        'RegistrantEmailAddress'  => 'admin@twilio.com',
        'TechFirstName'           => 'Twilio',
        'TechLastName'            => 'INC',
        'TechAddress1'            => '0000',
        'TechCity'                => 'San Francisco',
        'TechStateProvince'       => 'California',
        'TechPostalCode'          => '00000',
        'TechCountry'             => 'UNITED STATES',
        'TechPhone'               => '+1.555555554',
        'TechEmailAddress'        => 'tech@twilio.com',
        'AdminFirstName'          => 'Twilio',
        'AdminLastName'           => 'INC',
        'AdminAddress1'           => '0000',
        'AdminCity'               => 'San Francisco',
        'AdminStateProvince'      => 'California',
        'AdminPostalCode'         => '00000',
        'AdminCountry'            => 'UNITED STATES',
        'AdminPhone'              => '+1.555555555',
        'AdminEmailAddress'       => 'ladmin@twilio.com',
        'AuxBillingFirstName'     => 'Twilio',
        'AuxBillingLastName'      => 'INC',
        'AuxBillingAddress1'      => '0000',
        'AuxBillingCity'          => 'San Francisco',
        'AuxBillingStateProvince' => 'California',
        'AuxBillingPostalCode'    => '00000',
        'AuxBillingCountry'       => 'UNITED STATES',
        'AuxBillingPhone'         => '+1.555555557',
        'AuxBillingEmailAddress'  => 'auxbil@twilio.com',
     );
     $command        = createDomain($config,$domain_details );
     if ( $command->status() == 'error' ) {
        print_r( $command->errorMessage )."<br>";
     }
     print_r($command)."<br>";
  }
}

Creating Notifications Functions

With the domain names registered in our sandbox account, we can write code to send renewal and expiry SMS notifications.

The first step is to get a list of all the domains associated with a user using Namecheap API method getList. The method returns all domain details such as the name and expiry date. Create a file index.php in the root directory of your application and add getDomainList function:

<?php

include_once( 'Api.php' );

/**
* get list of domains and their details
* @return \Namecheap\Namecheap\Command\ACommand
*/
function getDomainList( $config ) {
  try {
     $command = Namecheap\Api::factory( $config, 'domains.getList' );
     $command->dispatch();
  } catch ( \Exception $e ) {
     die( $e->getMessage() );
  }

  return $command->domains;
}

Next, we need to get the contact information of the requested domain using Namecheap API method getContacts. We can then extract the registrant and admin phone numbers from that information. Open index.php and add the getContacts function:

<?php

include_once( 'Api.php' );

/**
* get domain contact information
* @param $config
* @param $domain_name
*
* @return mixed
*/
function getContacts( $config,$domain_name ) {
  try {
     $command = Namecheap\Api::factory( $config, 'domains.getContacts' );
     $command->domainName( $domain_name )->dispatch();
  } catch ( \Exception $e ) {
     die( $e->getMessage() );
  }

  return $command;
}

We also need a function to renew an expiring domain using Namecheap API method renew. Add the renewDomain function:

<?php

include_once( 'Api.php' );

/**
* renew domain name
*
* @param $config
* @param $domain_name
* @param $years
*
* @return \Namecheap\Namecheap\Command\ACommand
*/
function renewDomain( $config, $domain_name, $years ) {
  try {
     $command = Namecheap\Api::factory( $config, 'domains.renew' );
     $command->setParams( array(
        'DomainName' => $domain_name,
        'Years'      => $years
     ) )->dispatch();
  } catch ( \Exception $e ) {
     die( $e->getMessage() );
  }

  return $command;
}

Finally, let’s create a function to send an SMS using the Twilio API. Open index.php and add the sendSMS function:

<?php

use Twilio\Rest\Client;

/**
* send Twilio SMS
*
* @param $to
* @param $sms_body
*/
function sendSMS( $to, $sms_body ) {
// Your Account SID and Auth Token from twilio.com/console
  $sid    = getenv( 'TWILIO_SID' );
  $token  = getenv( 'TWILIO_AUTH_TOKEN' );
  $client = new Client( $sid, $token );
  $client->messages->create(
     $to,
     array(
        // A Twilio phone number you purchased at twilio.com/console
        'from' => getenv( 'TWILIO_PHONE_NUMBER' ),
        // the body of the text message you'd like to send
        'body' => $sms_body
     )
  );
}

That is all we need to send domain renewal and expiry notifications. Let’s put all the functions together and send notifications. Add sendNotifications function to index.php:

<?php

require_once( 'vendor/autoload.php' );
include_once( 'Api.php' );

use Twilio\Rest\Client;

// load .env file
$dotenv = Dotenv\Dotenv::create( __DIR__ );
$dotenv->load();

/**
* Send all notifications
*
* @param $config
*/
function sendNotifications( $config ) {
  $domains = getDomainList( $config );
  foreach ( $domains as $domain ) {
     $contact                 = getContacts( $config, $domain['Name'] );
     $phone_numbers           = [];
     $registrant_phone_number = str_replace( ".", "", $contact->registrant['Phone'] );
     $admin_phone_number      = str_replace( ".", "", $contact->admin['Phone'] );
     if ( $registrant_phone_number != "" ) {
        array_push( $phone_numbers, $registrant_phone_number );
     }
     // ensure registrant and admin phone numbers are not the same to avoid duplicate SMS
     if ( $admin_phone_number != "" && $admin_phone_number != $registrant_phone_number ) {
        array_push( $phone_numbers, $admin_phone_number );
     }
     // domain name expiry notifications
     if ( $domain['IsExpired'] === true ) {
        $expiry_message = "Your domain " . $domain['Name'] . " has expired.Go to your dashboard to reactivate";
     } else {
        // to avoid spamming your users you should start sending this message 2 or 1 month before the domain expiry date.
        $expiry_message = "Your domain " . $domain['Name'] . " will expire on " . $domain['Expires'] . ".";
     }
     //calculate date difference
     $now                  = time(); // today's timestamp
     $expiry_date_array    = explode( "/", $domain['Expires'] );
     $reformat_expiry_date = $expiry_date_array[2] . "-" . $expiry_date_array[0] . "-" . $expiry_date_array[1];
     $expiry_date          = strtotime( $reformat_expiry_date );
     $datediff_days        = round( ( $expiry_date - $now ) / ( 60 * 60 * 24 ) );
     $renewal_status       = false;
     // renew domain 30 days to expiry date
     // domain name renewal notifications
     if ( $datediff_days < 30 && $datediff_days > 0 ) {
        $renew = renewDomain( $config, $domain['Name'], 1 );
        if ( $renew->status() == 'error' ) {
           die( $renew->errorMessage );
        }
        $renewal_message = "Your domain " . $domain['Name'] . " has been renewed successfully.";
        $renewal_status  = true;
     }
     foreach ( $phone_numbers as $phone_number ) {
        sendSMS( $phone_number, $expiry_message );
        if ( $renewal_status ) {
           sendSMS( $phone_number, $renewal_message );
        }
     }
  }
}

$config = new \Namecheap\Config();
$config->apiUser( getenv( 'NAMECHEAP_USERNAME' ) )
      ->apiKey( getenv( 'NAMECHEAP_KEY' ) )
      ->clientIp( getenv( 'IP_ADDRESS' ) )
      ->sandbox( true );
sendNotifications( $config );

Testing the App

To test the app, you first need to create one or more domains in your Namecheap sandbox account. You can create the domain(s) manually from your sandbox dashboard or update the details in create.php and hit the URL base_url/create.php in the browser.

Once you have created the domains, you can then test the notifications by hitting the URL base_url/index.php in the browser. You should get messages similar to the one shown in the screenshot below.

Example renewal messages from NameCheap and Twilio

Note: Remember to update the code to production by setting “sandbox” parameter to false and updating your API keys with your production Namecheap API keys when you move to a production environment.

Conclusion

In this tutorial, we have used Namecheap API and Twilio SMS to send SMS notifications. We have just scratched the surface of what you can do using Namecheap API. Apart from domain name renewal and expiry notifications, you can also use Namecheap API for DNS management, domain transfer, SSL management and so much more. The code is available on Github.

I would love to know what you build using the API.

Feel free to reach out to me: