@microsoft/botbuilder-m365
Version:
M365 extensions for Microsoft BotBuilder, Alpha release.
254 lines (253 loc) • 14.6 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.AdaptiveCards = void 0;
/**
* @module botbuilder-m365
*/
/**
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/
// TODO:
/* eslint-disable security/detect-object-injection */
const botbuilder_1 = require("botbuilder");
const ACTION_INVOKE_NAME = `adaptiveCard/action`;
const ACTION_EXECUTE_TYPE = `Action.Execute`;
const DEFAULT_ACTION_SUBMIT_FILTER = 'verb';
const SEARCH_INvOKE_NAME = `application/search`;
class AdaptiveCards {
constructor(app) {
this._app = app;
}
/**
*
* @param {string | RegExp | RouteSelector | string[] | RegExp[] | RouteSelector[]} verb The name action(s) to be handled
* @param {Promise<AdaptiveCard | string>} handler The promise returning the Adaptive Card or string to be executed
* @returns {Application} The application
*/
actionExecute(verb, handler) {
(Array.isArray(verb) ? verb : [verb]).forEach((v) => {
const selector = createActionExecuteSelector(v);
this._app.addRoute(selector, (context, state) => __awaiter(this, void 0, void 0, function* () {
var _a, _b, _c, _d, _e;
// Insure that we're in an Action.Execute as expected
const a = context === null || context === void 0 ? void 0 : context.activity;
if ((a === null || a === void 0 ? void 0 : a.type) !== botbuilder_1.ActivityTypes.Invoke ||
(a === null || a === void 0 ? void 0 : a.name) !== ACTION_INVOKE_NAME ||
((_b = (_a = a === null || a === void 0 ? void 0 : a.value) === null || _a === void 0 ? void 0 : _a.action) === null || _b === void 0 ? void 0 : _b.type) !== ACTION_EXECUTE_TYPE) {
throw new Error(`Unexpected AdaptiveCards.actionExecute() triggered for activity type: ${a === null || a === void 0 ? void 0 : a.type}`);
}
// Call handler and then check to see if an invoke response has already been added
const result = yield handler(context, state, (_e = (_d = (_c = a.value) === null || _c === void 0 ? void 0 : _c.action) === null || _d === void 0 ? void 0 : _d.data) !== null && _e !== void 0 ? _e : {});
if (!context.turnState.get(botbuilder_1.INVOKE_RESPONSE_KEY)) {
// Format invoke response
let response;
if (typeof result == 'string') {
// Return message
response = {
statusCode: 200,
type: 'application/vnd.microsoft.activity.message',
value: result
};
}
else {
// Return card
response = {
statusCode: 200,
type: 'application/vnd.microsoft.card.adaptive',
value: result
};
}
// Queue up invoke response
yield context.sendActivity({
value: { body: response, status: 200 },
type: botbuilder_1.ActivityTypes.InvokeResponse
});
}
}), true);
});
return this._app;
}
actionSubmit(verb, handler) {
var _a, _b;
const filter = (_b = (_a = this._app.options.adaptiveCards) === null || _a === void 0 ? void 0 : _a.actionSubmitFilter) !== null && _b !== void 0 ? _b : DEFAULT_ACTION_SUBMIT_FILTER;
(Array.isArray(verb) ? verb : [verb]).forEach((v) => {
const selector = createActionSubmitSelector(v, filter);
this._app.addRoute(selector, (context, state) => __awaiter(this, void 0, void 0, function* () {
var _a;
// Insure that we're in an Action.Execute as expected
const a = context === null || context === void 0 ? void 0 : context.activity;
if ((a === null || a === void 0 ? void 0 : a.type) !== botbuilder_1.ActivityTypes.Message || (a === null || a === void 0 ? void 0 : a.text) || typeof (a === null || a === void 0 ? void 0 : a.value) !== 'object') {
throw new Error(`Unexpected AdaptiveCards.actionSubmit() triggered for activity type: ${a === null || a === void 0 ? void 0 : a.type}`);
}
// Call handler
yield handler(context, state, (_a = a.value) !== null && _a !== void 0 ? _a : {});
}));
});
return this._app;
}
search(dataset, handler) {
(Array.isArray(dataset) ? dataset : [dataset]).forEach((ds) => {
const selector = createSearchSelector(ds);
this._app.addRoute(selector, (context, state) => __awaiter(this, void 0, void 0, function* () {
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
// Insure that we're in an Action.Execute as expected
const a = context === null || context === void 0 ? void 0 : context.activity;
if ((a === null || a === void 0 ? void 0 : a.type) !== botbuilder_1.ActivityTypes.Invoke || (a === null || a === void 0 ? void 0 : a.name) !== SEARCH_INvOKE_NAME) {
throw new Error(`Unexpected AdaptiveCards.search() triggered for activity type: ${a === null || a === void 0 ? void 0 : a.type}`);
}
// Flatten search parameters
const query = {
count: (_c = (_b = (_a = a === null || a === void 0 ? void 0 : a.value) === null || _a === void 0 ? void 0 : _a.queryOptions) === null || _b === void 0 ? void 0 : _b.top) !== null && _c !== void 0 ? _c : 25,
skip: (_f = (_e = (_d = a === null || a === void 0 ? void 0 : a.value) === null || _d === void 0 ? void 0 : _d.queryOptions) === null || _e === void 0 ? void 0 : _e.skip) !== null && _f !== void 0 ? _f : 0,
parameters: {
queryText: (_h = (_g = a === null || a === void 0 ? void 0 : a.value) === null || _g === void 0 ? void 0 : _g.queryText) !== null && _h !== void 0 ? _h : '',
dataset: (_k = (_j = a === null || a === void 0 ? void 0 : a.value) === null || _j === void 0 ? void 0 : _j.dataset) !== null && _k !== void 0 ? _k : ''
}
};
// Call handler and then check to see if an invoke response has already been added
const results = yield handler(context, state, query);
if (!context.turnState.get(botbuilder_1.INVOKE_RESPONSE_KEY)) {
// Format invoke response
const response = {
type: 'application/vnd.microsoft.search.searchResponse',
value: {
results: results
}
};
// Queue up invoke response
yield context.sendActivity({
value: { body: response, status: 200 },
type: botbuilder_1.ActivityTypes.InvokeResponse
});
}
}), true);
});
return this._app;
}
}
exports.AdaptiveCards = AdaptiveCards;
/**
* Selector to match an Action.Execute invoke activity.
*
* @param {string | RegExp | RouteSelector} verb action name, RegExp, or RouteSelector to match
* @returns {RouteSelector} The selector Promise
*/
function createActionExecuteSelector(verb) {
if (typeof verb == 'function') {
// Return the passed in selector function
return verb;
}
else if (verb instanceof RegExp) {
// Return a function that matches the verb using a RegExp
return (context) => {
var _a, _b, _c, _d;
const a = context === null || context === void 0 ? void 0 : context.activity;
const isInvoke = (a === null || a === void 0 ? void 0 : a.type) == botbuilder_1.ActivityTypes.Invoke &&
(a === null || a === void 0 ? void 0 : a.name) === ACTION_INVOKE_NAME &&
((_b = (_a = a === null || a === void 0 ? void 0 : a.value) === null || _a === void 0 ? void 0 : _a.action) === null || _b === void 0 ? void 0 : _b.type) === ACTION_EXECUTE_TYPE;
if (isInvoke && typeof ((_d = (_c = a === null || a === void 0 ? void 0 : a.value) === null || _c === void 0 ? void 0 : _c.action) === null || _d === void 0 ? void 0 : _d.verb) == 'string') {
return Promise.resolve(verb.test(a.value.action.verb));
}
else {
return Promise.resolve(false);
}
};
}
else {
// Return a function that attempts to match verb
return (context) => {
var _a, _b, _c, _d;
const a = context === null || context === void 0 ? void 0 : context.activity;
const isInvoke = (a === null || a === void 0 ? void 0 : a.type) == botbuilder_1.ActivityTypes.Invoke &&
(a === null || a === void 0 ? void 0 : a.name) === ACTION_INVOKE_NAME &&
((_b = (_a = a === null || a === void 0 ? void 0 : a.value) === null || _a === void 0 ? void 0 : _a.action) === null || _b === void 0 ? void 0 : _b.type) === ACTION_EXECUTE_TYPE;
if (isInvoke && ((_d = (_c = a === null || a === void 0 ? void 0 : a.value) === null || _c === void 0 ? void 0 : _c.action) === null || _d === void 0 ? void 0 : _d.verb) === verb) {
return Promise.resolve(true);
}
else {
return Promise.resolve(false);
}
};
}
}
/**
* This function is used to create a selector function that will match on a submit action for a specific verb.
*
* @param {string} verb The verb to match. Can be a string, RegExp, or RouteSelector function.
* @param {string} filter The property on the activity value object to match the verb against.
* @returns {RouteSelector} RouteSelector that matches on a submit action for a specific verb.
*/
function createActionSubmitSelector(verb, filter) {
if (typeof verb == 'function') {
// Return the passed in selector function
return verb;
}
else if (verb instanceof RegExp) {
// Return a function that matches the verb using a RegExp
return (context) => {
const a = context === null || context === void 0 ? void 0 : context.activity;
const isSubmit = (a === null || a === void 0 ? void 0 : a.type) == botbuilder_1.ActivityTypes.Message && !(a === null || a === void 0 ? void 0 : a.text) && typeof (a === null || a === void 0 ? void 0 : a.value) === 'object';
if (isSubmit && typeof (a === null || a === void 0 ? void 0 : a.value[filter]) == 'string') {
return Promise.resolve(verb.test(a.value[filter]));
}
else {
return Promise.resolve(false);
}
};
}
else {
// Return a function that attempts to match verb
return (context) => {
const a = context === null || context === void 0 ? void 0 : context.activity;
const isSubmit = (a === null || a === void 0 ? void 0 : a.type) == botbuilder_1.ActivityTypes.Message && !(a === null || a === void 0 ? void 0 : a.text) && typeof (a === null || a === void 0 ? void 0 : a.value) === 'object';
return Promise.resolve(isSubmit && (a === null || a === void 0 ? void 0 : a.value[filter]) === verb);
};
}
}
/**
* This code creates a RouteSelector that can be used to route search requests to
* a bot's search handler.
*
* @param {string | RegExp | RouteSelector} dataset The dataset to match. Can be a string, RegExp, or RouteSelector function.
@returns {RouteSelector} Route's search requests to a bot's search handler.
*/
function createSearchSelector(dataset) {
if (typeof dataset == 'function') {
// Return the passed in selector function
return dataset;
}
else if (dataset instanceof RegExp) {
// Return a function that matches the dataset using a RegExp
return (context) => {
var _a;
const a = context === null || context === void 0 ? void 0 : context.activity;
const isSearch = (a === null || a === void 0 ? void 0 : a.type) == botbuilder_1.ActivityTypes.Invoke && (a === null || a === void 0 ? void 0 : a.name) === SEARCH_INvOKE_NAME;
if (isSearch && typeof ((_a = a === null || a === void 0 ? void 0 : a.value) === null || _a === void 0 ? void 0 : _a.dataset) == 'string') {
return Promise.resolve(dataset.test(a.value.dataset));
}
else {
return Promise.resolve(false);
}
};
}
else {
// Return a function that attempts to match dataset
return (context) => {
var _a;
const a = context === null || context === void 0 ? void 0 : context.activity;
const isSearch = (a === null || a === void 0 ? void 0 : a.type) == botbuilder_1.ActivityTypes.Invoke && (a === null || a === void 0 ? void 0 : a.name) === SEARCH_INvOKE_NAME;
return Promise.resolve(isSearch && ((_a = a === null || a === void 0 ? void 0 : a.value) === null || _a === void 0 ? void 0 : _a.dataset) === dataset);
};
}
}
//# sourceMappingURL=AdaptiveCards.js.map