UNPKG

botbuilder

Version:

Bot Builder is a framework for building rich bots on virtually any platform.

174 lines • 8.96 kB
"use strict"; // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. 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.SkillHandlerImpl = void 0; const botframework_connector_1 = require("botframework-connector"); const uuid_1 = require("uuid"); const botbuilder_core_1 = require("botbuilder-core"); /** * @internal */ class SkillHandlerImpl { /** * @internal */ constructor(skillConversationReferenceKey, adapter, logic, conversationIdFactory, getOauthScope = () => undefined) { this.skillConversationReferenceKey = skillConversationReferenceKey; this.adapter = adapter; this.logic = logic; this.conversationIdFactory = conversationIdFactory; this.getOauthScope = getOauthScope; } /** * @internal */ onSendToConversation(claimsIdentity, conversationId, activity) { return this.processActivity(claimsIdentity, conversationId, null, activity); } /** * @internal */ onReplyToActivity(claimsIdentity, conversationId, activityId, activity) { return this.processActivity(claimsIdentity, conversationId, activityId, activity); } /** * @internal */ onUpdateActivity(claimsIdentity, conversationId, activityId, activity) { return __awaiter(this, void 0, void 0, function* () { let resourceResponse; yield this.continueConversation(claimsIdentity, conversationId, (context, ref) => __awaiter(this, void 0, void 0, function* () { const newActivity = botbuilder_core_1.TurnContext.applyConversationReference(activity, ref.conversationReference); context.activity.id = activityId; context.activity.callerId = `${botbuilder_core_1.CallerIdConstants.BotToBotPrefix}${botframework_connector_1.JwtTokenValidation.getAppIdFromClaims(claimsIdentity.claims)}`; resourceResponse = yield context.updateActivity(newActivity); })); return resourceResponse ? resourceResponse : { id: activityId }; }); } /** * @internal */ onDeleteActivity(claimsIdentity, conversationId, activityId) { return __awaiter(this, void 0, void 0, function* () { return this.continueConversation(claimsIdentity, conversationId, (context) => context.deleteActivity(activityId)); }); } getSkillConversationReference(conversationId) { return __awaiter(this, void 0, void 0, function* () { let skillConversationReference; try { skillConversationReference = yield this.conversationIdFactory.getSkillConversationReference(conversationId); } catch (err) { // If the factory has overridden getSkillConversationReference, call the deprecated getConversationReference(). // In this scenario, the oAuthScope paired with the ConversationReference can only be used for talking with // an official channel, not another bot. if (err.message === 'NotImplemented') { skillConversationReference = { conversationReference: yield this.conversationIdFactory.getConversationReference(conversationId), oAuthScope: this.getOauthScope(), }; } else { throw err; } } if (!skillConversationReference) { throw new Error('skillConversationReference not found'); } else if (!skillConversationReference.conversationReference) { throw new Error('conversationReference not found.'); } return skillConversationReference; }); } processActivity(claimsIdentity, conversationId, replyToActivityId, activity) { return __awaiter(this, void 0, void 0, function* () { let resourceResponse; yield this.continueConversation(claimsIdentity, conversationId, (context, ref) => __awaiter(this, void 0, void 0, function* () { /** * This callback does the following: * - Applies the correct ConversationReference to the Activity for sending to the user-router conversation. * - For EndOfConversation Activities received from the Skill, removes the ConversationReference from the * ConversationIdFactory */ const newActivity = botbuilder_core_1.TurnContext.applyConversationReference(activity, ref.conversationReference); context.activity.id = replyToActivityId; context.activity.callerId = `${botbuilder_core_1.CallerIdConstants.BotToBotPrefix}${botframework_connector_1.JwtTokenValidation.getAppIdFromClaims(claimsIdentity.claims)}`; switch (newActivity.type) { case botbuilder_core_1.ActivityTypes.EndOfConversation: yield this.conversationIdFactory.deleteConversationReference(conversationId); this.applySkillActivityToTurnContext(context, newActivity); yield this.logic(context); break; case botbuilder_core_1.ActivityTypes.Event: this.applySkillActivityToTurnContext(context, newActivity); yield this.logic(context); break; default: resourceResponse = yield context.sendActivity(newActivity); break; } })); if (!resourceResponse) { resourceResponse = { id: uuid_1.v4() }; } return resourceResponse; }); } continueConversation(claimsIdentity, conversationId, callback) { return __awaiter(this, void 0, void 0, function* () { const ref = yield this.getSkillConversationReference(conversationId); const continueCallback = (context) => { context.turnState.set(this.skillConversationReferenceKey, ref); return callback(context, ref); }; try { yield this.adapter.continueConversationAsync(claimsIdentity, ref.conversationReference, ref.oAuthScope, continueCallback); } catch (err) { if (err.message === 'NotImplemented') { // We're in the legacy scenario where our adapter does not support passing through claims/audience // explicitly. Stash it in turn context and hope for the best! yield this.adapter.continueConversation(ref.conversationReference, (context) => __awaiter(this, void 0, void 0, function* () { context.turnState.set(context.adapter.BotIdentityKey, claimsIdentity); return continueCallback(context); })); } else { throw err; } } }); } // adapter.continueConversation() sends an event activity with continueConversation in the name. // this warms up the incoming middlewares but once that's done and we hit the custom callback, // we need to swap the values back to the ones received from the skill so the bot gets the actual activity. applySkillActivityToTurnContext(context, activity) { context.activity.channelData = activity.channelData; context.activity.code = activity.code; context.activity.entities = activity.entities; context.activity.locale = activity.locale; context.activity.localTimestamp = activity.localTimestamp; context.activity.name = activity.name; context.activity.relatesTo = activity.relatesTo; context.activity.replyToId = activity.replyToId; context.activity.timestamp = activity.timestamp; context.activity.text = activity.text; context.activity.type = activity.type; context.activity.value = activity.value; } } exports.SkillHandlerImpl = SkillHandlerImpl; //# sourceMappingURL=skillHandlerImpl.js.map