New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

botbuilder-instrumentation

Package Overview
Dependencies
Maintainers
1
Versions
38
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

botbuilder-instrumentation - npm Package Compare versions

Comparing version 1.0.5 to 1.0.6

events.js

300

main.js
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const util = require("util");
const _ = require("lodash");
const builder = require("botbuilder");
const request_1 = require("request");
const ApplicationInsights = require("applicationinsights");
const events_1 = require("./events");
class BotFrameworkInstrumentation {
constructor(settings) {
this.appInsightsClient = null;
this.console = {};
this.methods = {
"debug": 0,
"info": 1,
"log": 2,
"warn": 3,
"error": 4
};
this.settings = {
sentiments: {
minWords: 3,
url: 'https://westus.api.cognitive.microsoft.com/text/analytics/v2.0/sentiment',
id: 'bot-analytics',
key: null
}
};
settings = settings || {};
_.extend(this.settings.sentiments, settings.sentiments);
this.settings.sentiments.key = this.settings.sentiments.key || process.env.CG_SENTIMENT_KEY;
this.settings.instrumentationKey = settings.instrumentationKey || process.env.APPINSIGHTS_INSTRUMENTATIONKEY;
if (!this.settings.instrumentationKey) {
throw new Error('App Insights instrumentation key was not provided in options or the environment variable APPINSIGHTS_INSTRUMENTATIONKEY');
}
if (!this.settings.sentiments.key) {
console.warn('No sentiment key was provided - text sentiments will not be collected');
}
}
formatArgs(args) {
return util.format.apply(util.format, Array.prototype.slice.call(args));
}
setupConsoleCollection() {
// Overriding console methods so that prints to console will first be logged
// to application insights
_.keys(this.methods).forEach(method => {
console[method] = (() => {
let original = console.log;
return (...args) => {
let stdout = null;
try {
let msg = this.formatArgs(args);
this.appInsightsClient.trackTrace(msg, this.methods[method]);
stdout = process.stdout;
process.stdout = process.stderr;
original.apply(console, args);
}
finally {
process.stdout = stdout || process.stdout;
}
};
})();
});
}
collectSentiment(session, text) {
text = text || '';
if (!this.settings.sentiments.key)
return;
if (text.match(/\S+/g).length < this.settings.sentiments.minWords)
return;
var _message = session.message || {};
var _address = _message.address || {};
var _conversation = _address.conversation || {};
var _user = _address.user || {};
request_1.default({
url: this.settings.sentiments.url,
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Ocp-Apim-Subscription-Key': this.settings.sentiments.key
},
json: true,
body: {
"documents": [
{
"language": "en",
"id": this.settings.sentiments.id,
"text": text
}
]
}
}, (error, response, body) => {
if (error) {
return this.appInsightsClient.trackException(error);
}
try {
let result = _.find(body.documents, { id: this.settings.sentiments.id }) || {};
var score = result.score || null;
if (isNaN(score)) {
throw new Error('Could not collect sentiment');
}
var item = {
text: text,
score: score,
timestamp: _message.timestamp,
channel: _address.channelId,
conversationId: _conversation.id,
userId: _user.id,
userName: _user.name
};
this.appInsightsClient.trackEvent(events_1.default.Sentiment.name, item);
}
catch (error) {
return this.appInsightsClient.trackException(error);
}
});
}
monitor(bot) {
ApplicationInsights.setup(this.settings.instrumentationKey).start();
this.appInsightsClient = ApplicationInsights.getClient(this.settings.instrumentationKey);
this.setupConsoleCollection();
// Adding middleware to intercept all user messages
if (bot) {
bot.use({
botbuilder: function (session, next) {
try {
let message = session.message;
let address = message.address || {};
let conversation = address.conversation || {};
let user = address.user || {};
let item = {
text: message.text,
type: message.type,
timestamp: message.timestamp,
conversationId: conversation.id,
channel: address.channelId,
userId: user.id,
userName: user.name
};
this.appInsightsClient.trackEvent(events_1.default.UserMessage.name, item);
}
catch (e) {
}
finally {
next();
}
},
send: (message, next) => {
try {
let address = message.address || {};
let conversation = address.conversation || {};
let user = address.user || {};
let item = {
text: message.text,
type: message.type,
timestamp: message.timestamp,
conversationId: conversation.id
};
this.appInsightsClient.trackEvent(events_1.default.BotMessage.name, item);
}
catch (e) {
}
finally {
next();
}
}
});
}
// Monitoring new dialog calls like session.beginDialog
// When beginning a new dialog, the framework uses pushDialog to change context
// to a new dialog
// Todo: Check alternative as <builder.SimpleDialog.prototype.begin>
// builder.Session.prototype..pushDialog = (function() {
// var orig = builder.Session.prototype.pushDialog;
// return function (args) {
// var _session = this;
// var _message = _session.message || {};
// var _address = _message.address || {};
// var _conversation = _address.conversation || {};
// var _user = _address.user || {};
// var _callstack = _session.sessionState.callstack;
// var item = {
// intent: args && args.id,
// state: args && args.state && JSON.stringify(args.state),
// channel: _address.channelId,
// conversationId: _conversation.id,
// callstack_length: _callstack.length.toString(),
// userId: _user.id,
// userName: _user.name
// };
// _.take(_callstack, 3).forEach((stackItem: any, idx: number) => {
// item[`callstack_${idx}_id`] = stackItem.id;
// item[`callstack_${idx}_state`] = JSON.stringify(stackItem.state);
// });
// this.appInsightsClient.trackEvent(Events.Intents.name, item);
// orig.apply(_session, [args]);
// }
// })();
// Capture message session before send
// builder.Session.prototype.prepareMessage = (function() {
// var orig = builder.Session.prototype.prepareMessage;
// return function (msg) {
// var _session = this;
// var res = orig.apply(_session, [msg]);
// if (_session.dialogData['transaction.started']) {
// var transactionEnded = false;
// var success = false;
// var conversation = _.find(transactions, { intent: _session.dialogData['transaction.id'] });
// if (conversation.intent != _session.dialogData['BotBuilder.Data.Intent']) {
// transactionEnded = true;
// } else {
// var test = conversation.test;
// var success = typeof test == 'string' ? test == msg.text : test.test(msg.text);
// if (success) {
// transactionEnded = true;
// }
// }
// if (transactionEnded) {
// endConverting(_session, null, success);
// delete _session.dialogData['transaction.started'];
// delete _session.dialogData['transaction.id'];
// }
// }
// return res;
// }
// })();
// Collect intents collected from LUIS after entities were resolved
builder.IntentDialog.prototype.recognize = (() => {
let _recognize = builder.IntentDialog.prototype.recognize;
return function (context, cb) {
let _dialog = this;
_recognize.apply(_dialog, [context, (err, result) => {
var entities = [];
if (result && result.entities) {
result.entities.forEach(value => {
entities.push({
type: value.type,
entity: value.entity
});
});
}
let message = context.message;
let address = message.address || {};
let conversation = address.conversation || {};
let user = address.user || {};
let item = {
text: message.text,
timestamp: message.timestamp,
intent: result && result.intent,
channel: address.channelId,
score: result && result.score,
entities: entities,
withError: !err,
error: err,
conversationId: conversation.id,
userId: user.id,
userName: user.name
};
this.appInsightsClient.trackEvent(events_1.default.Intent.name, item);
// transactions.forEach(cc => {
// if (cc.intent == item.intent) {
// startConverting(context, null);
// context.dialogData['transaction.started'] = true;
// context.dialogData['transaction.id'] = cc.intent;
// }
// });
this.collectSentiment(context, message.text);
// Todo: on "set alarm" utterence, failiure
return cb(err, result);
}]);
};
})();
}
startTransaction(context, name = '') {
let message = context.message;
let address = message.address || {};
let conversation = address.conversation || {};
let user = address.user || {};
let item = {
name: name,
timestamp: message.timestamp,
channel: address.channelId,
conversationId: conversation.id,
userId: user.id,
userName: user.name
};
this.appInsightsClient.trackEvent(events_1.default.StartTransaction.name, item);
}
endTransaction(context, name = '', successful = true) {
let message = context.message;
let address = message.address || {};
let conversation = address.conversation || {};
let user = address.user || {};
let item = {
name: name,
successful: successful.toString(),
timestamp: message.timestamp,
channel: address.channelId,
conversationId: conversation.id,
userId: user.id,
userName: user.name
};
this.appInsightsClient.trackEvent(events_1.default.EndTransaction.name, item);
}
}
exports.BotFrameworkInstrumentation = BotFrameworkInstrumentation;

312

main.ts

@@ -1,8 +0,11 @@

import util from 'util';
import * as util from 'util';
import * as _ from 'lodash';
import * as builder from 'botbuilder';
import request from 'request';
import builder from 'botbuilder';
import ApplicationInsights from "applicationinsights";
import ApplicationInsights = require("applicationinsights");
import Events from './events';
export interface IInstrumentationSettings {
instrumentationKey?: string;
sentiments?: {

@@ -18,3 +21,3 @@ minWords?: number,

private client = null;
private appInsightsClient = null;

@@ -30,3 +33,3 @@ private console = {};

private settings = {
private settings: IInstrumentationSettings = {
sentiments: {

@@ -44,2 +47,14 @@ minWords: 3,

_.extend(this.settings.sentiments, settings.sentiments);
this.settings.sentiments.key = this.settings.sentiments.key || process.env.CG_SENTIMENT_KEY;
this.settings.instrumentationKey = settings.instrumentationKey || process.env.APPINSIGHTS_INSTRUMENTATIONKEY;
if (!this.settings.instrumentationKey) {
throw new Error('App Insights instrumentation key was not provided in options or the environment variable APPINSIGHTS_INSTRUMENTATIONKEY');
}
if (!this.settings.sentiments.key) {
console.warn('No sentiment key was provided - text sentiments will not be collected');
}
}

@@ -51,3 +66,3 @@

setup() {
private setupConsoleCollection() {

@@ -67,3 +82,3 @@ // Overriding console methods so that prints to console will first be logged

let msg = this.formatArgs(args);
this.client.trackTrace(msg, this.methods[method]);
this.appInsightsClient.trackTrace(msg, this.methods[method]);

@@ -80,2 +95,285 @@ stdout = process.stdout;

}
private collectSentiment(session: any, text: string) {
text = text || '';
if (!this.settings.sentiments.key) return;
if (text.match(/\S+/g).length < this.settings.sentiments.minWords) return;
var _message = session.message || {};
var _address = _message.address || {};
var _conversation = _address.conversation || {};
var _user = _address.user || {};
request({
url: this.settings.sentiments.url,
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Ocp-Apim-Subscription-Key': this.settings.sentiments.key
},
json: true,
body: {
"documents": [
{
"language": "en",
"id": this.settings.sentiments.id,
"text": text
}
]
}
},
(error, response, body) => {
if (error) {
return this.appInsightsClient.trackException(error);
}
try {
let result: any = _.find(body.documents, { id: this.settings.sentiments.id }) || {};
var score = result.score || null;
if (isNaN(score)) {
throw new Error('Could not collect sentiment');
}
var item = {
text: text,
score: score,
timestamp: _message.timestamp,
channel: _address.channelId,
conversationId: _conversation.id,
userId: _user.id,
userName: _user.name
};
this.appInsightsClient.trackEvent(Events.Sentiment.name, item);
} catch (error) {
return this.appInsightsClient.trackException(error);
}
});
}
monitor (bot: builder.UniversalBot) {
ApplicationInsights.setup(this.settings.instrumentationKey).start();
this.appInsightsClient = ApplicationInsights.getClient(this.settings.instrumentationKey);
this.setupConsoleCollection();
// Adding middleware to intercept all user messages
if (bot) {
bot.use({
botbuilder: function (session, next) {
try {
let message: any = session.message;
let address = message.address || {};
let conversation = address.conversation || {};
let user = address.user || {};
let item = {
text: message.text,
type: message.type,
timestamp: message.timestamp,
conversationId: conversation.id,
channel: address.channelId,
userId: user.id,
userName: user.name
};
this.appInsightsClient.trackEvent(Events.UserMessage.name, item);
} catch (e) {
} finally {
next();
}
},
send: (message: any, next: (err?: Error) => void) => {
try {
let address = message.address || {};
let conversation = address.conversation || {};
let user = address.user || {};
let item = {
text: message.text,
type: message.type,
timestamp: message.timestamp,
conversationId: conversation.id
};
this.appInsightsClient.trackEvent(Events.BotMessage.name, item);
} catch (e) {
}
finally {
next();
}
}
});
}
// Monitoring new dialog calls like session.beginDialog
// When beginning a new dialog, the framework uses pushDialog to change context
// to a new dialog
// Todo: Check alternative as <builder.SimpleDialog.prototype.begin>
// builder.Session.prototype..pushDialog = (function() {
// var orig = builder.Session.prototype.pushDialog;
// return function (args) {
// var _session = this;
// var _message = _session.message || {};
// var _address = _message.address || {};
// var _conversation = _address.conversation || {};
// var _user = _address.user || {};
// var _callstack = _session.sessionState.callstack;
// var item = {
// intent: args && args.id,
// state: args && args.state && JSON.stringify(args.state),
// channel: _address.channelId,
// conversationId: _conversation.id,
// callstack_length: _callstack.length.toString(),
// userId: _user.id,
// userName: _user.name
// };
// _.take(_callstack, 3).forEach((stackItem: any, idx: number) => {
// item[`callstack_${idx}_id`] = stackItem.id;
// item[`callstack_${idx}_state`] = JSON.stringify(stackItem.state);
// });
// this.appInsightsClient.trackEvent(Events.Intents.name, item);
// orig.apply(_session, [args]);
// }
// })();
// Capture message session before send
// builder.Session.prototype.prepareMessage = (function() {
// var orig = builder.Session.prototype.prepareMessage;
// return function (msg) {
// var _session = this;
// var res = orig.apply(_session, [msg]);
// if (_session.dialogData['transaction.started']) {
// var transactionEnded = false;
// var success = false;
// var conversation = _.find(transactions, { intent: _session.dialogData['transaction.id'] });
// if (conversation.intent != _session.dialogData['BotBuilder.Data.Intent']) {
// transactionEnded = true;
// } else {
// var test = conversation.test;
// var success = typeof test == 'string' ? test == msg.text : test.test(msg.text);
// if (success) {
// transactionEnded = true;
// }
// }
// if (transactionEnded) {
// endConverting(_session, null, success);
// delete _session.dialogData['transaction.started'];
// delete _session.dialogData['transaction.id'];
// }
// }
// return res;
// }
// })();
// Collect intents collected from LUIS after entities were resolved
builder.IntentDialog.prototype.recognize = (() => {
let _recognize = builder.IntentDialog.prototype.recognize;
return function(context, cb) {
let _dialog = this;
_recognize.apply(_dialog, [context, (err, result) => {
var entities = [];
if (result && result.entities) {
result.entities.forEach(value => {
entities.push({
type: value.type,
entity: value.entity
})
});
}
let message = context.message;
let address = message.address || {};
let conversation = address.conversation || {};
let user = address.user || {};
let item = {
text: message.text,
timestamp: message.timestamp,
intent: result && result.intent,
channel: address.channelId,
score: result && result.score,
entities: entities,
withError: !err,
error: err,
conversationId: conversation.id,
userId: user.id,
userName: user.name
};
this.appInsightsClient.trackEvent(Events.Intent.name, item);
// transactions.forEach(cc => {
// if (cc.intent == item.intent) {
// startConverting(context, null);
// context.dialogData['transaction.started'] = true;
// context.dialogData['transaction.id'] = cc.intent;
// }
// });
this.collectSentiment(context, message.text);
// Todo: on "set alarm" utterence, failiure
return cb(err, result);
}]);
};
})();
}
startTransaction(context: any, name = '') {
let message = context.message;
let address = message.address || {};
let conversation = address.conversation || {};
let user = address.user || {};
let item = {
name: name,
timestamp: message.timestamp,
channel: address.channelId,
conversationId: conversation.id,
userId: user.id,
userName: user.name
};
this.appInsightsClient.trackEvent(Events.StartTransaction.name, item);
}
endTransaction(context: any, name = '', successful = true) {
let message = context.message;
let address = message.address || {};
let conversation = address.conversation || {};
let user = address.user || {};
let item = {
name: name,
successful: successful.toString(),
timestamp: message.timestamp,
channel: address.channelId,
conversationId: conversation.id,
userId: user.id,
userName: user.name
};
this.appInsightsClient.trackEvent(Events.EndTransaction.name, item);
}
}

4

package.json
{
"name": "botbuilder-instrumentation",
"version": "1.0.5",
"version": "1.0.6",
"description": "",
"main": "index.js",
"main": "main.js",
"scripts": {

@@ -7,0 +7,0 @@ "test": "echo \"Error: no test specified\" && exit 1"

@@ -5,3 +5,2 @@ {

"target": "es6",
"sourceMap": false,
"allowJs": true,

@@ -17,3 +16,6 @@ "moduleResolution": "node",

"node_modules"
],
"types": [
"node_modules/@types"
]
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc