Skip to content

Commit

Permalink
Refactor AppInsights into smaller dialogs with triggerAction
Browse files Browse the repository at this point in the history
  • Loading branch information
pcostantini committed Feb 25, 2017
1 parent 43bbef1 commit 1a1e415
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 104 deletions.
2 changes: 1 addition & 1 deletion Node/core-AppInsights/.env
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ MICROSOFT_APP_PASSWORD=

# Please subscribe to create your own key and try it out further.
# Get Started: https://azure.microsoft.com/en-us/services/application-insights/
APPINSIGHTS_INSTRUMENTATIONKEY=
APPINSIGHTS_INSTRUMENTATION_KEY=

4 changes: 2 additions & 2 deletions Node/core-AppInsights/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ 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://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.
* An Application Insights instance in Azure. The Instrumentation Key for which must be put in the `APPINSIGHTS_INSTRUMENTATION_KEY` key in [.env](.env) file to try it out further.

### Code Highlights

Expand All @@ -22,7 +22,7 @@ The notable changes to the State API bot which enable telemetry logging are thre

````javascript
var appInsights = require('applicationinsights');
appInsights.setup(process.env.APPINSIGHTS_INSTRUMENTATIONKEY).start();
appInsights.setup(process.env.APPINSIGHTS_INSTRUMENTATION_KEY).start();
var appInsightsClient = appInsights.getClient();
...
````
Expand Down
195 changes: 100 additions & 95 deletions Node/core-AppInsights/app.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
// This loads the environment variables from the .env file
require('dotenv-extended').load();

var builder = require('botbuilder');
var restify = require('restify');
require('dotenv-extended').load();

var telemetryModule = require('./telemetry-module.js');

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

// Setup Restify Server
Expand All @@ -13,12 +16,12 @@ server.listen(process.env.port || process.env.PORT || 3978, function () {
console.log('%s listening to %s', server.name, server.url);
});

// Create connector and listen for messages
var connector = new builder.ChatConnector({
appId: process.env.MICROSOFT_APP_ID,
appPassword: process.env.MICROSOFT_APP_PASSWORD
});

// 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\'';
Expand All @@ -34,132 +37,134 @@ var bot = new builder.UniversalBot(connector, function (session) {
// initialize with default city
if (!session.conversationData[CityKey]) {
session.conversationData[CityKey] = 'Seattle';

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

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);

// is user's name set?
var userName = session.userData[UserNameKey];
if (!userName) {
return session.beginDialog('greet');
}

try {
// has the user been welcomed to the conversation?
if (!session.privateConversationData[UserWelcomedKey]) {
session.privateConversationData[UserWelcomedKey] = true;
return session.send('Welcome back %s! Remember the rules: %s', userName, HelpMessage);
}
} catch (error) {
var exceptionTelemetry = telemetryModule.createTelemetry(session);
exceptionTelemetry.exception = error.toString();
appInsightsClient.trackException(exceptionTelemetry);
} finally {
var resumeAfterPromptTelemetry = telemetryModule.createTelemetry(session);
appInsightsClient.trackTrace('resumeAfterPrompt', resumeAfterPromptTelemetry);
}

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

// 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('greet');
return;
}
// search dialog
bot.dialog('search', function (session, args, next) {
var measuredEventTelemetry = telemetryModule.createTelemetry(session);
var timerStart = process.hrtime();

try {
// has the user been welcomed to the conversation?
if (!session.privateConversationData[UserWelcomedKey]) {
session.privateConversationData[UserWelcomedKey] = true;
session.send('Welcome back %s! Remember the rules: %s', userName, HelpMessage);
}
} catch (error) {
var exceptionTelemetry = telemetryModule.createTelemetry(session);
exceptionTelemetry.exception = error.toString();
appInsightsClient.trackException(exceptionTelemetry);

} finally {
var resumeAfterPromptTelemetry = telemetryModule.createTelemetry(session);
appInsightsClient.trackTrace('resumeAfterPrompt', resumeAfterPromptTelemetry);
}
try {
// perform search
var city = session.privateConversationData[CityKey] || session.conversationData[CityKey];
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));
} catch (error) {
measuredEventTelemetry.exception = error.toString();
appInsightsClient.trackException('search', t);
} finally {
var timerEnd = process.hrtime(timerStart);
measuredEventTelemetry.metrics = (timerEnd[0], timerEnd[1] / 1000000);
appInsightsClient.trackEvent('timeTaken', measuredEventTelemetry);
}

session.endDialog();
});

next();
// reset bot dialog
bot.dialog('reset', function (session) {
// reset data
delete session.userData[UserNameKey];
delete session.conversationData[CityKey];
delete session.privateConversationData[CityKey];
delete session.privateConversationData[UserWelcomedKey];

}).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) {
session.send(
'%s, you have overridden the city. Your searches are for things in %s. The default conversation city is %s.',
userName, userCity, defaultCity);
return;
} else {
session.send('Hey %s, I\'m currently configured to search for things in %s.', userName, defaultCity);
}
var telemetry = telemetryModule.createTelemetry(session);
appInsightsClient.trackEvent('reset', telemetry);

var telemetry = telemetryModule.createTelemetry(session);
appInsightsClient.trackEvent('current city', telemetry);
session.endDialog('Ups... I\'m suffering from a memory loss...');
}).triggerAction({ matches: /^reset/i });

}).matches(/^change city to (.*)/i, function (session, args) {
// change default city
var newCity = args.matched[1].trim();
session.conversationData[CityKey] = newCity;
var userName = session.userData[UserNameKey];
session.send('All set %s. From now on, all my searches will be for things in %s.', userName, newCity);
// print current city dialog
bot.dialog('printCurrentCity', function (session) {
// print city settings
var userName = session.userData[UserNameKey];
var defaultCity = session.conversationData[CityKey];
var userCity = session.privateConversationData[CityKey];
if (userCity) {
session.endDialog(
'%s, you have overridden the city. Your searches are for things in %s. The default conversation city is %s.',
userName, userCity, defaultCity);
} else {
session.endDialog('Hey %s, I\'m currently configured to search for things in %s.', userName, defaultCity);
}

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

}).matches(/^change my city to (.*)/i, function (session, args) {
// change user's city
var newCity = args.matched[1].trim();
session.privateConversationData[CityKey] = newCity;
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);
session.endDialog();
}).triggerAction({ matches: /^current city/i });

}).matches(/^reset/i, function (session, args) {
// reset data
delete session.userData[UserNameKey];
delete session.privateConversationData[CityKey];
delete session.privateConversationData[UserWelcomedKey];
session.send('Ups... I\'m suffering from a memory loss...');
session.endDialog();
// change current city dialog
bot.dialog('changeCurrentCity', function (session, args) {
// change default city
var newCity = args.intent.matched[1].trim();
session.conversationData[CityKey] = newCity;
var userName = session.userData[UserNameKey];

}).onDefault(function (session) {
// perform search
var measuredEventTelemetry = telemetryModule.createTelemetry(session);
var timerStart = process.hrtime();
var telemetry = telemetryModule.createTelemetry(session);
appInsightsClient.trackEvent('change city to', telemetry);

try {
var city = session.privateConversationData[CityKey] || session.conversationData[CityKey];
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.endDialog('All set %s. From now on, all my searches will be for things in %s.', userName, newCity);
}).triggerAction({ matches: /^change city to (.*)/i });

} catch (error) {
measuredEventTelemetry.exception = error.toString();
appInsightsClient.trackException('search', t);
// change my current city dialog
bot.dialog('changeMyCurrentCity', function (session, args) {
// change user's city
var newCity = args.intent.matched[1].trim();
session.privateConversationData[CityKey] = newCity;
var userName = session.userData[UserNameKey];

} finally {
var timerEnd = process.hrtime(timerStart);
measuredEventTelemetry.metrics = (timerEnd[0], timerEnd[1] / 1000000);
appInsightsClient.trackEvent('timeTaken', measuredEventTelemetry);
var telemetry = telemetryModule.createTelemetry(session);
appInsightsClient.trackEvent('change my city to', telemetry);

}
}));
session.endDialog('All set %s. I have overridden the city to %s just for you', userName, newCity);
}).triggerAction({ matches: /^change my city to (.*)/i });

// 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);

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

// end the current dialog and replace it with 'search' dialog
session.replaceDialog('search');
return;
return session.endDialog('Welcome %s! %s', results.response, HelpMessage);
}

builder.Prompts.text(session, 'Before get started, please tell me your name?');
}));
}));
6 changes: 1 addition & 5 deletions Node/core-AppInsights/azuredeploy.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
"MICROSOFT_APP_PASSWORD": {
"type": "string"
},
"APPINSIGHTS_INSTRUMENTATIONKEY": {
"APPINSIGHTS_INSTRUMENTATION_KEY": {
"type": "string"
}
},
Expand Down Expand Up @@ -112,10 +112,6 @@
{
"name": "APPINSIGHTS_INSTRUMENTATION_KEY",
"value": "[parameters('APPINSIGHTS_INSTRUMENTATION_KEY')]"
},
{
"name": "APPINSIGHTS_INSTRUMENTATIONKEY",
"value": "[parameters('APPINSIGHTS_INSTRUMENTATIONKEY')]"
}
]
}
Expand Down
2 changes: 1 addition & 1 deletion Node/core-AppInsights/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
"url": "https://github.com/Microsoft/BotBuilder-Samples.git"
},
"dependencies": {
"applicationinsights": "^0.17.1",
"applicationinsights": "^0.17.2",
"botbuilder": "^3.6.0",
"dotenv-extended": "^1.0.4",
"restify": "^4.3.0"
Expand Down

0 comments on commit 1a1e415

Please sign in to comment.