Skip to content
This repository
tree: 7fb5bf68f7

Fetching latest commit…

Octocat-spinner-32-eaf2f5

Cannot retrieve the latest commit at this time

Octocat-spinner-32 _build
Octocat-spinner-32 lib
Octocat-spinner-32 tests
Octocat-spinner-32 README.markdown
Octocat-spinner-32 _build.cfg
README.markdown

The chatterl application

Copyright © 2008-2009 Yomi Colledge

Version: Jan 15 2009 01:45:25

Authors: Yomi (baphled) Colledge.

Description

A multi processed chat system that can be housed over a number of nodes & track clients over varying devices, at the time of the writing the system works over multiple nodes & is able to do the basics (connect to a group, send message to other clients & connected groups).

The main focus of this project is to create a chat system that is highly reliable as well as scaleable. Other developers will be able to create add-on modules that are able to interact with chatterl & further enhance the functionality of chatterl & the chatterl clients experience.

Installing Chatterl

As mentioned the system is OTP based, of which it uses Sinan to maintain its builds. At the moment of this writing Chatterl is still in alpha so their is no real release at the moment, to get it running you will need to do the following:

git-clone git://github.com/baphled/chatterl.git &&
cd chatterl &&
sinan doc && 
sinan dist &&
cd _/build/development/tar &&
sudo faxien install-release chatterl-0.1.1.0.tar.gz

The above presumes that you have Sinan configured & installed, if you haven't refer to erlware. You will need to change to cookie & name values to something else, doing so should drop you into the erlang shell & ready to run the Chatterl application.

Running Chatterl

To run a client on a different machine you will need to do the above if (making sure that the -sname is not the same as any other connected nodes & that the cookie is the same) if connecting on the same box simply cd to the ebin directory & run the following command:

erl -s chatterl -s reloader -name bar -setcookie abc

Bar being the name you want use to identify the erlang node.

From here you will need to make sure that they nodes can connect using the below command from another node:
net_adm:ping(foo@bar.net).

Where foo is the node name & bar.net is the tld of the node box (indicated within yout hosts file or dns server). Once you receive the infamous pong response you are ready to roll.

Features

  • Client login/logout to Chatterl.
  • List Chatterl groups.
  • List Chatterl users.
  • Login/logout of a chatterl group.
  • Send message to a group & other clients.
  • A RESTful API

Future Features

  • Centralised Error logging & data storage.
  • Client customisable routines (able to poll RSS feeds, twitter, FB & the such like).
  • Better handling of errors.
  • User registration.
  • FB Connect.
  • Chat bots (AIML based).
  • Web frontend (using BeepBeep).
  • Chat modules handler(banning, censorship, chatbots).

Useage

At the moment of this writing there are two ways to interact with Chatterl, through a Erlang shell or via CWIGA, which gives you the ability to interact with Chatterl via a RESTful API.

Shell Interaction

Starting the server
erl -s chatterl

Chatterl server runs as an OTP application & uses a supervisor to manage it (in later versions there will be options to spawn multiple servers, allowing for a more fault tolerant chat system). To start up the server you simply need to run the following command:

Which will initialise the server & CWIGA The backend allowing clients to connect & groups to be created & admin the ability to manage the system. Groups can be created on differing nodes as long as the node can communicate with the chatterl_serv.

CWIGA allows for developers to interact with the API, giving them the ability use the basic CRUD functionalities of Chatterl as well as handle clients along with thier messages & other functionality.

Starting a group
chatterl_serv:create("room","description").

Which will spawn a group process which users can connect to.

Chatterl groups can be started on any node that can communicate with the server, this allows the user to create a number of groups on varying nodes, helping with general organisation as well a performance & reliablity.

Connection to chatterl
chatter_client:start(UserName).

Creating a connection to the server is done by using the following command.

At the time of this writing chatterl_clients can only spawn a client per node, this will later be changed once the web interface has been fully implemented, possibly to a refactoring the client to a parameterised module. For the moment node users must follow the basic OTP configurations (same cookie, valid DNS name, etc).

This will initialise a user & connect them to chatterl_serv (must be done before users can join a group or communicate with other chatterl users).

Disconnecting from chatterl
chatterl_client:stop().

This will disconnect the user from all the groups they are currently connected to as well as the actual Chatterl server.

Joining a group
chatterl_client:join(GroupName).

If the group exists the user is able to join the group allowing them to send message to the room.

Dropping from a group
chatterl_client:drop(GroupName).

This will send a message to the group, which will handle the termination.

Sending group message
chatterl_client:send_msg(GroupName,Message).

GroupName being the name of the group the client is connected to, Message being the message that you want to send to the receiving client. If the message is sent successfully all users connected to the group will receive the message.

Sending a private message
chatterl_client:private_msg(RecipientName,Message).

This allows a Chatterl client to send a private message to another client.

If the message is sent successfully then the sender will receive follow message:
{ok,msg_sent}

in turn sending the message to the receipients node.

CWIGA

CWIGA Brief

CWIGA handles all interaction with Chatterl, though for the moment the basics have only been implemented. It can respond in both XML & JSON (at the moment of writing only XML is functional).

CWIGA responsed coming in a standardised structure, allowing for easy parsing and searching of data, all data is represented in the following formats:
  • JSON
  • XML
Any unrecognised formats will fall back to JSON, as it is the default response format. Defining the prefered format can been done by appending the corresponding path extension to the query string
http://CWIGAURL:9000/users/some_group/list.xml

will retrieve the user list of some_group in XML format.

Response Types

CWIGA has three types of responses which are as follows:

  • Success
  • Failure
  • Error

Success When ever a response has been successfully retrieved from Chatter, returning with a 200 HTTP response code along with the corresponding response structure (see Response Structures).

Failure When a Chatterl responds with a failure (user cannot connect), CWIGA in turn responds with failure, returning with a 200 HTTP response code.

Error If some kind of error occurs within Chatterl CWIGA responds with an error. As these are usually internal errors, they return with a 500 HTTP response code.

Response Structures

All CWIGA responses follow the same format for simplicity & ease of use. There are three basic response format that can be retrieved from CWIGA:

  • Empty
  • Populated
  • Messages

Following are examples of the different response types shown in JSON & XML respectively.

Empty Empty responses are structured are used when ever a response is returned with an empty value, these response are displayed in the below formats:

<chatterl>
    <response>
        <users/>
    </response>
</chatterl>
{"chatterl":
    {"response":
        {"success":
            {"groups":[]}
        }
    }
}

Message list Populated lists are have the following structure: When CWIGA has a number of results it creates a structure simular to below:

{"chatterl":
    {"response":
        {"success":
            {"groups":
                [
                    {"group":"nu"},
                    {"group":"another group"}
                ]
            }
        }
    }
}
<chatterl>
    <response>
        <users>
            <user>noobie</user>
            <user>noobiz</user>
            <user>nooby</user>
            <user>noobz</user>
        </users>
    </response>
</chatterl>

Multi Message lists Primarily this format is used for storing all messages associated to a group (At the time of this writing this structure has not been implemented in XML format).

{"chatterl":
    {"response":
        {"success":
            {"messages":
                [{"message":
                    [
                        {"client":"baph"},
                        {"date":ISODATE},
                        {"msgbody":"hey"}
                    ]
                },
                {"message":
                    [
                        {"client":"baph"},
                        {"date":ISODATE},
                        {"msgbody":"welcome"}]
                }]
            }
        }
    }
}
<chatterl>
    <response>
        <messages>
            <message>
                <client>baph</client>
                <date>ISODATE</date>
                <msgbody>hey</msgbody>  
            </message>
            <message>
                <client>baph</client>
                <date>ISODATE</date>
                <mgsbody>welcome</msgbody>  
            </message>
        </messages>
    </response>
</chatterl>

Messages There are a couple of reasons for receiving messages, the first two being used for success & failures (which are used for simple interactions with CWIGA). The other time is when CWIGA has come across an error, messages are formatted in the following formats:

{"chatterl":
    {"response":
        {"success":"noob now connected"}
    }
}

<chatterl>
    <response>
        <failure>Unable to connect.</failure>
    </response>
</chatterl>

CWIGA Calls

All commands apart from connect require the client to connect, without it, they will receive an erorr (at the moment this is not true).

CWIGA commands are as follows:

  • Connect to Chatterl.
  • Disconnect to Chatterl.
  • List Users.
  • List Groups.
  • List Groups Users.
  • Join a Group.
  • Leave a Group.
  • Send Group messages.
  • Poll Group messages.

Connect to Chatterl

http://CWIGAURL:9000/connect/USER

Calls Chatterl & makes a connection, once this is successful, the client is able to interact with the rest of the API. When a client connects successfully, the following response will be received:

{"chatterl":
    {"response":
        {"success":"foo has connected to Chatterl"}
    }
}
<chatterl>
    <response>
        <success>foo now connected</success>
    </response>
</chatterl>

Disonnect from Chatterl

http://CWIGAURL:9000/disconnect/USER

Disconnects the client from Chatterl, this destroys the client process along with all the connections it is associated with (needs to be full implemented).

Successful responses are displayed are the following:
{"chatterl":
    {"response":
        {"success":"User dropped"}
    }
}
<chatterl>
    <response>
        <success>User dropped</success>
    </response>
</chatterl>

Where as displayed below:

{"chatterl":
    {"response":
        {"failure":"Unable to drop from group"}
    }
}
<chatterl>
    <response>
        <failure>Unable to drop from group</failure>
    </response>
</chatterl>

List Users on Chatterl

http://CWIGAURL:9000/users/list

This call only has two types of response (an empty list or a populated on) which are expressed as follows:

Empty
{"chatterl":
    {"response":
        {"success":
            {"clients":[]}
        }
    }
}
<chatterl>
    <response>
        <success>
            <clients/>
        </success>
    </response>
</chatterl>

Populated

{"chatterl":
    {"response":
        {"success":
            {"clients":[
                {"client":"foo"},
                {"client":"bar"},
                {"client":"baz"}
            ]}
        }
    }
}
<chatterl>
    <response>
        <success>
            <clients>
                <client>foo</client>
                <client>bar</client>
                <client>baz</client>
            </clients>
        </success>
    </response>
</chatterl>

List Users in a Chatterl Group

http://CWIGAURL:9000/users/some_group/list

Will list all the clients currently connected to Chatterl, responses to this requests produce the same response body as (/users/list) the above examplexsy.

List Chatterl Groups
http://CWIGAURL:9000/groups/list
{"chatterl":
    {"response":
        {"success":
            {"groups":[
                {"group":"nu_group"},
                {"group":"anuva_group"},
                {"group":"one_more"}
            ]}
        }
    }
}
<chatterl>
    <response>
        <success>
            <groups>
                <group>nu_group</group>
                <group>anuva_group</group>
                <group>one_more</group>
            </groups>
        </success>
    </response>
</chatterl>

Join a Group

http://CWIGAURL:9000/groups/join?client="foo"

Successful requests return the following response:

{"chatterl":
    {"response":
        {"success":"foo joined group"}
    }
}
<chatterl>
    <response>
        <success>foo joined group;/success>
    </response>
</chatterl>

Where as failures result in responses simular to the ones below:

{"chatterl":
    {"response":
        {"failure":"foo joined group"}
    }
}
<chatterl>
    <response>
        <failure>foo joined group;/failure>
    </response>
</chatterl>

Leave a Groups

http://CWIGAURL:9000/groups/some_group/leave?client="foo"

Makes a client leave the specified group, on succes a response simular to below is received.

{"chatterl":
    {"response":
        {"success":"foo has left group foo"}
    }
}
<chatterl>
    <response>
        <success>foo has left group foo;/success>
    </response>
</chatterl>

Failure responses are returns as follows:

{"chatterl":
    {"response":
        {"failure":"foo not connected to some_group"}
    }
}
<chatterl>
    <response>
        <failure>foo not connected to some_group;/failure>
    </response>
</chatterl>

Send a Group message

http://CWIGAURL:9000/groups/send/some_group?client=foo&msg=hey%20all

These responses are dealt with in the same fashion as joining a group.

Successful requests are as follows:
{"chatterl":
    {"response":
        {"success":"msg_sent"}
    }
}

Where as failure responses are returns as follows:

{"chatterl":
    {"response":
        {"failure":"Can not send the same message twice"}
    }
}

Poll Group for messages

http://CWIGAURL:9000/groups/poll/some_group

Checks a groups for a list of its messages, there are two types of successful requests:

  • No messages
  • List of messages

No messages are represented as follows:

{"chatterl":{"response":{"messages":[]}}}
<chatterl>
    <response>
        <success>
            <messages/>
        </success>
    </response>
</chatterl>

Lists of messages are expressed in the following manner:

{"chatterl":
    {"response":
        {"success":
            {"messages":
                [{"message":
                    [
                        {"client":"baph"},
                        {"date":ISODATE},
                        {"msgbody":"hey"}
                    ]
                },
                {"message":
                    [
                        {"client":"baph"},
                        {"date":ISODATE},
                        {"msgbody":"welcome"}]
                }]
            }
        }
    }
}
<chatterl>
    <response>
        <messages>
            <message>
                <client>baph</client>
                <date>ISODATE</date>
                <msgbody>hey</msgbody>  
            </message>
            <message>
                <client>baph</client>
                <date>ISODATE</date>
                <mgsbody>welcome</msgbody>  
            </message>
        </messages>
    </response>
</chatterl>

It is possible for a group not to exist, in these cases the following response will be returned:

{"chatterl":{"response":{"failure":"Group:some_group does'n exist"}}}
<chatterl>
    <response>
        <failure>Group:some_group does'n exist;/failure>
    </response>
</chatterl>
Something went wrong with that request. Please try again.