@microsoft/agents-hosting-extensions-teams
Version:
Microsoft 365 Agents SDK for JavaScript. Teams extensions
210 lines • 11.5 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.TaskModule = exports.TaskModuleInvokeNames = void 0;
const agents_activity_1 = require("@microsoft/agents-activity");
const agents_hosting_1 = require("@microsoft/agents-hosting");
var TaskModuleInvokeNames;
(function (TaskModuleInvokeNames) {
TaskModuleInvokeNames["CONFIG_FETCH_INVOKE_NAME"] = "config/fetch";
TaskModuleInvokeNames["CONFIG_SUBMIT_INVOKE_NAME"] = "config/submit";
TaskModuleInvokeNames["FETCH_INVOKE_NAME"] = "task/fetch";
TaskModuleInvokeNames["SUBMIT_INVOKE_NAME"] = "task/submit";
TaskModuleInvokeNames["DEFAULT_TASK_DATA_FILTER"] = "verb";
})(TaskModuleInvokeNames || (exports.TaskModuleInvokeNames = TaskModuleInvokeNames = {}));
/**
* Class that exposes Teams task module-related events.
* Provides an organized way to handle task module operations in Microsoft Teams.
*/
class TaskModule {
/**
* Creates a new instance of the TaskModule class.
* @param app - The agent application
*/
constructor(app, options) {
this._options = options !== null && options !== void 0 ? options : { taskDataFilter: TaskModuleInvokeNames.DEFAULT_TASK_DATA_FILTER };
this._app = app;
}
/**
* Handles task module fetch events. These occur when a task module is requested to be displayed.
* @param handler - The handler to call when a task module fetch event occurs
* @returns this (for method chaining)
*/
onFetch(handler) {
const routeSel = (context) => {
return Promise.resolve(context.activity.type === agents_activity_1.ActivityTypes.Invoke &&
context.activity.channelId === 'msteams' &&
context.activity.name === 'task/fetch');
};
this._app.addRoute(routeSel, handler, true); // Invoke requires true
return this;
}
/**
* Registers a handler to process the submission of a task module.
* @remarks
* Handlers should respond with another TaskInfo object, message string, or `null` to indicate
* the task is completed.
* @template TData Optional. Type of the data object being passed to the handler.
* @param {string | RegExp | RouteSelector | string[] | RegExp[] | RouteSelector[]} verb - Name of the verb(s) to register the handler for.
* @param {(context: TurnContext, state: TState, data: TData) => Promise<TaskModuleTaskInfo | string | null | undefined>} handler - Function to call when the handler is triggered.
* @param {TurnContext} handler.context - Context for the current turn of conversation with the user.
* @param {TState} handler.state - Current state of the turn.
* @param {TData} handler.data - Data object passed to the handler.
* @returns {Application<TState>} The application for chaining purposes.
*/
submit(verb, handler) {
(Array.isArray(verb) ? verb : [verb]).forEach((v) => {
var _a;
const { DEFAULT_TASK_DATA_FILTER, SUBMIT_INVOKE_NAME } = TaskModuleInvokeNames;
const filterField = (_a = this._options.taskDataFilter) !== null && _a !== void 0 ? _a : DEFAULT_TASK_DATA_FILTER;
const selector = createTaskSelector(v, filterField, SUBMIT_INVOKE_NAME);
this._app.addRoute(selector, async (context, state) => {
var _a, _b, _c, _d, _e;
if (((_a = context === null || context === void 0 ? void 0 : context.activity) === null || _a === void 0 ? void 0 : _a.channelId) === agents_activity_1.Channels.Msteams) {
if (((_b = context === null || context === void 0 ? void 0 : context.activity) === null || _b === void 0 ? void 0 : _b.type) !== agents_activity_1.ActivityTypes.Invoke || ((_c = context === null || context === void 0 ? void 0 : context.activity) === null || _c === void 0 ? void 0 : _c.name) !== SUBMIT_INVOKE_NAME) {
throw new Error(`Unexpected TaskModules.submit() triggered for activity type: ${(_d = context === null || context === void 0 ? void 0 : context.activity) === null || _d === void 0 ? void 0 : _d.type}`);
}
const result = await handler(context, state, (_e = context.activity.value.data) !== null && _e !== void 0 ? _e : {});
if (!result) {
await context.sendActivity(agents_activity_1.Activity.fromObject({
value: { status: 200 },
type: agents_activity_1.ActivityTypes.InvokeResponse
}));
}
if (!context.turnState.get(agents_hosting_1.INVOKE_RESPONSE_KEY)) {
let response;
if (typeof result === 'string') {
response = {
task: {
type: 'message',
value: result
}
};
}
else if (typeof result === 'object') {
// Return card
response = {
task: {
type: 'continue',
value: result
}
};
}
// Queue up invoke response
await context.sendActivity(agents_activity_1.Activity.fromObject({
value: { body: response, status: 200 },
type: agents_activity_1.ActivityTypes.InvokeResponse
}));
}
}
}, true);
});
return this._app;
}
/**
* Handles specific task module fetch events based on a verb/action.
* @param verb - The verb or action identifier to match against in the task module data
* @param handler - The handler to call when a matching task module fetch event occurs
* @returns this (for method chaining)
*/
onFetchByVerb(verb, handler) {
const routeSel = (context) => {
var _a;
return Promise.resolve(context.activity.type === agents_activity_1.ActivityTypes.Invoke &&
context.activity.channelId === 'msteams' &&
context.activity.name === 'task/fetch' &&
// @ts-ignore
((_a = context.activity.value) === null || _a === void 0 ? void 0 : _a.data) === verb);
};
this._app.addRoute(routeSel, handler, true);
return this;
}
/**
* Handles specific task module submit events based on a verb/action.
* @param verb - The verb or action identifier to match against in the task module data
* @param handler - The handler to call when a matching task module submit event occurs
* @returns this (for method chaining)
*/
onSubmitByVerb(verb, handler) {
const routeSel = (context) => {
var _a;
return Promise.resolve(context.activity.type === agents_activity_1.ActivityTypes.Invoke &&
context.activity.channelId === 'msteams' &&
context.activity.name === 'task/submit' &&
// @ts-ignore
((_a = context.activity.value) === null || _a === void 0 ? void 0 : _a.data) === verb);
};
this._app.addRoute(routeSel, handler, true);
return this;
}
/**
* Handles configuration fetch events. These occur when an agent configuration is requested.
* @param handler - The handler to call when a configuration fetch event occurs
* @returns this (for method chaining)
*/
onConfigurationFetch(handler) {
const routeSel = (context) => {
return Promise.resolve(context.activity.type === agents_activity_1.ActivityTypes.Invoke &&
context.activity.channelId === 'msteams' &&
context.activity.name === 'config/fetch');
};
this._app.addRoute(routeSel, handler, true);
return this;
}
/**
* Handles configuration submit events. These occur when an agent configuration is submitted.
* @param handler - The handler to call when a configuration submit event occurs
* @returns this (for method chaining)
*/
onConfigurationSubmit(handler) {
const routeSel = (context) => {
return Promise.resolve(context.activity.type === agents_activity_1.ActivityTypes.Invoke &&
context.activity.channelId === 'msteams' &&
context.activity.name === 'config/submit');
};
this._app.addRoute(routeSel, handler, true);
return this;
}
}
exports.TaskModule = TaskModule;
/**
* Creates a route selector function for a given verb, filter field, and invoke name.
* @param {string | RegExp | RouteSelector} verb - The verb to match.
* @param {string} filterField - The field to use for filtering.
* @param {string} invokeName - The name of the invoke action.
* @returns {RouteSelector} The route selector function.
* @private
* @remarks
* This function is used to create a route selector function for a given verb, filter field, and invoke name.
* The route selector function is used to match incoming requests to the appropriate handler function.
*/
function createTaskSelector(verb, filterField, invokeName) {
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;
const isTeams = context.activity.channelId === agents_activity_1.Channels.Msteams;
const isInvoke = ((_a = context === null || context === void 0 ? void 0 : context.activity) === null || _a === void 0 ? void 0 : _a.type) === agents_activity_1.ActivityTypes.Invoke && ((_b = context === null || context === void 0 ? void 0 : context.activity) === null || _b === void 0 ? void 0 : _b.name) === invokeName;
const data = ((_c = context === null || context === void 0 ? void 0 : context.activity) === null || _c === void 0 ? void 0 : _c.value).data;
if (isInvoke && isTeams && typeof data === 'object' && typeof data[filterField] === 'string') {
return Promise.resolve(verb.test(data[filterField]));
}
else {
return Promise.resolve(false);
}
};
}
else {
// Return a function that attempts to match verb
return (context) => {
var _a, _b, _c;
const isInvoke = ((_a = context === null || context === void 0 ? void 0 : context.activity) === null || _a === void 0 ? void 0 : _a.type) === agents_activity_1.ActivityTypes.Invoke && ((_b = context === null || context === void 0 ? void 0 : context.activity) === null || _b === void 0 ? void 0 : _b.name) === invokeName;
const data = ((_c = context === null || context === void 0 ? void 0 : context.activity) === null || _c === void 0 ? void 0 : _c.value).data;
return Promise.resolve(isInvoke && typeof data === 'object' && data[filterField] === verb);
};
}
}
//# sourceMappingURL=taskModule.js.map