Introduction
This piece of software enables the user to have a programmable ChatBot. Where most of the tutorials circulating on the internet have their knowledge base hard coded (obviously for demonstration purposes), here we will see that it is possible to add and edit rules to knowledge base during runtime, and the database is automatically saved to a file on storage.
Second thing that this program does is it doesn't simply compare strings to search for answers, but it uses a different strategy to calculate resemblance between strings, and this sort of overcomes typing errors, misspelled words, or inverted phrases.
In addition to the features mentioned above, it has several secondary features that enhance user experience like a testing section, message delaying, greeting message, and the ability to load and backup database into files.
Background
Originally, this was an application that I made previously for someone who had nothing to do with any programing. I found many examples that do illustrate how it should be basically done, but for my end-users, several things needed to be enhanced like:
- User friendly interface
- An editable knowledge base via the GUI
- A way to overcome typing errors, misspelled words, etc.
- Message delaying
I have based my work on this CodeProject article, Make your Skype Bot in .NET,
as it was a nice 'scratch the surface' with the Skype4COM COM wrapper, and it's highly suggested to check it out as it contains a lot of definitions that will not be covered in this article.
Code Explanation
String Comparison Strategy and Message Processing
It is obvious that normal string comparison will only match strings character by character, which is not very effective when dealing with messages that were input by humans.
In the case like we have here, strings are commonly compared by Resemblance. i.e., we will have to calculate the rate of how much do a pair of strings look alike.
There are many algorithms and approaches to do such a comparison, for the sake of this project we will be using the Levenshtein distance.
Message processing is summarized in the following diagram :
Source code preview of the actual method for message processing is as follows:
private string ProcessCommand(string msg,bool showSimilarity)
{
msg = preTreatMessage(msg);
string answer="";
string searchQuery = "";
string[] tokens = msg.Split(' ');
string oper = "";
foreach (string token in tokens)
{
if (token != "")
{
searchQuery += oper + " receive LIKE '%" + token + "%' ";
oper = "OR";
}
}
DataRow[] results = this.database.Rules.Select
("active = True AND "+searchQuery);
double maxScore = this.intelligence;
List<string> answerlist =new List<string>();
foreach (DataRow result in results)
{
MatchsMaker m = new MatchsMaker(msg, result["receive"].ToString());
if (m.Score > maxScore)
{
answerlist.Clear();
answerlist.Add(result["send"] + ((showSimilarity)?"
(" + m.Score + ")":""));
this.messageDelay = (int)result["delay"];
maxScore = m.Score;
}
else if (m.Score == maxScore)
{
answerlist.Add(result["send"] +
((showSimilarity)?" (" + m.Score + ")":""));
this.messageDelay = (int)result["delay"];
}
}
if (answerlist.Count == 0) {
answer = "";
}else{
Random rand = new Random();
answer = answerlist[rand.Next(0,answerlist.Count)];
}
return answer;
}
Message Delaying
This feature was required to make the bot more realistic, a delay amount is assigned to each rule; However it can be done differently for example, we can count the characters of the response in order to avoid setting the delay every time we add a new rule.
Another thing that is not covered is to make Skype show that we are currently typing a message, during the message delaying.
Here is a preview of the method (Thread
) for delaying the message, its simply sleeps for the amount of seconds set by the message.
private void SendSkypeMessage(string username, string message)
{
if (message != "")
{
System.Threading.Thread.Sleep(1000*this.messageDelay);
try
{
skype.SendMessage(username, message);
}
catch { }
}
}
It is called within the skype_MessageStatus
callback method:
System.Threading.Thread t = new System.Threading.Thread(() =>
SendSkypeMessage(msg.Sender.Handle, send));
t.Start();
History
Related Material