Tag Archives: Code

Coding Amazon Echo Skills for Alexa with C#

Amazon Echo

Amazon Echo

I was reading this months CODE Magazine and there is an article about coding new Skills for Amazon Echo and Echo Dot to extend Alexa’s functionality. When you think about how you could extend Alexa to fit into your life, it could be well worth adding C# into your life. Amazon Echo is currently on offer for Mothers Day, with a £15 discount, maybe the time to get one. 

Lets say you want to check if a domain is registered, you could say “Alexa ask NominetTool if steven.uk is registered ?” or Alexa ask NominetTool who steven.uk is Registered to ?”. I guess depending on how accurate Alexa turns out to be, you could even try “Alexa ask NominetTool to Register steven.co.uk”.

I don’t have an Echo or Echo Dot, nor do I code in C# but this article does make it seem like a fun reason to learn. Its been maybe 10 yrs or more since I last opened VC++, and probably longer than that since I last wrote any reasonable amount of code. Looking at C# it doesn’t look that difficult once the new syntax makes sense. If I can pick up a cheap Echo or Echo Dot, I may just delve in to this. 

Looking at the code sample they provided…

HowTo.prototype.intentHandlers = {
   "RecipeIntent": function (intent, session, response) {
      var itemSlot = intent.slots.Item, itemName;
      
      if (itemSlot && itemSlot.value) {
         itemName = itemSlot.value.toLowerCase();
      }
      
      var cardTitle = "Recipe for " + itemName,
         recipe = recipes[itemName],
         speechOutput,
         repromptOutput;
      
      if (recipe) {
         speechOutput = {
            speech: recipe,
            type: AlexaSkill.speechOutputType.PLAIN_TEXT
         };
      
         response.tellWithCard(speechOutput, cardTitle, recipe);
      } else {
         var speech;
      
         if (itemName) {
            speech = "I'm sorry, I currently do not know the
                       recipe for " + itemName + ". What else can I help
                       with?";
         } else {
            speech = "I'm sorry, I currently do not know that
                       recipe. What else can I help with?";
         }
      
         speechOutput = {
            speech: speech,
            type: AlexaSkill.speechOutputType.PLAIN_TEXT
         };
      
         repromptOutput = {
            speech: "What else can I help with?",
            type: AlexaSkill.speechOutputType.PLAIN_TEXT
         };
      
         response.ask(speechOutput, repromptOutput);
      }
   },
      
   "AMAZON.StopIntent": function (intent, session, response) {
      var speechOutput = "Goodbye";
      response.tell(speechOutput);
   },
      
   "AMAZON.CancelIntent": function (intent, session, response) {
      var speechOutput = "Goodbye";
      response.tell(speechOutput);
   },
      
   "AMAZON.HelpIntent": function (intent, session, response) {
      var speechText = "You can ask questions such as, what's the
                 recipe, or, you can say exit... Now, what can I help you
                 with?";
      
      var repromptText = "You can say things like, what's the
                 recipe, or you can say exit... Now, what can I help you
                 with?";
      
      var speechOutput = {
         speech: speechText,
         type: AlexaSkill.speechOutputType.PLAIN_TEXT
      };
      
      var repromptOutput = {
         speech: repromptText,
         type: AlexaSkill.speechOutputType.PLAIN_TEXT
      };
      
      response.ask(speechOutput, repromptOutput);
   }
};

It looks quite simple to program, I guess you would use a PHP or C# web interface to execute the Recipes section, or in the example I gave to handle the domain name queries. Port the Whois Family Parser over to C# and you would be able to ask questions about whois result. 

Exciting times ahead. 

What You Need to Build A Domain Drop List

Nomient Logo

Nomient Logo

This article is going to be a 4 part jobby, with a few side articles possibly, as it turned out to be somewhat longer than I expected. Most people reading this blog will know what a drop list is, but you may not know how to make one or how much effort and expense goes into it. Currently a lot less effort goes into since Nominet released the zone files. The old way will be one of the side articles I cover another time.

What is a drop list is quite a simple question; a list of domains due to expire on any given day. I’m going to talk about what you need to build one in this post, and in the next one how you build your own drop list and the costs you will likely incur in both parts. After that it will be an article on maintaining the drop list and buying drop lists in the final part. Some of the methods are hard earned lessons, which will save you time. I won’t be giving all my secrets away, some will be old methods, so there are better ways to do it, but they still work. I will also be dropping in some chunks of code too, the missing bits will be easy enough with basic coding skills which I assume you have.

Where To Start ?

Building your own drop list, isn’t too hard. It is however quite costly and time consuming, not to mention fraught with rules from Nominet. The rules are somewhat open to interpretation so I’m not going to go there, better to speak to Nominet directly about them.

Nominet Membership

Firstly a Nominet Tag is required, which is FREE, however this isn’t enough, a Nominet Membership is required. This membership costs £400+Vat to Join, then £100+Vat per year membership.

You will also need DAC Access which is £25+VAT per year, that’s the last of the Nominet costs, but not the end.

A list of Fee’s are available here… Nominet Fee Schedule, you can see the main benefit here is the cost of domains at wholesale prices, but direct access to Nominet systems is essential for list building and drop catching.

Suitable Hosting

Suitable hosting is quite subjective, but I would recommend a VPS Hosting Account. This is because shared hosting almost certainly won’t be suitable. You’ll hit your resource limits and get an get somewhat unhappy email from your host, if not asking you to upgrade or sling your hook.

A suitable VPS will cost you anywhere from £10-30 per month. This is assuming you are comfortable and able to manage a Linux Server and install PHP, MySQL, Apache and manage the required security updates yourself. Otherwise a Managed VPS will be possibly £30-80+ per month, do your own research and choose wisely.

An important factor here to remember is, unlike with Drop Catching where the speed between your server and Nominet is Critical, in this instance it doesn’t matter at all, so cheap with a decent reputation and good support is your objective.

Alternatives to VPS and Shared Hosting

I have heard of people doing this on a business hosting account, which is often half way between a low end VPS and a standard shared account or more simply a shared hosting account with more resources.

There are also a number of people who have claim they used an install of WAMP (Windows, Apache, MySQL and PHP 0r MAMP (Mac, Apache, MySQL an PHP) on a local machine, machine on their network or even on their own PC.

You could also build such a thing on a local NAS Server like a Synology NAS Server or qNAP or any other for that matter. I personally have a test environment on one of my Synology units and see no reason most 2-Bay units wouldn’t be able to handle a project of this size.

These routes are worth looking in to, but I can’t comment on any of them with regards to efficacy, as I haven’t done them.

Apply for Zone File Access

Once you’re 1, a Nominet Member with DAC Access, 2, have your hosting sorted, you need apply to Nominet for Zone File access. You have to be a Nominet Member to gain access to this. When you’ve been granted Zone File access, you need to download and process the file. I blogged on the .UK Zone File Release, to give you an idea of the process.

Nominet Zonefile Zip File Content

Nominet Zonefile Zip File Content

The file you will download is around 240mb; a zip file which contains 9 unique files inside (see right). These are individual Zone File for each available extension under the .UK ccTLD, all managed by Nominet. Exacting them all will consume just over 1.5GB of storage, more or less depending on destination disk format.

Even though there are 9 files in the archive there are only 2 types of file.

1, Zone Files, these contain details about the zone, along with domains and their name servers. We won’t be using these, for drop lists we don’t need name servers.

2, Database Dump, which is a Comma Separated Value (CSV) file.

The CSV file is a literally just a list of domains, with nothing in there which makes it very very easy to process and quite fast. It will look like the list below…

domain1.co.uk
domain2.co.uk
domain3.net.uk
domain4.org.uk
domain5.uk

Its important to note, neither the individual zone files, or the database dump contain any dates, tags or anything more other than domain names or domain names, zone data and name servers.

In Part 2, I will discuss bringing the above together to actually build a drop list.

Extracting a Zip file with PHP

I recently had to make a quick script to extract the contents of a zip file, this zip file is copied via ftp from a remote server and stored locally. The file name to request and transfer is set via URL Encoding. This were originally a function, which I converted into a class and now devolved totally for this small script.

Sometimes quick and dirty tasks, require quick and dirty code, using the class would have been overkill. As usual there are a dozen ways to do this, and you could remove the error checks and echo’s to make the code even more compact.

// get the absolute path to $file ($file is set via the transfer process, but is JUST the file name no extension).
$path = pathinfo(realpath($file.'.zip'), PATHINFO_DIRNAME);
$link = $path.'/'.$file.'.zip';
$linkz = $path.'/'.$file.'.csv';
// assuming file.zip is in the same directory as the executing script.
	if (file_exists($linkz)) {
		die("<p>The .csv file exists, exit processs.</p>");
	} 
	if(file_exists($link)){
		echo "<p>The $link exists, and $linkz file doesn't exist.</p>";		
		//prepare for handling a zip file.
		$zip = new ZipArchive; 
		// load the zip file.
		$res = $zip->open($file.'.zip');
		if ($res === TRUE) { // check the file has been loaded.
			echo "<p>Extracting File...</p>";
			$zip->extractTo($path); //begin extracting file
			$zip->close(); //unloa and release the zip file.
			echo "<p>$file.zip extracted to $path</p>";
		} else {
			echo "<p>Doh!, stupid $file.zip wouldn't open.</p>";
		}
	}else{

		die("<p>$file.zip doesn't exist, exit process.</p>");

	}

Its a little messy, but were procedural code, converted into a function, then part of a class and back to a procedural layout.

.UK Family Whois Splitter

I were looking for a snippet of code for someone when I came across an old tool. This isn’t a parser or a tool like phois or similar, its just a usable snippet of code to do a job. Really I should update it, and maybe use a function to handle the job, but it works just fine for its use.

The job in this instance were to monitor my domains for changes in status, in a few situations.

1, When a domain were sold, I monitored the tag and registrant name (now I’m using the DAC I only monitor the tag for .uk).
2, When using another registrar/registry I monitored expiry to avoid losing domains due to non-renewal or errors.

In order to do this, I needed code to (1), connect to a whois server (this is easy),  (2), split the required bits of info from the result (not so easy) and (3), place it in a database (easy). Then work on the data from there, (4), load the “watched”, “sold” or “close to expiry” domains, (5), scan the whois and compare, then (6), act on the result.

90% of the various registries whois outputs, out there are fairly uniform, but much like Nominets EPP, their whois is non-standard, so I needed a custom splitter. I’m not sure I would do it the same if I wrote the code now… some years later.

I have updated the code a little to include a ROFR (Right of First Refusal) detection, this won’t be needed come june (2019) when the period expires.

switch(trim($ext)){
	case "uk":
		$def = array();
		if(preg_grep("/Right of reg/", $arr)){
			$def['domain'] = $arr[1];
			$def["rofr"] = $arr[3]; 
			$type = "rofr";			
			break;	
		}

		$def['domain'] = $arr[1];
		$def['registrant'] = $arr[3]; 

		preg_match('/Tag = (.*)]/', $res, $matches);
		$def['tag'] = trim($matches[1]);
			
		preg_match("/Registered on: (.*)/", $res, $matches);
		$def['created'] = date("Y-m-d",strtotime(trim($matches[1])));
			
		preg_match("/Last updated: (.*)/", $res, $matches);
		$def['updated'] = date("Y-m-d",strtotime(trim($matches[1])));
				
		preg_match("/Expiry date: (.*)/", $res, $matches);
		$def['expiry'] = date("Y-m-d",strtotime(trim($matches[1])));

		$type = "uk";	
		break;

	default:
		break;
}

This will produce an array called $def, which when calling a valid name would look like…

Array
(
    [domain] => steven.uk
    [registrant] => Steve Morley
    [tag] => MORLEY
    [created] => 2014-06-12
    [updated] => 2016-02-29
    [expiry] => 2024-06-12
)

or if the the .UK has right of first registration intact…

Array
(
    [domain] => steven.uk
    [rofr] => steven.co.uk
)

Working from this array, you can you can put these into a database, compare them to the database return and act on it from there. I suggest sending yourself an email or text message (api’s are easy to follow).

Querying The Dac with PHP

I see the same thing over and over, and some people imply or suggest its easy or incredibly hard to connect and query/poll the Nominet DAC (Domain Availability Checker) to get basic data about a domain.

There are a few reasons you would want to do this, the main ones are to build a drop list database or build a drop catching script, but both are built on the same foundations.

Before you can use this, you need to be a Nominet Member, and have a DAC Subscription, but you can access the DAC Testbed for Free without Membership or Subscription.

I’m going to use a high level language for this example, which in this case is PHP, but Perl is faster, and a low level compiled language like C would be way way quicker, but PHP is more than adequate for database building and non-prime drop catching.

Basic Connect to and Poll the Dac

<?php 
$sock = socket_create(AF_INET, SOCK_STREAM, 0); 
echo "Socket Created.<br>";
socket_connect($sock , 'dac.nic.uk' , 3043); 
//change dac.nic.uk to testbed-dac.nominet.org.uk to access testbed.
echo "Socket Connected.<br>";
socket_send ($sock, "steven.co.uk\r\n", 16, 0);
echo "Message Sent.<br />";
$resp = socket_read($sock, 1000);
echo "Response: $resp.  <br />";
socket_send ($sock, "#exit\r\n", 9, 0);
echo "Dac Session Exit Sent.<br />";
socket_shutdown($sock, 2);
echo "Socket Shutdown.<br />";
socket_close($sock);
echo "Socket Closed.<br />";
?>

The above code will result in the following output, it really is as simple a half a dozen lines of code,.

Socket Created.
Socket Connected.
Message Sent.
Response: steven.co.uk,Y,N,1998-08-18,2022-08-18,MORLEY.
Dac Session Exit Sent.
Socket Shutdown.
Socket Closed.

You can now act upon the returned $resp variable, explode it into manageable chunks like…

$dac = split(",",$resp);
echo "Split Dac. <br />";

This will return an array of 6 blocks numbered 0-5, which will be…

Array(
    [0] => steven.co.uk
    [1] => Y
    [2] => N
    [3] => 1998-08-18
    [4] => 2022-08-18
    [5] => MORLEY
)

From here you can put it into a database…

Query a List of Names

Its most likely you would want to add some sort of loop to load a list of names…

<?php 
$arrList = array("steven.uk", "steven.co.uk");
$sock = socket_create(AF_INET, SOCK_STREAM, 0); 
socket_connect($sock , 'dac.nic.uk' , 3043); 

foreach($arrList as $message) {
 socket_send ($sock, $message . "\r\n", len($message)+4, 0);
 $resp = socket_read($sock, 1000);
 echo $resp;
}

socket_send ($sock, "#exit\r\n", 9, 0);
socket_shutdown($sock, 2);
socket_close($sock);

?>

Thats the basics covered where most people seem to strugle, its really endless where you can take a script.

I may revisit this code in future and expand on it, but for now, lets see what you do with it.