CommunityEventBot
A Bot to get information on your community event. The bot is written in C#.
Initial Bot Setup
To get started with bot, you first have to install the Bot Builder SDK, which is available via Nuget. A template of a sample bot to start with is also available on the Bot Framework documentation website.
Set the bot up as explained on the Create a bot for .NET website
Database setup
To get the information about the event, any kind of storage can be used that is connectable to the C# bot environment. In this example, we use a SQL database. A sample SQL query looks like this:
SELECT [id]
,[speakerName]
,[speakerDescription]
,[speakerImage]
,[talkTitle]
,[talkDescription]
,[talkTime]
,[talkTrack]
FROM [dbo].[eventinfoextended]Fill the database with the information needed for the event bot. To do this, use a tool of your choice. I recommend using the SQL Management Studio.
LUIS setup
After the data is included in the database we have to figure out, what kinds of questions the user wants to ask the bot. In this simple scenario we want to get answers to the following questions:
- What can I do next?
- What is <speaker> talking about?
- When is the session from <speaker>?
These questions will be mapped to 3 intents:
- talk.next
- talk.content
- talk.speaker
The value of <speaker> is stored in an entity called: speakerName
To provide the functionality to recognize these intents from users questions, the Cognitive Service LUIS is used. To learn more about LUIS, you can visit the LUIS web portal.
We train each intent with 5-10 phrases that we expect the user to say, when he wants the specific information.
LUIS Training
To train and publish you LUIS model, follow the steps as described:
-
Create a new app on [luis.ai](https://www.luis.ai/applications)
-
Go to intents and create a new intent
-
Add phrases to the intent
Add the phrases the service should understand, but don't worry, because LUIS is an intelligent service, it can adapt to changes in the query, so if a word is missing or added or the word order is changed, it will still trigger the intent as intended - or should I say: intented
😆 Sorry!
-
Create a new entity to recognize properties
To add a entity, select the values that will be dynamic by clicking on them. Type a name and click "Create entity".
-
Training the service
-
Publish the service
Bot development
Integrating LUIS
For LUIS integration, you have 2 options: Either you use the built-in dialogs, as described in Enable LUIS. The second option is to include the REST call manually. This offers more flexibility over the LUIS results and is used in this implementation. The implemented LuisConnector takes just a few lines of code:
[Serializable]
public class LuisConnector
{
public static async Task<LuisResult> GetLuisResult(string query)
{
LuisResult luisResponse;
string luisUrl = $"https://westus.api.cognitive.microsoft.com/luis/v2.0/apps/{Credentials.LUIS_MODEL_ID}?subscription-key={Credentials.LUIS_SUBSCRIPTION_KEY}&verbose=true&q={HttpUtility.HtmlEncode(query)}";
HttpClient client = new HttpClient();
var response = await client.GetStringAsync(luisUrl);
luisResponse = JsonConvert.DeserializeObject<LuisResult>(response);
return luisResponse;
}
}The LuisResult mentioned above, looks like this:
[Serializable]
public class LuisResult
{
public string query { get; set; }
public Topscoringintent topScoringIntent { get; set; }
public Intent[] intents { get; set; }
public Entity[] entities { get; set; }
}
[Serializable]
public class Topscoringintent
{
public string intent { get; set; }
public float score { get; set; }
}
[Serializable]
public class Intent
{
public string intent { get; set; }
public float score { get; set; }
}
[Serializable]
public class Entity
{
public string entity { get; set; }
public string type { get; set; }
public int startIndex { get; set; }
public int endIndex { get; set; }
public float score { get; set; }
}Integrating the database
For database integration, the namespace System.Data.SqlClient is used, which provides the SQLConnection object to automate connection to the database and SqlCommand to send queries to the database.
The resulting SQLConnector which is used in the implementation, looks like this:
[Serializable]
public static class SqlConnector
{
/// <summary>
/// Call the database to get all dishes
/// </summary>
/// <param name="project">All available dishes.</param>
internal static List<EventSpeaker> GetEventSpeakerInfo()
{
List<EventSpeaker> speakerInfo = new List<EventSpeaker>();
using (SqlConnection connection = new SqlConnection(Credentials.SQL_CONNECTION_STRING))
{
var query = String.Format("SELECT * FROM eventinfoextended;");
SqlCommand command = new SqlCommand(query, connection);
connection.Open();
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
var id = Convert.ToDecimal(reader["ID"]);
var speakerName = reader["SPEAKERNAME"].ToString();
var speakerDescription = reader["SPEAKERDESCRIPTION"].ToString();
var speakerImage = reader["SPEAKERIMAGE"].ToString();
var talkTitle = reader["TALKTITLE"].ToString();
var talkDescription = reader["TALKDESCRIPTION"].ToString();
var talkTime = Convert.ToDateTime(reader["TALKTIME"]);
var talkTrack = reader["TALKTRACK"].ToString();
speakerInfo.Add(new EventSpeaker
{
Id = (int)id,
SpeakerDescription = speakerDescription,
SpeakerImageUrl = speakerImage,
SpeakerName = speakerName,
TalkDescription = talkDescription,
TalkTime = talkTime,
TalkTitle = talkTitle,
TalkTrack = talkTrack
});
}
}
connection.Close();
}
return speakerInfo;
}
}Adding speech capabilities
Click on the image to get a demo of the interaction with Cortana.
For Cortana integration, take a look at the following links:






