UNPKG

@microsoft/agents-hosting-teams

Version:

Microsoft 365 Agents SDK for JavaScript

423 lines 23.7 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.MessageExtensions = void 0; /** * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. */ const agents_activity_1 = require("@microsoft/agents-activity"); const agents_hosting_1 = require("@microsoft/agents-hosting"); const messageExtensionsInvokeNames_1 = require("./messageExtensionsInvokeNames"); const parsers_1 = require("../../parsers"); /** * The MessageExtensions class provides methods to handle various messaging extension scenarios in a Teams application. * It allows developers to define handlers for different invoke activities such as queries, task fetches, and message previews. * @template TState - The type of the TurnState used in the application. */ class MessageExtensions { /** * Creates an instance of MessageExtensions. * @param app - The TeamsApplication instance to associate with this MessageExtensions instance. */ constructor(app) { this._app = app; } /** * Registers a handler for the anonymous query link invoke activity. * @param handler - A function to handle the anonymous query link. * @returns The TeamsApplication instance. */ anonymousQueryLink(handler) { const { ANONYMOUS_QUERY_LINK_INVOKE } = messageExtensionsInvokeNames_1.MessageExtensionsInvokeNames; const selector = (context) => { var _a; return Promise.resolve(((_a = context === null || context === void 0 ? void 0 : context.activity) === null || _a === void 0 ? void 0 : _a.type) === agents_activity_1.ActivityTypes.Invoke && (context === null || context === void 0 ? void 0 : context.activity.name) === ANONYMOUS_QUERY_LINK_INVOKE); }; this._app.addRoute(selector, async (context, state) => { var _a; const activityValueUrl = (0, parsers_1.parseValueQuery)(context.activity.value); const result = await handler(context, state, (_a = activityValueUrl.url) !== null && _a !== void 0 ? _a : ''); if (!context.turnState.get(agents_hosting_1.INVOKE_RESPONSE_KEY)) { const response = { composeExtension: result }; await context.sendActivity({ value: { body: response, status: 200 }, type: agents_activity_1.ActivityTypes.InvokeResponse }); } }, true); return this._app; } /** * Registers a handler for editing a message preview. * @param commandId - The command ID(s) or selector(s) to match the activity. * @param handler - A function to handle the message preview edit. * @returns The TeamsApplication instance. */ messagePreviewEdit(commandId, handler) { const { SUBMIT_ACTION_INVOKE } = messageExtensionsInvokeNames_1.MessageExtensionsInvokeNames; (Array.isArray(commandId) ? commandId : [commandId]).forEach((cid) => { const selector = createTaskSelector(cid, SUBMIT_ACTION_INVOKE, 'edit'); this._app.addRoute(selector, async (context, state) => { var _a, _b, _c, _d; const activityValue = (0, parsers_1.parseValueAgentMessagePreviewAction)(context.activity.value); if (((_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) !== SUBMIT_ACTION_INVOKE || activityValue.botMessagePreviewAction !== 'edit') { throw new Error(`Unexpected MessageExtensions.messagePreviewEdit() triggered for activity type: ${(_c = context === null || context === void 0 ? void 0 : context.activity) === null || _c === void 0 ? void 0 : _c.type}`); } const activityActivityPreview = (0, parsers_1.parseValueAgentActivityPreview)(context.activity.value); const result = await handler(context, state, (_d = activityActivityPreview.botActivityPreview[0]) !== null && _d !== void 0 ? _d : {}); await this.returnSubmitActionResponse(context, result); }, true); }); return this._app; } /** * Registers a handler for sending a message preview. * @param commandId - The command ID(s) or selector(s) to match the activity. * @param handler - A function to handle the message preview send. * @returns The TeamsApplication instance. */ messagePreviewSend(commandId, handler) { const { SUBMIT_ACTION_INVOKE } = messageExtensionsInvokeNames_1.MessageExtensionsInvokeNames; (Array.isArray(commandId) ? commandId : [commandId]).forEach((cid) => { const selector = createTaskSelector(cid, SUBMIT_ACTION_INVOKE, 'send'); this._app.addRoute(selector, async (context, state) => { var _a, _b, _c, _d; const activityMessagePreviewAction = (0, parsers_1.parseValueAgentMessagePreviewAction)(context.activity.value); if (((_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) !== SUBMIT_ACTION_INVOKE || activityMessagePreviewAction.botMessagePreviewAction !== 'send') { throw new Error(`Unexpected MessageExtensions.messagePreviewSend() triggered for activity type: ${(_c = context === null || context === void 0 ? void 0 : context.activity) === null || _c === void 0 ? void 0 : _c.type}`); } const activityActivityPreview = (0, parsers_1.parseValueAgentActivityPreview)(context.activity.value); await handler(context, state, (_d = activityActivityPreview.botActivityPreview[0]) !== null && _d !== void 0 ? _d : {}); if (!context.turnState.get(agents_hosting_1.INVOKE_RESPONSE_KEY)) { await context.sendActivity({ value: { body: {}, status: 200 }, type: agents_activity_1.ActivityTypes.InvokeResponse }); } }, true); }); return this._app; } /** * Registers a handler for fetching a task module. * @param commandId - The command ID(s) or selector(s) to match the activity. * @param handler - A function to handle the task fetch. * @returns The TeamsApplication instance. */ fetchTask(commandId, handler) { const { FETCH_TASK_INVOKE } = messageExtensionsInvokeNames_1.MessageExtensionsInvokeNames; (Array.isArray(commandId) ? commandId : [commandId]).forEach((cid) => { const selector = createTaskSelector(cid, FETCH_TASK_INVOKE); this._app.addRoute(selector, async (context, state) => { var _a, _b, _c; if (((_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) !== FETCH_TASK_INVOKE) { throw new Error(`Unexpected MessageExtensions.fetchTask() triggered for activity type: ${(_c = context === null || context === void 0 ? void 0 : context.activity) === null || _c === void 0 ? void 0 : _c.type}`); } const result = await handler(context, state); if (!context.turnState.get(agents_hosting_1.INVOKE_RESPONSE_KEY)) { let response; if (typeof result === 'string') { response = { task: { type: 'message', value: result } }; } else { response = { task: { type: 'continue', value: result } }; } await context.sendActivity({ value: { body: response, status: 200 }, type: agents_activity_1.ActivityTypes.InvokeResponse }); } }, true); }); return this._app; } /** * Registers a handler for a query invoke activity. * @param commandId - The command ID(s) or selector(s) to match the activity. * @param handler - A function to handle the query. * @returns The TeamsApplication instance. */ query(commandId, handler) { const { QUERY_INVOKE } = messageExtensionsInvokeNames_1.MessageExtensionsInvokeNames; (Array.isArray(commandId) ? commandId : [commandId]).forEach((cid) => { const selector = createTaskSelector(cid, QUERY_INVOKE); this._app.addRoute(selector, async (context, state) => { var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k; if (((_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) !== QUERY_INVOKE) { throw new Error(`Unexpected MessageExtensions.query() triggered for activity type: ${(_c = context === null || context === void 0 ? void 0 : context.activity) === null || _c === void 0 ? void 0 : _c.type}`); } const meQuery = (_e = (_d = context === null || context === void 0 ? void 0 : context.activity) === null || _d === void 0 ? void 0 : _d.value) !== null && _e !== void 0 ? _e : {}; const query = { count: (_g = (_f = meQuery === null || meQuery === void 0 ? void 0 : meQuery.queryOptions) === null || _f === void 0 ? void 0 : _f.count) !== null && _g !== void 0 ? _g : 25, skip: (_j = (_h = meQuery === null || meQuery === void 0 ? void 0 : meQuery.queryOptions) === null || _h === void 0 ? void 0 : _h.skip) !== null && _j !== void 0 ? _j : 0, parameters: {} }; ((_k = meQuery.parameters) !== null && _k !== void 0 ? _k : []).forEach((param) => { if (param.name) { query.parameters[param.name] = param.value; } }); const result = await handler(context, state, query); if (!context.turnState.get(agents_hosting_1.INVOKE_RESPONSE_KEY)) { const response = { composeExtension: result }; await context.sendActivity({ value: { body: response, status: 200 }, type: agents_activity_1.ActivityTypes.InvokeResponse }); } }, true); }); return this._app; } /** * Registers a handler for a query link invoke activity. * @param handler - A function to handle the query link. * @returns The TeamsApplication instance. */ queryLink(handler) { const { QUERY_LINK_INVOKE } = messageExtensionsInvokeNames_1.MessageExtensionsInvokeNames; const selector = (context) => { var _a; return Promise.resolve(((_a = context === null || context === void 0 ? void 0 : context.activity) === null || _a === void 0 ? void 0 : _a.type) === agents_activity_1.ActivityTypes.Invoke && (context === null || context === void 0 ? void 0 : context.activity.name) === QUERY_LINK_INVOKE); }; this._app.addRoute(selector, async (context, state) => { const activityValueUrl = (0, parsers_1.parseValueQuery)(context.activity.value); const result = await handler(context, state, activityValueUrl.url); if (!context.turnState.get(agents_hosting_1.INVOKE_RESPONSE_KEY)) { const response = { composeExtension: result }; await context.sendActivity({ value: { body: response, status: 200 }, type: agents_activity_1.ActivityTypes.InvokeResponse }); } }, true); return this._app; } /** * Registers a handler for selecting an item in a messaging extension. * @param handler - A function to handle the item selection. * @returns The TeamsApplication instance. */ selectItem(handler) { const { SELECT_ITEM_INVOKE } = messageExtensionsInvokeNames_1.MessageExtensionsInvokeNames; const selector = (context) => { var _a; return Promise.resolve(((_a = context === null || context === void 0 ? void 0 : context.activity) === null || _a === void 0 ? void 0 : _a.type) === agents_activity_1.ActivityTypes.Invoke && (context === null || context === void 0 ? void 0 : context.activity.name) === SELECT_ITEM_INVOKE); }; this._app.addRoute(selector, async (context, state) => { var _a, _b; const result = await handler(context, state, (_b = (_a = context === null || context === void 0 ? void 0 : context.activity) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : {}); if (!context.turnState.get(agents_hosting_1.INVOKE_RESPONSE_KEY)) { const response = { composeExtension: result }; await context.sendActivity({ value: { body: response, status: 200 }, type: agents_activity_1.ActivityTypes.InvokeResponse }); } }, true); return this._app; } /** * Registers a handler for submitting an action in a messaging extension. * @param commandId - The command ID(s) or selector(s) to match the activity. * @param handler - A function to handle the action submission. * @returns The TeamsApplication instance. */ submitAction(commandId, handler) { const { SUBMIT_ACTION_INVOKE } = messageExtensionsInvokeNames_1.MessageExtensionsInvokeNames; (Array.isArray(commandId) ? commandId : [commandId]).forEach((cid) => { const selector = createTaskSelector(cid, SUBMIT_ACTION_INVOKE); 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.type) !== agents_activity_1.ActivityTypes.Invoke || ((_b = context === null || context === void 0 ? void 0 : context.activity) === null || _b === void 0 ? void 0 : _b.name) !== SUBMIT_ACTION_INVOKE) { throw new Error(`Unexpected MessageExtensions.submitAction() triggered for activity type: ${(_c = context === null || context === void 0 ? void 0 : context.activity) === null || _c === void 0 ? void 0 : _c.type}`); } const result = await handler(context, state, (_e = (_d = context.activity.value) === null || _d === void 0 ? void 0 : _d.data) !== null && _e !== void 0 ? _e : {}); await this.returnSubmitActionResponse(context, result); }, true); }); return this._app; } /** * Sends a response for a submit action invoke activity. * @param context - The TurnContext of the activity. * @param result - The result to send in the response. */ async returnSubmitActionResponse(context, result) { 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' && result != null) { if (result.card) { response = { task: { type: 'continue', value: result } }; } else { response = { composeExtension: result }; } } else { response = { composeExtension: undefined }; } await context.sendActivity({ value: { body: response, status: 200 }, type: agents_activity_1.ActivityTypes.InvokeResponse }); } } /** * Registers a handler for querying a URL setting in a messaging extension. * @param handler - A function to handle the URL setting query. * @returns The TeamsApplication instance. */ queryUrlSetting(handler) { const { QUERY_SETTING_URL } = messageExtensionsInvokeNames_1.MessageExtensionsInvokeNames; const selector = (context) => { var _a; return Promise.resolve(((_a = context === null || context === void 0 ? void 0 : context.activity) === null || _a === void 0 ? void 0 : _a.type) === agents_activity_1.ActivityTypes.Invoke && (context === null || context === void 0 ? void 0 : context.activity.name) === QUERY_SETTING_URL); }; this._app.addRoute(selector, async (context, state) => { const result = await handler(context, state); if (!context.turnState.get(agents_hosting_1.INVOKE_RESPONSE_KEY)) { const response = { composeExtension: result }; await context.sendActivity({ value: { status: 200, body: response }, type: agents_activity_1.ActivityTypes.InvokeResponse }); } }, true); return this._app; } /** * Registers a handler for configuring settings in a messaging extension. * @param handler - A function to handle the settings configuration. * @returns The TeamsApplication instance. */ configureSettings(handler) { const { CONFIGURE_SETTINGS } = messageExtensionsInvokeNames_1.MessageExtensionsInvokeNames; const selector = (context) => { var _a; return Promise.resolve(((_a = context === null || context === void 0 ? void 0 : context.activity) === null || _a === void 0 ? void 0 : _a.type) === agents_activity_1.ActivityTypes.Invoke && (context === null || context === void 0 ? void 0 : context.activity.name) === CONFIGURE_SETTINGS); }; this._app.addRoute(selector, async (context, state) => { var _a; await handler(context, state, (_a = context.activity.value) !== null && _a !== void 0 ? _a : {}); if (!context.turnState.get(agents_hosting_1.INVOKE_RESPONSE_KEY)) { await context.sendActivity({ value: { status: 200 }, type: agents_activity_1.ActivityTypes.InvokeResponse }); } }, true); return this._app; } /** * Registers a handler for handling button clicks in a messaging extension card. * @param handler - A function to handle the button click. * @returns The TeamsApplication instance. */ handleOnButtonClicked(handler) { const { QUERY_CARD_BUTTON_CLICKED } = messageExtensionsInvokeNames_1.MessageExtensionsInvokeNames; const selector = (context) => { var _a; return Promise.resolve(((_a = context === null || context === void 0 ? void 0 : context.activity) === null || _a === void 0 ? void 0 : _a.type) === agents_activity_1.ActivityTypes.Invoke && (context === null || context === void 0 ? void 0 : context.activity.name) === QUERY_CARD_BUTTON_CLICKED); }; this._app.addRoute(selector, async (context, state) => { var _a; await handler(context, state, (_a = context.activity.value) !== null && _a !== void 0 ? _a : {}); if (!context.turnState.get(agents_hosting_1.INVOKE_RESPONSE_KEY)) { await context.sendActivity({ value: { status: 200 }, type: agents_activity_1.ActivityTypes.InvokeResponse }); } }, true); return this._app; } } exports.MessageExtensions = MessageExtensions; function createTaskSelector(commandId, invokeName, messagePreviewAction) { if (typeof commandId === 'function') { return commandId; } else if (commandId instanceof RegExp) { return (context) => { var _a, _b; const activityValue = (0, parsers_1.parseValueCommandId)(context.activity.value); 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; if (isInvoke && typeof activityValue.commandId === 'string' && matchesPreviewAction(context.activity, messagePreviewAction)) { return Promise.resolve(commandId.test(activityValue.commandId)); } else { return Promise.resolve(false); } }; } else { return (context) => { var _a, _b, _c; if (!((_a = context.activity.name) === null || _a === void 0 ? void 0 : _a.includes('task'))) { const activityValue = (0, parsers_1.parseValueCommandId)(context.activity.value); const isInvoke = ((_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) === invokeName; return Promise.resolve(isInvoke && activityValue.commandId === commandId && matchesPreviewAction(context.activity, messagePreviewAction)); } return Promise.resolve(false); }; } } function matchesPreviewAction(activity, messagePreviewAction) { if ('botMessagePreviewAction' in (activity === null || activity === void 0 ? void 0 : activity.value)) { const activityValue = (0, parsers_1.parseValueAgentMessagePreviewAction)(activity.value); return activityValue.botMessagePreviewAction === messagePreviewAction; } else { return messagePreviewAction === undefined; } } //# sourceMappingURL=messageExtensions.js.map