About

The SL Developer’s Corner is my place in the virtual world “Second Life”, where i experiment and tinker with the features of this platform. I try to publish my experiences and often also include the source code of the scripts on this site. Other posting related to Second life can be also found on Happy Coding 2nd-life section.

Friday 13 July 2007

A.L.I.C.E. Chatbot Connection in Second Life using Ruby on Rails

Like i told you some month ago, i have quick-hacked a Chatbot for Second Life, which connects to an A.L.I.C.E.-Bot at www.pandorabots.com. In this posting i want to show the LindenScript-Code and the server-side code i've used. On the server-side its Ruby on Rails, as usual. ;)

The Ruby on Rails serverside script:

I have built an "bot_controller.rb" file which looks like this:


require 'net/http'
require 'uri'
require 'cgi'

class BotController < ApplicationController

def ask_question
question = params[:q]
custid = params[:cid]

res = Net::HTTP.post_form(URI.parse('http://www.pandorabots.com/pandora/talk-xml'),
{'botid'=>'###YOUR BOT ID###', 'custid' => custid, 'input'=>question})
case res
when Net::HTTPSuccess, Net::HTTPRedirection

xmlDoc = REXML::Document.new(res.body)

botCustid = xmlDoc.elements["result"].attributes["custid"]
statusCode = xmlDoc.elements["result"].attributes["status"]


case statusCode
when "0"
render :text => xmlDoc.elements["result/that"].get_text.value+"||"+botCustid
else
render :text => 'Help, this error occurred: ' + xmlDoc.elements["result/message"].get_text.value+"||"+botCustid
end

else
render :text => 'error'
end

end

end
The controller just takes a given conversation-id (custId) and the question from the person in 2nd-Life. Like you'll see later, the custId is just for possible future improvements and has now no special use. :)
The other parts in the script are like in the Twitter/Jaiku scripts which i did. They retrieve the XML-document and get the right parts using XPath-expressions. And after that the script builds a nice "||"-separated result-string for the Second Life world.
You also need your own bot-id from the pandorabots-site. Create an account there and you get your own.

The LindenScript:

key requestId;
string custid;

default
{
state_entry()
{
llListen( 0, "", NULL_KEY, "" );
custid = "";
}

touch_start(integer total_number)
{
llWhisper(0, "Talk to me on Chat-Channel 0.");
}

listen(integer channel, string name, key id, string message)
{
requestId = llHTTPRequest("###YOUR URL###/bot/ask_question",[HTTP_METHOD,"POST", HTTP_MIMETYPE, "application/x-www-form-urlencoded"],"q="+message+"&cid="+custid);
}

http_response(key request_id, integer status, list metadata, string body) {

if (request_id == requestId) {

if(body == "erro") {
llWhisper(0, "An error occurred. Please try again later");
} else {

list parts = llParseString2List(body,["||"],[]);

string that = llList2String(parts, 0);
custid = llList2String(parts, 1);
llWhisper(0, that);
}

} else {
llWhisper(0, "An error occurred. Please try again later");
}
}


}

The script is really easy. It just listens on Channel 0, gets the message from the user and calls the Ruby on Rails script. After that it gets the result, splits the string using the "||" separator and then prints the answer for the question.

Possible future extensions:

There are a lot of possible extensions for this script. The most important one i the problem with the conversation-id.
It would be nice, if the Chatbot in Second Life could remember the different users. For example on the server-side we could create a database which manages every person which has talked to the chatbot. We store the SecondLife-username and the appropriate conversation-id in a database-structure. Everytime the user comes back, we get the conversation-id from the database and use this one. So the A.L.I.C.E.-Bot can optimize its questions for every user.

You can also add some error-handling. So that the user gets nice messages if something goes wrong.

So, hope you like it. :)