693 lines
No EOL
28 KiB
JavaScript
693 lines
No EOL
28 KiB
JavaScript
"use strict";
|
|
/**
|
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
* 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.TurnContext = exports.BotCallbackHandlerKey = void 0;
|
|
const _1 = require(".");
|
|
const internal_1 = require("./internal");
|
|
const turnContextStateCollection_1 = require("./turnContextStateCollection");
|
|
const botframework_schema_1 = require("botframework-schema");
|
|
exports.BotCallbackHandlerKey = 'botCallbackHandler';
|
|
function getAppropriateReplyToId(source) {
|
|
if (source.type !== botframework_schema_1.ActivityTypes.ConversationUpdate ||
|
|
(source.channelId !== botframework_schema_1.Channels.Directline && source.channelId !== botframework_schema_1.Channels.Webchat)) {
|
|
return source.id;
|
|
}
|
|
return undefined;
|
|
}
|
|
/**
|
|
* Provides context for a turn of a bot.
|
|
*
|
|
* @remarks
|
|
* Context provides information needed to process an incoming activity. The context object is
|
|
* created by a [BotAdapter](xref:botbuilder-core.BotAdapter) and persists for the length of the turn.
|
|
*/
|
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging
|
|
class TurnContext {
|
|
/**
|
|
* Creates an new instance of the [TurnContext](xref:xref:botbuilder-core.TurnContext) class.
|
|
*
|
|
* @param adapterOrContext The adapter creating the context or the context object to clone.
|
|
* @param request Optional. The incoming activity for the turn.
|
|
*/
|
|
constructor(adapterOrContext, request) {
|
|
this._respondedRef = { responded: false };
|
|
this._turnState = new turnContextStateCollection_1.TurnContextStateCollection();
|
|
this._onSendActivities = [];
|
|
this._onUpdateActivity = [];
|
|
this._onDeleteActivity = [];
|
|
this._turn = 'turn';
|
|
this._locale = 'locale';
|
|
/**
|
|
* List of activities to send when `context.activity.deliveryMode == 'expectReplies'`.
|
|
*/
|
|
this.bufferedReplyActivities = [];
|
|
if (adapterOrContext instanceof TurnContext) {
|
|
adapterOrContext.copyTo(this);
|
|
}
|
|
else {
|
|
this._adapter = adapterOrContext;
|
|
this._activity = request;
|
|
}
|
|
}
|
|
/**
|
|
* Removes at mentions for the activity's [recipient](xref:botframework-schema.Activity.recipient)
|
|
* from the text of an activity and returns the updated text.
|
|
* Use with caution; this function alters the activity's [text](xref:botframework-schema.Activity.text) property.
|
|
*
|
|
* @param activity The activity to remove at mentions from.
|
|
* @returns The updated activity's text.
|
|
* @remarks
|
|
* Some channels, for example Microsoft Teams, add at-mention details to the text of a message activity.
|
|
*
|
|
* Use this helper method to modify the activity's [text](xref:botframework-schema.Activity.text) property.
|
|
* It removes all at mentions of the activity's [recipient](xref:botframework-schema.Activity.recipient)
|
|
* and then returns the updated property value.
|
|
*
|
|
* For example:
|
|
* ```JavaScript
|
|
* const updatedText = TurnContext.removeRecipientMention(turnContext.request);
|
|
* ```
|
|
* **See also**
|
|
* - [removeMentionText](xref:botbuilder-core.TurnContext.removeMentionText)
|
|
*/
|
|
static removeRecipientMention(activity) {
|
|
return TurnContext.removeMentionText(activity, activity.recipient.id);
|
|
}
|
|
/**
|
|
* Removes at mentions for a given ID from the text of an activity and returns the updated text.
|
|
* Use with caution; this function alters the activity's [text](xref:botframework-schema.Activity.text) property.
|
|
*
|
|
* @param activity The activity to remove at mentions from.
|
|
* @param id The ID of the user or bot to remove at mentions for.
|
|
* @returns The updated activity's text.
|
|
* @remarks
|
|
* Some channels, for example Microsoft Teams, add at mentions to the text of a message activity.
|
|
*
|
|
* Use this helper method to modify the activity's [text](xref:botframework-schema.Activity.text) property.
|
|
* It removes all at mentions for the given bot or user ID and then returns the updated property value.
|
|
*
|
|
* For example, when you remove mentions of **echoBot** from an activity containing the text "@echoBot Hi Bot",
|
|
* the activity text is updated, and the method returns "Hi Bot".
|
|
*
|
|
* The format of a mention [entity](xref:botframework-schema.Entity) is channel-dependent.
|
|
* However, the mention's [text](xref:botframework-schema.Mention.text) property should contain
|
|
* the exact text for the user as it appears in the activity text.
|
|
*
|
|
* For example, whether the channel uses "<at>username</at>" or "@username", this string is in
|
|
* the activity's text, and this method will remove all occurrences of that string from the text.
|
|
*
|
|
* For example:
|
|
* ```JavaScript
|
|
* const updatedText = TurnContext.removeMentionText(activity, activity.recipient.id);
|
|
* ```
|
|
* **See also**
|
|
* - [removeRecipientMention](xref:botbuilder-core.TurnContext.removeRecipientMention)
|
|
*/
|
|
static removeMentionText(activity, id) {
|
|
const mentions = TurnContext.getMentions(activity);
|
|
const mentionsFiltered = mentions.filter((mention) => mention.mentioned.id === id);
|
|
if (mentionsFiltered.length) {
|
|
activity.text = activity.text.replace(mentionsFiltered[0].text, '').trim();
|
|
}
|
|
return activity.text;
|
|
}
|
|
/**
|
|
* Gets all at-mention entities included in an activity.
|
|
*
|
|
* @param activity The activity.
|
|
* @returns All the at-mention entities included in an activity.
|
|
* @remarks
|
|
* The activity's [entities](xref:botframework-schema.Activity.entities) property contains a flat
|
|
* list of metadata objects pertaining to this activity and can contain
|
|
* [mention](xref:botframework-schema.Mention) entities. This method returns all such entities
|
|
* for a given activity.
|
|
*
|
|
* For example:
|
|
* ```JavaScript
|
|
* const mentions = TurnContext.getMentions(turnContext.request);
|
|
* ```
|
|
*/
|
|
static getMentions(activity) {
|
|
const result = [];
|
|
if (activity.entities !== undefined) {
|
|
for (let i = 0; i < activity.entities.length; i++) {
|
|
if (activity.entities[i].type.toLowerCase() === 'mention') {
|
|
result.push(activity.entities[i]);
|
|
}
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
/**
|
|
* Copies conversation reference information from an activity.
|
|
*
|
|
* @param activity The activity to get the information from.
|
|
* @returns A conversation reference for the conversation that contains this activity.
|
|
* @remarks
|
|
* You can save the conversation reference as a JSON object and use it later to proactively message the user.
|
|
*
|
|
* For example:
|
|
* ```JavaScript
|
|
* const reference = TurnContext.getConversationReference(context.request);
|
|
* ```
|
|
*
|
|
* **See also**
|
|
*
|
|
* - [BotAdapter.continueConversation](xref:botbuilder-core.BotAdapter.continueConversation)
|
|
*/
|
|
static getConversationReference(activity) {
|
|
return {
|
|
activityId: getAppropriateReplyToId(activity),
|
|
user: (0, internal_1.shallowCopy)(activity.from),
|
|
bot: (0, internal_1.shallowCopy)(activity.recipient),
|
|
conversation: (0, internal_1.shallowCopy)(activity.conversation),
|
|
channelId: activity.channelId,
|
|
locale: activity.locale,
|
|
serviceUrl: activity.serviceUrl,
|
|
};
|
|
}
|
|
/**
|
|
* Updates an activity with the delivery information from an existing conversation reference.
|
|
*
|
|
* @param activity The activity to update.
|
|
* @param reference The conversation reference to copy delivery information from.
|
|
* @param isIncoming Optional. `true` to treat the activity as an incoming activity, where the
|
|
* bot is the recipient; otherwise, `false`. Default is `false`, and the activity will show
|
|
* the bot as the sender.
|
|
* @returns This activity, updated with the delivery information.
|
|
* @remarks
|
|
* Call the [getConversationReference](xref:botbuilder-core.TurnContext.getConversationReference)
|
|
* method on an incoming activity to get a conversation reference that you can then use
|
|
* to update an outgoing activity with the correct delivery information.
|
|
*/
|
|
static applyConversationReference(activity, reference, isIncoming = false) {
|
|
var _a;
|
|
activity.channelId = reference.channelId;
|
|
(_a = activity.locale) !== null && _a !== void 0 ? _a : (activity.locale = reference.locale);
|
|
activity.serviceUrl = reference.serviceUrl;
|
|
activity.conversation = reference.conversation;
|
|
if (isIncoming) {
|
|
activity.from = reference.user;
|
|
activity.recipient = reference.bot;
|
|
if (reference.activityId) {
|
|
activity.id = reference.activityId;
|
|
}
|
|
}
|
|
else {
|
|
activity.from = reference.bot;
|
|
activity.recipient = reference.user;
|
|
if (reference.activityId) {
|
|
activity.replyToId = reference.activityId;
|
|
}
|
|
}
|
|
return activity;
|
|
}
|
|
/**
|
|
* Copies conversation reference information from a resource response for a sent activity.
|
|
*
|
|
* @param activity The sent activity.
|
|
* @param reply The resource response for the activity, returned by the
|
|
* [sendActivity](xref:botbuilder-core.TurnContext.sendActivity) or
|
|
* [sendActivities](xref:botbuilder-core.TurnContext.sendActivities) method.
|
|
* @returns A ConversationReference that can be stored and used later to delete or update the activity.
|
|
* @remarks
|
|
* You can save the conversation reference as a JSON object and use it later to update or delete the message.
|
|
*
|
|
* For example:
|
|
* ```javascript
|
|
* var reply = await context.sendActivity('Hi');
|
|
* var reference = TurnContext.getReplyConversationReference(context.activity, reply);
|
|
* ```
|
|
*
|
|
* **See also**
|
|
*
|
|
* - [deleteActivity](xref:botbuilder-core.TurnContext.deleteActivity)
|
|
* - [updateActivity](xref:botbuilder-core.TurnContext.updateActivity)
|
|
*/
|
|
static getReplyConversationReference(activity, reply) {
|
|
const reference = TurnContext.getConversationReference(activity);
|
|
// Update the reference with the new outgoing Activity's id.
|
|
reference.activityId = reply.id;
|
|
return reference;
|
|
}
|
|
/**
|
|
* Asynchronously sends an activity to the sender of the incoming activity.
|
|
*
|
|
* @param name The activity or text to send.
|
|
* @param value Optional. The text to be spoken by your bot on a speech-enabled channel.
|
|
* @param valueType Optional. Indicates whether your bot is accepting, expecting, or ignoring user
|
|
* @param label Optional. Indicates whether your bot is accepting, expecting, or ignoring user
|
|
* @returns A promise with a ResourceResponse.
|
|
* @remarks
|
|
* Creates and sends a Trace activity. Trace activities are only sent when the channel is the emulator.
|
|
*
|
|
* For example:
|
|
* ```JavaScript
|
|
* await context.sendTraceActivity(`The following exception was thrown ${msg}`);
|
|
* ```
|
|
*
|
|
* **See also**
|
|
*
|
|
* - [sendActivities](xref:botbuilder-core.TurnContext.sendActivities)
|
|
*/
|
|
sendTraceActivity(name, value, valueType, label) {
|
|
const traceActivity = {
|
|
type: botframework_schema_1.ActivityTypes.Trace,
|
|
timestamp: new Date(),
|
|
name: name,
|
|
value: value,
|
|
valueType: valueType,
|
|
label: label,
|
|
};
|
|
return this.sendActivity(traceActivity);
|
|
}
|
|
/**
|
|
* Asynchronously sends an activity to the sender of the incoming activity.
|
|
*
|
|
* @param activityOrText The activity or text to send.
|
|
* @param speak Optional. The text to be spoken by your bot on a speech-enabled channel.
|
|
* @param inputHint Optional. Indicates whether your bot is accepting, expecting, or ignoring user
|
|
* input after the message is delivered to the client. One of: 'acceptingInput', 'ignoringInput',
|
|
* or 'expectingInput'. Default is 'acceptingInput'.
|
|
* @returns A promise with a ResourceResponse.
|
|
* @remarks
|
|
* If the activity is successfully sent, results in a
|
|
* [ResourceResponse](xref:botframework-schema.ResourceResponse) object containing the ID that the
|
|
* receiving channel assigned to the activity.
|
|
*
|
|
* See the channel's documentation for limits imposed upon the contents of the **activityOrText** parameter.
|
|
*
|
|
* To control various characteristics of your bot's speech such as voice, rate, volume, pronunciation,
|
|
* and pitch, specify **speak** in Speech Synthesis Markup Language (SSML) format.
|
|
*
|
|
* For example:
|
|
* ```JavaScript
|
|
* await context.sendActivity(`Hello World`);
|
|
* ```
|
|
*
|
|
* **See also**
|
|
*
|
|
* - [sendActivities](xref:botbuilder-core.TurnContext.sendActivities)
|
|
* - [updateActivity](xref:botbuilder-core.TurnContext.updateActivity)
|
|
* - [deleteActivity](xref:botbuilder-core.TurnContext.deleteActivity)
|
|
*/
|
|
sendActivity(activityOrText, speak, inputHint) {
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
let a;
|
|
if (typeof activityOrText === 'string') {
|
|
a = { text: activityOrText, inputHint: inputHint || botframework_schema_1.InputHints.AcceptingInput };
|
|
if (speak) {
|
|
a.speak = speak;
|
|
}
|
|
}
|
|
else {
|
|
a = activityOrText;
|
|
}
|
|
const responses = (yield this.sendActivities([a])) || [];
|
|
return responses[0];
|
|
});
|
|
}
|
|
/**
|
|
* Asynchronously sends a set of activities to the sender of the incoming activity.
|
|
*
|
|
* @param activities The activities to send.
|
|
* @returns A promise with a ResourceResponse.
|
|
* @remarks
|
|
* If the activities are successfully sent, results in an array of
|
|
* [ResourceResponse](xref:botframework-schema.ResourceResponse) objects containing the IDs that
|
|
* the receiving channel assigned to the activities.
|
|
*
|
|
* Before they are sent, the delivery information of each outbound activity is updated based on the
|
|
* delivery information of the inbound inbound activity.
|
|
*
|
|
* For example:
|
|
* ```JavaScript
|
|
* await context.sendActivities([
|
|
* { type: 'typing' },
|
|
* { type: 'delay', value: 2000 },
|
|
* { type: 'message', text: 'Hello... How are you?' }
|
|
* ]);
|
|
* ```
|
|
*
|
|
* **See also**
|
|
*
|
|
* - [sendActivity](xref:botbuilder-core.TurnContext.sendActivity)
|
|
* - [updateActivity](xref:botbuilder-core.TurnContext.updateActivity)
|
|
* - [deleteActivity](xref:botbuilder-core.TurnContext.deleteActivity)
|
|
*/
|
|
sendActivities(activities) {
|
|
let sentNonTraceActivity = false;
|
|
const ref = TurnContext.getConversationReference(this.activity);
|
|
const output = activities.map((activity) => {
|
|
const result = TurnContext.applyConversationReference(Object.assign({}, activity), ref);
|
|
if (!result.type) {
|
|
result.type = botframework_schema_1.ActivityTypes.Message;
|
|
}
|
|
if (result.type !== botframework_schema_1.ActivityTypes.Trace) {
|
|
sentNonTraceActivity = true;
|
|
}
|
|
if (result.id) {
|
|
delete result.id;
|
|
}
|
|
return result;
|
|
});
|
|
return this.emit(this._onSendActivities, output, () => __awaiter(this, void 0, void 0, function* () {
|
|
if (this.activity.deliveryMode === botframework_schema_1.DeliveryModes.ExpectReplies) {
|
|
// Append activities to buffer
|
|
const responses = [];
|
|
output.forEach((a) => {
|
|
this.bufferedReplyActivities.push(a);
|
|
// Ensure the TurnState has the InvokeResponseKey, since this activity
|
|
// is not being sent through the adapter, where it would be added to TurnState.
|
|
if (a.type === botframework_schema_1.ActivityTypes.InvokeResponse) {
|
|
this.turnState.set(_1.INVOKE_RESPONSE_KEY, a);
|
|
}
|
|
responses.push({ id: undefined });
|
|
});
|
|
// Set responded flag
|
|
if (sentNonTraceActivity) {
|
|
this.responded = true;
|
|
}
|
|
return responses;
|
|
}
|
|
else {
|
|
const responses = yield this.adapter.sendActivities(this, output);
|
|
for (let index = 0; index < (responses === null || responses === void 0 ? void 0 : responses.length); index++) {
|
|
const activity = output[index];
|
|
activity.id = responses[index].id;
|
|
}
|
|
// Set responded flag
|
|
if (sentNonTraceActivity) {
|
|
this.responded = true;
|
|
}
|
|
return responses;
|
|
}
|
|
}));
|
|
}
|
|
/**
|
|
* Asynchronously updates a previously sent activity.
|
|
*
|
|
* @param activity The replacement for the original activity.
|
|
* @returns A promise with a ResourceResponse.
|
|
* @remarks
|
|
* The [id](xref:botframework-schema.Activity.id) of the replacement activity indicates the activity
|
|
* in the conversation to replace.
|
|
*
|
|
* For example:
|
|
* ```JavaScript
|
|
* const matched = /approve (.*)/i.exec(context.activity.text);
|
|
* if (matched) {
|
|
* const update = await approveExpenseReport(matched[1]);
|
|
* await context.updateActivity(update);
|
|
* }
|
|
* ```
|
|
*
|
|
* **See also**
|
|
*
|
|
* - [sendActivity](xref:botbuilder-core.TurnContext.sendActivity)
|
|
* - [deleteActivity](xref:botbuilder-core.TurnContext.deleteActivity)
|
|
* - [getReplyConversationReference](xref:botbuilder-core.TurnContext.getReplyConversationReference)
|
|
*/
|
|
updateActivity(activity) {
|
|
const ref = TurnContext.getConversationReference(this.activity);
|
|
const a = TurnContext.applyConversationReference(activity, ref);
|
|
return this.emit(this._onUpdateActivity, a, () => this.adapter.updateActivity(this, a));
|
|
}
|
|
/**
|
|
* Asynchronously deletes a previously sent activity.
|
|
*
|
|
* @param idOrReference ID or conversation reference for the activity to delete.
|
|
* @returns A promise representing the async operation.
|
|
* @remarks
|
|
* If an ID is specified, the conversation reference for the current request is used
|
|
* to get the rest of the information needed.
|
|
*
|
|
* For example:
|
|
* ```JavaScript
|
|
* const matched = /approve (.*)/i.exec(context.activity.text);
|
|
* if (matched) {
|
|
* const savedId = await approveExpenseReport(matched[1]);
|
|
* await context.deleteActivity(savedId);
|
|
* }
|
|
* ```
|
|
*
|
|
* **See also**
|
|
*
|
|
* - [sendActivity](xref:botbuilder-core.TurnContext.sendActivity)
|
|
* - [updateActivity](xref:botbuilder-core.TurnContext.updateActivity)
|
|
* - [getReplyConversationReference](xref:botbuilder-core.TurnContext.getReplyConversationReference)
|
|
*/
|
|
deleteActivity(idOrReference) {
|
|
let reference;
|
|
if (typeof idOrReference === 'string') {
|
|
reference = TurnContext.getConversationReference(this.activity);
|
|
reference.activityId = idOrReference;
|
|
}
|
|
else {
|
|
reference = idOrReference;
|
|
}
|
|
return this.emit(this._onDeleteActivity, reference, () => this.adapter.deleteActivity(this, reference));
|
|
}
|
|
/**
|
|
* Adds a response handler for send activity operations.
|
|
*
|
|
* @param handler The handler to add to the context object.
|
|
* @returns The updated context object.
|
|
* @remarks
|
|
* This method returns a reference to the turn context object.
|
|
*
|
|
* When the [sendActivity](xref:botbuilder-core.TurnContext.sendActivity) or
|
|
* [sendActivities](xref:botbuilder-core.TurnContext.sendActivities) method is called,
|
|
* the registered handlers are called in the order in which they were added to the context object
|
|
* before the activities are sent.
|
|
*
|
|
* This example shows how to listen for and log outgoing `message` activities.
|
|
*
|
|
* ```JavaScript
|
|
* context.onSendActivities(async (ctx, activities, next) => {
|
|
* // Log activities before sending them.
|
|
* activities.filter(a => a.type === 'message').forEach(a => logSend(a));
|
|
*
|
|
* // Allow the send process to continue.
|
|
* next();
|
|
* });
|
|
* ```
|
|
*/
|
|
onSendActivities(handler) {
|
|
this._onSendActivities.push(handler);
|
|
return this;
|
|
}
|
|
/**
|
|
* Adds a response handler for update activity operations.
|
|
*
|
|
* @param handler The handler to add to the context object.
|
|
* @returns The updated context object.
|
|
* @remarks
|
|
* This method returns a reference to the turn context object.
|
|
*
|
|
* When the [updateActivity](xref:botbuilder-core.TurnContext.updateActivity) method is called,
|
|
* the registered handlers are called in the order in which they were added to the context object
|
|
* before the activity is updated.
|
|
*
|
|
* This example shows how to listen for and log activity updates.
|
|
*
|
|
* ```JavaScript
|
|
* context.onUpdateActivity(async (ctx, activity, next) => {
|
|
* // Replace activity
|
|
* await next();
|
|
*
|
|
* // Log update
|
|
* logUpdate(activity);
|
|
* });
|
|
* ```
|
|
*/
|
|
onUpdateActivity(handler) {
|
|
this._onUpdateActivity.push(handler);
|
|
return this;
|
|
}
|
|
/**
|
|
* Adds a response handler for delete activity operations.
|
|
*
|
|
* @param handler The handler to add to the context object.
|
|
* @returns The updated context object.
|
|
* @remarks
|
|
* This method returns a reference to the turn context object.
|
|
*
|
|
* When the [deleteActivity](xref:botbuilder-core.TurnContext.deleteActivity) method is called,
|
|
* the registered handlers are called in the order in which they were added to the context object
|
|
* before the activity is deleted.
|
|
*
|
|
* This example shows how to listen for and log activity deletions.
|
|
*
|
|
* ```JavaScript
|
|
* context.onDeleteActivity(async (ctx, reference, next) => {
|
|
* // Delete activity
|
|
* await next();
|
|
*
|
|
* // Log delete
|
|
* logDelete(activity);
|
|
* });
|
|
* ```
|
|
*/
|
|
onDeleteActivity(handler) {
|
|
this._onDeleteActivity.push(handler);
|
|
return this;
|
|
}
|
|
/**
|
|
* Called when this turn context object is passed into the constructor for a new turn context.
|
|
*
|
|
* @param context The new turn context object.
|
|
* @remarks
|
|
* This copies private members from this object to the new object.
|
|
* All property values are copied by reference.
|
|
*
|
|
* Override this in a derived class to copy any additional members, as necessary.
|
|
*/
|
|
copyTo(context) {
|
|
// Copy private members to other instance.
|
|
[
|
|
'_adapter',
|
|
'_activity',
|
|
'_respondedRef',
|
|
'_services',
|
|
'_onSendActivities',
|
|
'_onUpdateActivity',
|
|
'_onDeleteActivity',
|
|
].forEach((prop) => (context[prop] = this[prop]));
|
|
}
|
|
/**
|
|
* Gets the bot adapter that created this context object.
|
|
*
|
|
* @returns The bot adapter that created this context object.
|
|
*/
|
|
get adapter() {
|
|
return this._adapter;
|
|
}
|
|
/**
|
|
* Gets the activity associated with this turn.
|
|
*
|
|
* @returns The activity associated with this turn.
|
|
* @remarks
|
|
* This example shows how to get the users trimmed utterance from the activity:
|
|
*
|
|
* ```JavaScript
|
|
* const utterance = (context.activity.text || '').trim();
|
|
* ```
|
|
*/
|
|
get activity() {
|
|
return this._activity;
|
|
}
|
|
/**
|
|
* Indicates whether the bot has replied to the user this turn.
|
|
*
|
|
* @returns True if at least one response was sent for the current turn; otherwise, false.
|
|
* @remarks
|
|
* **true** if at least one response was sent for the current turn; otherwise, **false**.
|
|
* Use this to determine if your bot needs to run fallback logic after other normal processing.
|
|
*
|
|
* Trace activities do not set this flag.
|
|
*
|
|
* for example:
|
|
* ```JavaScript
|
|
* await routeActivity(context);
|
|
* if (!context.responded) {
|
|
* await context.sendActivity(`I'm sorry. I didn't understand.`);
|
|
* }
|
|
* ```
|
|
*/
|
|
get responded() {
|
|
return this._respondedRef.responded;
|
|
}
|
|
/**
|
|
* Sets the response flag on the current turn context.
|
|
*
|
|
* @remarks
|
|
* The [sendActivity](xref:botbuilder-core.TurnContext.sendActivity) and
|
|
* [sendActivities](xref:botbuilder-core.TurnContext.sendActivities) methods call this method to
|
|
* update the responded flag. You can call this method directly to indicate that your bot has
|
|
* responded appropriately to the incoming activity.
|
|
*/
|
|
set responded(value) {
|
|
if (!value) {
|
|
throw new Error("TurnContext: cannot set 'responded' to a value of 'false'.");
|
|
}
|
|
this._respondedRef.responded = true;
|
|
}
|
|
/**
|
|
* Gets the locale stored in the turnState.
|
|
*
|
|
* @returns The locale stored in the turnState.
|
|
*/
|
|
get locale() {
|
|
const turnObj = this._turnState[this._turn];
|
|
const locale = turnObj[this._locale];
|
|
if (typeof locale === 'string') {
|
|
return locale;
|
|
}
|
|
return undefined;
|
|
}
|
|
/**
|
|
* Sets the locale stored in the turnState.
|
|
*/
|
|
set locale(value) {
|
|
const turnObj = this._turnState[this._turn];
|
|
if (turnObj) {
|
|
turnObj[this._locale] = value;
|
|
}
|
|
else {
|
|
this._turnState[this._turn] = { locale: value };
|
|
}
|
|
}
|
|
/**
|
|
* Gets the services registered on this context object.
|
|
*
|
|
* @returns The services registered on this context object.
|
|
* @remarks
|
|
* Middleware, other components, and services will typically use this to cache information
|
|
* that could be asked for by a bot multiple times during a turn. You can use this cache to
|
|
* pass information between components of your bot.
|
|
*
|
|
* For example:
|
|
* ```JavaScript
|
|
* const cartKey = Symbol();
|
|
* const cart = await loadUsersShoppingCart(context);
|
|
* context.turnState.set(cartKey, cart);
|
|
* ```
|
|
*
|
|
* > [!TIP]
|
|
* > When creating middleware or a third-party component, use a unique symbol for your cache key
|
|
* > to avoid state naming collisions with the bot or other middleware or components.
|
|
*/
|
|
get turnState() {
|
|
return this._turnState;
|
|
}
|
|
/**
|
|
* @private
|
|
* Executes `handlers` as a chain, returning a promise that resolves to the final result.
|
|
*/
|
|
emit(handlers, arg, next) {
|
|
const runHandlers = ([handler, ...remaining]) => {
|
|
try {
|
|
return handler ? handler(this, arg, () => runHandlers(remaining)) : Promise.resolve(next());
|
|
}
|
|
catch (err) {
|
|
return Promise.reject(err);
|
|
}
|
|
};
|
|
return runHandlers(handlers);
|
|
}
|
|
}
|
|
exports.TurnContext = TurnContext;
|
|
//# sourceMappingURL=turnContext.js.map
|