Skip to content

Commit

Permalink
[Node-AppInsights] Update to botbuilder 3.5.1
Browse files Browse the repository at this point in the history
  • Loading branch information
pcostantini committed Jan 10, 2017
1 parent dfac8f5 commit c3f9f2e
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 48 deletions.
25 changes: 17 additions & 8 deletions Node/core-AppInsights/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ A sample bot which logs telemetry to an Application Insights instance.

The minimum prerequisites to run this sample are:
* Latest Node.js with NPM. Download it from [here](https://nodejs.org/en/download/).
* The Bot Framework Emulator. To install the Bot Framework Emulator, download it from [here](https://aka.ms/bf-bc-emulator). Please refer to [this documentation article](https://docs.botframework.com/en-us/csharp/builder/sdkreference/gettingstarted.html#emulator) to know more about the Bot Framework Emulator.
* The Bot Framework Emulator. To install the Bot Framework Emulator, download it from [here](https://emulator.botframework.com/). Please refer to [this documentation article](https://github.com/microsoft/botframework-emulator/wiki/Getting-Started) to know more about the Bot Framework Emulator.
* **[Recommended]** Visual Studio Code for IntelliSense and debugging, download it from [here](https://code.visualstudio.com/) for free.
* An Application Insights instance in Azure. The Instrumentation Key for which must be put in the `APPINSIGHTS_INSTRUMENTATIONKEY` key in [.env](.env) file to try it out further.

Expand All @@ -19,12 +19,14 @@ This bot is based off the State API bot, but adds in the ability to log custom t

The notable changes to the State API bot which enable telemetry logging are threefold:
1. Addition of Application Insights SDK and `appInsightsClient`
````javascript
var appInsights = require("applicationinsights");
appInsights.setup(process.env.APPINSIGHTS_INSTRUMENTATIONKEY).start();
var appInsightsClient = appInsights.getClient();
...
````

````javascript
var appInsights = require('applicationinsights');
appInsights.setup(process.env.APPINSIGHTS_INSTRUMENTATIONKEY).start();
var appInsightsClient = appInsights.getClient();
...
````

2. [Telemetry module](telemetry-module.js) to enable creation of Telemetry objects that will be pre-populated with conversation and user data to enable quick filter/pivoting in the Application Insights dashboard.
3. Usage of these methods throughout the bot's code (eg: here, here, and here)
Expand All @@ -40,4 +42,11 @@ Clicking on any item in the table will open up another pane allowing you to view
For more information logged directly from the Bot Connector, be sure to put your instrumentation key in to your bot's listing in the Bot Directory.

![Bot Directory Instrumentation Key field](images/botdirfield.png)
![Bot Directory Instrumentation Key field](images/botdirfield.png)

### More Information

To get more information about how to get started in Bot Builder for Node and Attachments please review the following resources:
* [Bot Builder for Node.js Reference](https://docs.botframework.com/en-us/node/builder/overview/#navtitle)
* [AppInsights Overview](https://docs.microsoft.com/en-us/azure/application-insights/app-insights-overview)
* [AppInsights for Custom Events and Metrics](https://docs.microsoft.com/en-us/azure/application-insights/app-insights-api-custom-events-metrics)
64 changes: 33 additions & 31 deletions Node/core-AppInsights/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ var restify = require('restify');
require('dotenv-extended').load();
var telemetryModule = require('./telemetry-module.js');

var appInsights = require("applicationinsights");
var appInsights = require('applicationinsights');
appInsights.setup(process.env.APPINSIGHTS_INSTRUMENTATIONKEY).start();
var appInsightsClient = appInsights.getClient();

Expand All @@ -18,43 +18,44 @@ var connector = new builder.ChatConnector({
appPassword: process.env.MICROSOFT_APP_PASSWORD
});

// Create Bot with `persistConversationData` flag
var bot = new builder.UniversalBot(connector, {
persistConversationData: true
});
// Listen for messages
server.post('/api/messages', connector.listen());

var HelpMessage = '\n * If you want to know which city I\'m using for my searches type \'current city\'. \n * Want to change the current city? Type \'change city to cityName\'. \n * Want to change it just for your searches? Type \'change my city to cityName\'';
var UserNameKey = 'UserName';
var UserWelcomedKey = 'UserWelcomed';
var CityKey = 'City';

// Bot dialogs
bot.dialog('/', function (session) {
// Setup bot with default dialog
var bot = new builder.UniversalBot(connector, function (session) {

var telemetry = telemetryModule.createTelemetry(session, { setDefault: false });

// initialize default city
// initialize with default city
if (!session.conversationData[CityKey]) {
session.conversationData[CityKey] = 'Seattle';

telemetry.setDefault = true;
}
}

var defaultCity = session.conversationData[CityKey];
session.send('Welcome to the Search City bot. I\'m currently configured to search for things in %s', defaultCity);

appInsightsClient.trackTrace("start", telemetry);
appInsightsClient.trackTrace('start', telemetry);

session.beginDialog('/search');
session.beginDialog('search');
});

bot.dialog('/search', new builder.IntentDialog()
// Enable Conversation Data persistence
bot.set('persistConversationData', true);

// Main dialog
bot.dialog('search', new builder.IntentDialog()
.onBegin(function (session, args, next) {
// is user's name set?
var userName = session.userData[UserNameKey];
if (!userName) {
session.beginDialog('/askUserName');
session.beginDialog('greet');
return;
}

Expand All @@ -71,17 +72,17 @@ bot.dialog('/search', new builder.IntentDialog()

} finally {
var resumeAfterPromptTelemetry = telemetryModule.createTelemetry(session);
appInsightsClient.trackTrace("resumeAfterPrompt", resumeAfterPromptTelemetry);
appInsightsClient.trackTrace('resumeAfterPrompt', resumeAfterPromptTelemetry);
}

next();

}).matches(/^current city/i, function (session) {
// print city settings
var userName = session.userData[UserNameKey];
var defaultCity = session.conversationData[CityKey];
var userCity = session.privateConversationData[CityKey]
if (!!userCity) {
var userCity = session.privateConversationData[CityKey];
if (userCity) {
session.send(
'%s, you have overridden the city. Your searches are for things in %s. The default conversation city is %s.',
userName, userCity, defaultCity);
Expand All @@ -91,7 +92,7 @@ bot.dialog('/search', new builder.IntentDialog()
}

var telemetry = telemetryModule.createTelemetry(session);
appInsightsClient.trackEvent("current city", telemetry);
appInsightsClient.trackEvent('current city', telemetry);

}).matches(/^change city to (.*)/i, function (session, args) {
// change default city
Expand All @@ -101,7 +102,7 @@ bot.dialog('/search', new builder.IntentDialog()
session.send('All set %s. From now on, all my searches will be for things in %s.', userName, newCity);

var telemetry = telemetryModule.createTelemetry(session);
appInsightsClient.trackEvent("change city to", telemetry);
appInsightsClient.trackEvent('change city to', telemetry);

}).matches(/^change my city to (.*)/i, function (session, args) {
// change user's city
Expand All @@ -110,7 +111,7 @@ bot.dialog('/search', new builder.IntentDialog()
var userName = session.userData[UserNameKey];
session.send('All set %s. I have overridden the city to %s just for you', userName, newCity);
var telemetry = telemetryModule.createTelemetry(session);
appInsightsClient.trackEvent("change my city to", telemetry);
appInsightsClient.trackEvent('change my city to', telemetry);

}).matches(/^reset/i, function (session, args) {
// reset data
Expand All @@ -130,32 +131,33 @@ bot.dialog('/search', new builder.IntentDialog()
var userName = session.userData[UserNameKey];
var messageText = session.message.text.trim();
session.send('%s, wait a few seconds. Searching for \'%s\' in \'%s\'...', userName, messageText, city);
session.send('https://www.bing.com/search?q=%s', encodeURIComponent(messageText + ' in ' + city));
session.send('https://www.bing.comsearch?q=%s', encodeURIComponent(messageText + ' in ' + city));

} catch (error) {
measuredEventTelemetry.exception = error.toString();
appInsightsClient.trackException("search", t)
appInsightsClient.trackException('search', t);

} finally {
var timerEnd = process.hrtime(timerStart);
measuredEventTelemetry.metrics = (timerEnd[0], timerEnd[1]/1000000);
appInsightsClient.trackEvent("timeTaken", measuredEventTelemetry);
measuredEventTelemetry.metrics = (timerEnd[0], timerEnd[1] / 1000000);
appInsightsClient.trackEvent('timeTaken', measuredEventTelemetry);

}
}
}));

bot.dialog('/askUserName', new builder.SimpleDialog(function (session, results) {
// Greet dialog
bot.dialog('greet', new builder.SimpleDialog(function (session, results) {
if (results && results.response) {
session.userData[UserNameKey] = results.response;
session.privateConversationData[UserWelcomedKey] = true;
session.send('Welcome %s! %s', results.response, HelpMessage)
session.send('Welcome %s! %s', results.response, HelpMessage);

var telemetry = telemetryModule.createTelemetry(session);
telemetry.userName = results.response; // You can add properties after-the-fact as well
appInsightsClient.trackEvent("new user", telemetry);
appInsightsClient.trackEvent('new user', telemetry);

// end the current dialog and replace it with '/search' dialog
session.replaceDialog('/search');
// end the current dialog and replace it with 'search' dialog
session.replaceDialog('search');
return;
}

Expand Down
6 changes: 3 additions & 3 deletions Node/core-AppInsights/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@
"author": "",
"license": "MIT",
"dependencies": {
"applicationinsights": "^0.16.0",
"botbuilder": "^3.2.3",
"applicationinsights": "^0.17.1",
"botbuilder": "^3.5.1",
"dotenv-extended": "^1.0.4",
"restify": "^4.1.1"
"restify": "^4.3.0"
}
}
12 changes: 6 additions & 6 deletions Node/core-AppInsights/telemetry-module.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
exports.createTelemetry = (session, properties = null) => {
exports.createTelemetry = (session, properties) => {
var data = {
conversationData: JSON.stringify(session.conversationData),
privateConversationData: JSON.stringify(session.privateConversationData),
userData: JSON.stringify(session.userData),
conversationId: session.message.address.conversation.id,
userId: session.message.address.user.id
}
};

if(properties) {
for(property in properties) {
if (properties) {
for (property in properties) {
data[property] = properties[property];
}
}

return data;
}
};

0 comments on commit c3f9f2e

Please sign in to comment.