188 lines
No EOL
9.4 KiB
JavaScript
188 lines
No EOL
9.4 KiB
JavaScript
"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));
|
|
});
|
|
}
|
|
/**
|
|
* @internal
|
|
*/
|
|
onGetMember(claimsIdentity, userId, conversationId) {
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
let member = null;
|
|
yield this.continueConversation(claimsIdentity, conversationId, (context) => __awaiter(this, void 0, void 0, function* () {
|
|
const client = context.turnState.get(context.adapter.ConnectorClientKey);
|
|
const conversationId = context.activity.conversation.id;
|
|
member = yield client.conversations.getConversationMember(conversationId, userId);
|
|
}));
|
|
return member;
|
|
});
|
|
}
|
|
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: (0, 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
|