Tuesday, July 21, 2015

RCON Client in Haskell

Source RCON is a TCP/IP based communication protocol, which can be used to issue console commands to the server via a remote console. The most common use of it, is to allow the server owners to control their game server properties without physically accessing the server. In order to use this, first one should be authenticated using the server's RCON password. 

Step 1: Setup the Minecraft server

To start off with the developing the RCON client, you should first establish a server to test your client. For this I'm using Minecraft. You can download the Minecraft server here, and run it. When started it creates a file called 'server.properties' in your working directly and shuts down immediately. The first step of configuration is to open the file 'EULA.txt' ( do not use a rich text editor like Wordpad, use Notepad, Gedit, etc ), and change 'eula=false' to 'eula=true'

Then edit your 'server.properties' manually to say 'enable-rcon=true'. Then save it and run the server again. Then edit the 'server.properties' file again to add your 'rcon.password'. After these steps, your 'server.properties' file should look like this;

Step 2: Establish a connection with the Minecraft server

In order to start with the development, first you should establish a connection with the server. In this step we need to identify a way to build a simple connection over the network using sockets.

Here 'Network.Socket' package is being used to create a connection with the server. First a socket is created using 'AF_INET' as the socket family, 'Stream' as the socket type, along with a default protocol.  
When we run this code after starting the Minecraft server, if you have got it correct it prints a log entry in the log file indicating the connection as follows; 

Step 3: Sending data over the network

Understanding the format of the data packets accepted by the server is a crucial part before sending data over the network. To understand this please go through the documentation at this page

According to the documentation we can build a Haskell data constructor to send our data over the network as follows;

First we need to build the data packet encapsulating the data we need to send over the network, and arrange them as a byte array to be sent over the network. In this code I have used 'Network.Socket.ByteString' send and receive data over the network. Since its 'send' method accepts a ByteString, the byte array needs to converted into a ByteString to feed into this method. 

Here the byte array representation of data in Haskell is a [Word8]. I've used 'Data.Bits' package to convert the Int values to [Word8] as follows;

And then this array of Word8 elements is packed into a ByteString using the 'pack' method in 'Data.ByteString' package. 

The complete code can be found at my GitHub repository

Monday, July 13, 2015

Develop a Mailchimp library with Haskell

Mailchimp is a free email marketing service provider. It helps you to design email newsletters, share them on social networks, integrate with services you already use and track your results. 

Haskell is an advanced purely-functional programming language, which has improved performs than other imperative languages. 

I have developed a library in Haskell interacting with the JSON API in Mailchimp, which enables one to do the following tasks with respect to a mailing list in Mailchimp;
  • Add subscribers
  • List subscribers in a particular mailing list
  • List mailing lists for a particular user account
  • Past activities performed on a given mailing list
Before starting off with the implementation, you should understand the functionalities we can perform on a mailing list in Mailchimp. For that, you should create a mailing list in Mailchimp. So, let's first go through the steps of creating a mailing list in Mailchimp (Here I'm referring to version 2.0 API)

Create a mailing list in Mailchimp
  1. After creating an account in Mailchimp, first thing you have to do is the creation of an 'apikey', which provides the authentication purpose in the JSON API in Haskell
    • Navigate to your 'Account'
    • Then go to the 'API keys' from the drop down menu in 'Extras'

    • Then create an API key from the menu
  2. Then create a mailing list according to your/client's preferences
  3. Then try adding couple of subscribers from the web interface and explore the functionalities available

Implementation of library

After that I recommend you to read the Mailchimp API documentation. This one is the Mailchimp version 2.0. Pay a closer attention towards the sample JSON requests and responses. 

Then select the functionality you want in your library, and start coding. In my library I have selected the above mentioned functionalities.

The first step of the implementation is the construction of the EndPoint URL, since all of the method descriptions in the API documentation are relative to it. The format of the end-point URL is as follows; `https://<dc>.api.mailchimp.com/2.0/SECTION/SOME_METHOD.OUTPUT_FORMAT`, where `<dc>` refers to the data-center prefix. 

The data-center prefix is the last part of your apikey separated by the "-" character. In order to retrieve the end-point URL you need to extract it. Here is a snapshot of my implementation of it;

One of the main sections, that you must pay attention is the exception handling in HTTP requests and responses. 

In my implementation I have used the `catch` method imported from `Control.Exception` package.

As explained in the Hackage documentation the statement which throws the exception is encapsulated within the catch statement, and then in the handler function the thrown `StatusCodeException` is handled by calling the `getResponse` function.

Here the `StatusCodeException` has 3 parameters, they are; Status, ResponseHeaders, and CookieJar as explained in the Hackage documentation.  

These are then passed into `getResponse` function. Using those 3 components it builds a Response of the same format as `withManager $ httpLbs req`.

Here is the link to the GitHub repository of my code, which is a work in progress. I hope to further develop it to support Mailchimp version 3.0 in the future.