botbuilder-core
Advanced tools
Comparing version 4.9.3 to 4.10.0-dev.20200805.aa06ea2
@@ -12,4 +12,2 @@ /** | ||
private static readonly lgType; | ||
private static readonly errorPrefix; | ||
private static readonly warningPrefix; | ||
private static adaptiveCardType; | ||
@@ -19,2 +17,4 @@ private static readonly genericCardTypeMapping; | ||
private static readonly cardActionProperties; | ||
private static readonly attachmentProperties; | ||
private static readonly cardProperties; | ||
/** | ||
@@ -26,8 +26,2 @@ * Generate the activity. | ||
/** | ||
* check the LG result before generate an Activity. | ||
* @param lgResult lg output. | ||
* @returns Diagnostic list. | ||
*/ | ||
static checkLGResult(lgResult: any): string[]; | ||
/** | ||
* Given a lg result, create a text activity. This method will create a MessageActivity from text. | ||
@@ -51,22 +45,8 @@ * @param text lg text output. | ||
private static getCardAttachment; | ||
private static realProperty; | ||
private static normalizedToList; | ||
private static parseStructuredLGResult; | ||
private static checkStructuredResult; | ||
private static checkActivity; | ||
private static checkActivityType; | ||
private static checkActivityPropertyName; | ||
private static checkActivityProperties; | ||
private static checkSuggestions; | ||
private static checkButtons; | ||
private static checkCardActions; | ||
private static checkCardAction; | ||
private static checkCardActionPropertyName; | ||
private static checkCardActionType; | ||
private static checkAttachments; | ||
private static checkAttachment; | ||
private static checkCardAttachment; | ||
private static getStructureType; | ||
private static normalizedToMediaOrImage; | ||
private static getValidBooleanValue; | ||
private static buildDiagnostic; | ||
} | ||
//# sourceMappingURL=activityFactory.d.ts.map |
@@ -20,39 +20,10 @@ "use strict"; | ||
static fromObject(lgResult) { | ||
const diagnostics = this.checkLGResult(lgResult); | ||
const errors = diagnostics.filter((u) => u.startsWith(this.errorPrefix)); | ||
if (errors !== undefined && errors.length > 0) { | ||
throw new Error(`${errors.join('\n')}`); | ||
} | ||
if (typeof lgResult === 'string') { | ||
const structuredLGResult = this.parseStructuredLGResult(lgResult.trim()); | ||
return structuredLGResult === undefined ? | ||
this.buildActivityFromText(lgResult.trim()) | ||
: this.buildActivityFromLGStructuredResult(lgResult); | ||
return this.buildActivityFromText(lgResult.trim()); | ||
} | ||
return this.buildActivityFromLGStructuredResult(lgResult); | ||
} | ||
/** | ||
* check the LG result before generate an Activity. | ||
* @param lgResult lg output. | ||
* @returns Diagnostic list. | ||
*/ | ||
static checkLGResult(lgResult) { | ||
if (lgResult === undefined) { | ||
return [this.buildDiagnostic('LG output is empty', false)]; | ||
if (typeof lgResult === 'object') { | ||
return this.buildActivityFromLGStructuredResult(lgResult); | ||
} | ||
if (typeof lgResult === 'string') { | ||
if (!lgResult.startsWith('{') || !lgResult.endsWith('}')) { | ||
return [this.buildDiagnostic('LG output is not a json object, and will fallback to string format.', false)]; | ||
} | ||
let lgStructuredResult = undefined; | ||
try { | ||
lgStructuredResult = JSON.parse(lgResult); | ||
} | ||
catch (error) { | ||
return [this.buildDiagnostic('LG output is not a json object, and will fallback to string format.', false)]; | ||
} | ||
return this.checkStructuredResult(lgStructuredResult); | ||
} | ||
else { | ||
return this.checkStructuredResult(lgResult); | ||
return this.buildActivityFromText(JSON.stringify(lgResult).trim()); | ||
} | ||
@@ -66,6 +37,8 @@ } | ||
const msg = { | ||
type: botframework_schema_1.ActivityTypes.Message, | ||
text: text, | ||
speak: text | ||
type: botframework_schema_1.ActivityTypes.Message | ||
}; | ||
if (text) { | ||
msg.text = text; | ||
msg.speak = text; | ||
} | ||
return msg; | ||
@@ -107,10 +80,3 @@ } | ||
default: | ||
var properties = this.activityProperties.map((u) => u.toLowerCase()); | ||
if (properties.includes(property.toLowerCase())) { | ||
var realPropertyName = this.activityProperties[properties.indexOf(property.toLowerCase())]; | ||
activity[realPropertyName] = value; | ||
} | ||
else { | ||
activity[property.toLowerCase()] = value; | ||
} | ||
activity[this.realProperty(property, this.activityProperties)] = value; | ||
break; | ||
@@ -154,14 +120,3 @@ } | ||
} | ||
const value = action[key]; | ||
switch (property.toLowerCase()) { | ||
case 'displaytext': | ||
cardAction.displayText = value; | ||
break; | ||
case 'channeldata': | ||
cardAction.channelData = value; | ||
break; | ||
default: | ||
cardAction[property.toLowerCase()] = value; | ||
break; | ||
} | ||
cardAction[this.realProperty(property, this.cardActionProperties)] = action[key]; | ||
} | ||
@@ -219,10 +174,4 @@ } | ||
break; | ||
case 'contenturl': | ||
attachment.contentUrl = value; | ||
break; | ||
case 'thumbnailurl': | ||
attachment.thumbnailUrl = value; | ||
break; | ||
default: | ||
attachment[property.toLowerCase()] = value; | ||
attachment[this.realProperty(property, this.attachmentProperties)] = value; | ||
break; | ||
@@ -248,7 +197,7 @@ } | ||
} | ||
const imageList = this.normalizedToList(value).map((u) => u.toString()); | ||
imageList.forEach((u) => card['images'].push({ url: u })); | ||
const imageList = this.normalizedToList(value); | ||
imageList.forEach((u) => card['images'].push(this.normalizedToMediaOrImage(u))); | ||
} | ||
else { | ||
card['image'] = { url: value.toString() }; | ||
card['image'] = this.normalizedToMediaOrImage(value); | ||
} | ||
@@ -260,4 +209,4 @@ break; | ||
} | ||
const mediaList = this.normalizedToList(value).map((u) => u.toString()); | ||
mediaList.forEach((u) => card['media'].push({ url: u })); | ||
const mediaList = this.normalizedToList(value); | ||
mediaList.forEach((u) => card['media'].push(this.normalizedToMediaOrImage(u))); | ||
break; | ||
@@ -278,8 +227,8 @@ case 'buttons': | ||
} | ||
else { | ||
card[property] = value; | ||
} | ||
break; | ||
case 'connectionname': | ||
card['connectionName'] = value; | ||
break; | ||
default: | ||
card[property.toLowerCase()] = value; | ||
card[this.realProperty(key.trim(), this.cardProperties)] = value; | ||
break; | ||
@@ -294,2 +243,11 @@ } | ||
} | ||
static realProperty(property, builtinProperties) { | ||
const properties = builtinProperties.map((u) => u.toLowerCase()); | ||
if (properties.includes(property.toLowerCase())) { | ||
return builtinProperties[properties.indexOf(property.toLowerCase())]; | ||
} | ||
else { | ||
return property; | ||
} | ||
} | ||
static normalizedToList(item) { | ||
@@ -306,205 +264,2 @@ if (item === undefined) { | ||
} | ||
static parseStructuredLGResult(lgStringResult) { | ||
let lgStructuredResult = undefined; | ||
if (lgStringResult === undefined || lgStringResult === '') { | ||
return undefined; | ||
} | ||
lgStringResult = lgStringResult.trim(); | ||
if (lgStringResult === '' || !lgStringResult.startsWith('{') || !lgStringResult.endsWith('}')) { | ||
return undefined; | ||
} | ||
try { | ||
lgStructuredResult = JSON.parse(lgStringResult); | ||
const type = this.getStructureType(lgStringResult); | ||
if (!type || type.trim() === '') { | ||
return undefined; | ||
} | ||
} | ||
catch (error) { | ||
return undefined; | ||
} | ||
return lgStructuredResult; | ||
} | ||
static checkStructuredResult(input) { | ||
const result = []; | ||
const type = this.getStructureType(input); | ||
if (!type || type.trim() === '') { | ||
return result; | ||
} | ||
if (this.genericCardTypeMapping.has(type) || type === 'attachment') { | ||
result.push(...this.checkAttachment(input)); | ||
} | ||
else if (type === 'activity') { | ||
result.push(...this.checkActivity(input)); | ||
} | ||
else { | ||
const diagnosticMessage = `Type '${type}' is not supported currently.`; | ||
result.push(this.buildDiagnostic(diagnosticMessage, false)); | ||
} | ||
return result; | ||
} | ||
static checkActivity(input) { | ||
const result = []; | ||
let activityType = undefined; | ||
if ('type' in input) { | ||
activityType = input['type'].toString().trim(); | ||
} | ||
result.push(...this.checkActivityType(activityType)); | ||
result.push(...this.checkActivityPropertyName(input)); | ||
result.push(...this.checkActivityProperties(input)); | ||
return result; | ||
} | ||
static checkActivityType(activityType) { | ||
if (activityType !== undefined) { | ||
if (!Object.values(botframework_schema_1.ActivityTypes).map((u) => u.toLowerCase()).includes(activityType.toLowerCase())) { | ||
return [this.buildDiagnostic(`'${activityType}' is not a valid activity type.`)]; | ||
} | ||
} | ||
return []; | ||
} | ||
static checkActivityPropertyName(input) { | ||
const invalidProperties = []; | ||
for (const property of Object.keys(input)) { | ||
if (property === this.lgType) { | ||
continue; | ||
} | ||
if (!this.activityProperties.map((u) => u.toLowerCase()).includes(property.toLowerCase())) { | ||
invalidProperties.push(property); | ||
} | ||
} | ||
if (invalidProperties.length > 0) { | ||
return [this.buildDiagnostic(`'${invalidProperties.join(',')}' not support in Activity.`, false)]; | ||
} | ||
return []; | ||
} | ||
static checkActivityProperties(input) { | ||
const result = []; | ||
for (const key of Object.keys(input)) { | ||
const property = key.trim(); | ||
const value = input[key]; | ||
switch (property.toLowerCase()) { | ||
case 'attachments': | ||
result.push(...this.checkAttachments(value)); | ||
break; | ||
case 'suggestedactions': | ||
result.push(...this.checkSuggestions(value)); | ||
break; | ||
default: | ||
break; | ||
} | ||
} | ||
return result; | ||
} | ||
static checkSuggestions(value) { | ||
const actions = this.normalizedToList(value); | ||
return this.checkCardActions(actions); | ||
} | ||
static checkButtons(value) { | ||
const actions = this.normalizedToList(value); | ||
return this.checkCardActions(actions); | ||
} | ||
static checkCardActions(actions) { | ||
const result = []; | ||
actions.forEach((u) => { result.push(...this.checkCardAction(u)); }); | ||
return result; | ||
} | ||
static checkCardAction(value) { | ||
const result = []; | ||
if (typeof value === 'string') { | ||
return result; | ||
} | ||
if (typeof value === 'object') { | ||
const type = this.getStructureType(value); | ||
if (type !== 'cardaction') { | ||
result.push(this.buildDiagnostic(`'${type}' is not card action type.`, false)); | ||
} | ||
else { | ||
result.push(...this.checkCardActionPropertyName(value)); | ||
if ('type' in value) { | ||
result.push(...this.checkCardActionType(value['type'])); | ||
} | ||
} | ||
} | ||
else { | ||
result.push(this.buildDiagnostic(`'${value}' is not a valid card action format.`, false)); | ||
} | ||
return result; | ||
} | ||
static checkCardActionPropertyName(input) { | ||
const invalidProperties = []; | ||
for (const property of Object.keys(input)) { | ||
if (property === this.lgType) { | ||
continue; | ||
} | ||
if (!this.cardActionProperties.map((u) => u.toLowerCase()).includes(property.toLowerCase())) { | ||
invalidProperties.push(property); | ||
} | ||
} | ||
if (invalidProperties.length > 0) { | ||
return [this.buildDiagnostic(`'${invalidProperties.join(',')}' not support in card action.`, false)]; | ||
} | ||
return []; | ||
} | ||
static checkCardActionType(cardActionType) { | ||
const result = []; | ||
if (!cardActionType) { | ||
return result; | ||
} | ||
if (!Object.values(botframework_schema_1.ActionTypes).map((u) => u.toLowerCase()).includes(cardActionType.toLowerCase())) { | ||
return [this.buildDiagnostic(`'${cardActionType}' is not a valid card action type.`)]; | ||
} | ||
return result; | ||
} | ||
static checkAttachments(value) { | ||
const result = []; | ||
const attachmentsJsonList = this.normalizedToList(value); | ||
for (const attachmentsJson of attachmentsJsonList) { | ||
if (typeof attachmentsJson === 'object') { | ||
result.push(...this.checkAttachment(attachmentsJson)); | ||
} | ||
} | ||
return result; | ||
} | ||
static checkAttachment(value) { | ||
const result = []; | ||
const type = this.getStructureType(value); | ||
if (this.genericCardTypeMapping.has(type)) { | ||
result.push(...this.checkCardAttachment(value)); | ||
} | ||
else if (type === 'adaptivecard') { | ||
// TODO | ||
// check adaptivecard format | ||
} | ||
else if (type === 'attachment') { | ||
// TODO | ||
// Check attachment format | ||
} | ||
else { | ||
result.push(this.buildDiagnostic(`'${type}' is not an attachment type.`, false)); | ||
} | ||
return result; | ||
} | ||
static checkCardAttachment(input) { | ||
const result = []; | ||
for (const key of Object.keys(input)) { | ||
const property = key.trim().toLowerCase(); | ||
const value = input[key]; | ||
switch (property) { | ||
case 'buttons': | ||
result.push(...this.checkButtons(value)); | ||
break; | ||
case 'autostart': | ||
case 'shareable': | ||
case 'autoloop': | ||
const boolValue = this.getValidBooleanValue(value.toString()); | ||
if (boolValue === undefined) { | ||
result.push(this.buildDiagnostic(`'${value.toString()}' is not a boolean value.`)); | ||
} | ||
break; | ||
default: | ||
break; | ||
} | ||
} | ||
return result; | ||
} | ||
static getStructureType(input) { | ||
@@ -523,3 +278,16 @@ let result = ''; | ||
} | ||
static normalizedToMediaOrImage(item) { | ||
if (!item) { | ||
return {}; | ||
} | ||
else if (typeof item === 'string') { | ||
return { url: item }; | ||
} | ||
else | ||
return item; | ||
} | ||
static getValidBooleanValue(boolValue) { | ||
if (typeof boolValue === 'boolean') { | ||
return boolValue; | ||
} | ||
if (boolValue.toLowerCase() === 'true') { | ||
@@ -533,10 +301,4 @@ return true; | ||
} | ||
static buildDiagnostic(message, isError = true) { | ||
message = message === undefined ? '' : message; | ||
return isError ? this.errorPrefix + message : this.warningPrefix + message; | ||
} | ||
} | ||
ActivityFactory.lgType = 'lgType'; | ||
ActivityFactory.errorPrefix = '[ERROR]'; | ||
ActivityFactory.warningPrefix = '[WARNING]'; | ||
ActivityFactory.adaptiveCardType = cardFactory_1.CardFactory.contentTypes.adaptiveCard; | ||
@@ -560,3 +322,7 @@ ActivityFactory.genericCardTypeMapping = new Map([ | ||
ActivityFactory.cardActionProperties = ['type', 'title', 'image', 'text', 'displayText', 'value', 'channelData']; | ||
ActivityFactory.attachmentProperties = ['contentType', 'contentUrl', 'content', 'name', 'thumbnailUrl']; | ||
ActivityFactory.cardProperties = ['title', 'subtitle', 'text', 'images', 'image', 'buttons', 'tap', 'media', | ||
'shareable', 'autoloop', 'autostart', 'aspect', 'duration', 'value', 'connectionName', 'tokenExchangeResource', | ||
'facts', 'items', 'total', 'tax', 'vat']; | ||
exports.ActivityFactory = ActivityFactory; | ||
//# sourceMappingURL=activityFactory.js.map |
@@ -254,2 +254,14 @@ /** | ||
/** | ||
* Registers an activity event handler for the _installationupdate_ activity. | ||
* | ||
* @param handler The event handler. | ||
* | ||
* @remarks | ||
* Returns a reference to the [ActivityHandler](xref:botbuilder-core.ActivityHandler) object. | ||
* | ||
* To handle a InstallationUpdate event, use the | ||
* [onInstallationUpdate](xref:botbuilder-core.ActivityHandler.onInstallationUpdate) type-specific event handler. | ||
*/ | ||
onInstallationUpdate(handler: BotHandler): this; | ||
/** | ||
* Registers an activity event handler for the _tokens-response_ event, emitted for any incoming | ||
@@ -379,2 +391,15 @@ * `tokens/response` event activity. These are generated as part of the OAuth authentication flow. | ||
/** | ||
* Runs all registered _instllationupdate_ handlers and then continues the event emission process. | ||
* | ||
* @param context The context object for the current turn. | ||
* | ||
* @remarks | ||
* Overwrite this method to support channel-specific behavior across multiple channels. | ||
* | ||
* The default logic is to call any handlers registered via | ||
* [onInstallationUpdateActivity](xref:botbuilder-core.ActivityHandler.onInstallationUpdateActivity), | ||
* and then continue by calling [defaultNextEvent](xref:botbuilder-core.ActivityHandler.defaultNextEvent). | ||
*/ | ||
protected onInstallationUpdateActivity(context: TurnContext): Promise<void>; | ||
/** | ||
* Runs all registered _unrecognized activity type_ handlers and then continues the event emission process. | ||
@@ -381,0 +406,0 @@ * |
@@ -265,2 +265,16 @@ "use strict"; | ||
/** | ||
* Registers an activity event handler for the _installationupdate_ activity. | ||
* | ||
* @param handler The event handler. | ||
* | ||
* @remarks | ||
* Returns a reference to the [ActivityHandler](xref:botbuilder-core.ActivityHandler) object. | ||
* | ||
* To handle a InstallationUpdate event, use the | ||
* [onInstallationUpdate](xref:botbuilder-core.ActivityHandler.onInstallationUpdate) type-specific event handler. | ||
*/ | ||
onInstallationUpdate(handler) { | ||
return this.on('InstallationUpdate', handler); | ||
} | ||
/** | ||
* Registers an activity event handler for the _tokens-response_ event, emitted for any incoming | ||
@@ -489,2 +503,19 @@ * `tokens/response` event activity. These are generated as part of the OAuth authentication flow. | ||
/** | ||
* Runs all registered _instllationupdate_ handlers and then continues the event emission process. | ||
* | ||
* @param context The context object for the current turn. | ||
* | ||
* @remarks | ||
* Overwrite this method to support channel-specific behavior across multiple channels. | ||
* | ||
* The default logic is to call any handlers registered via | ||
* [onInstallationUpdateActivity](xref:botbuilder-core.ActivityHandler.onInstallationUpdateActivity), | ||
* and then continue by calling [defaultNextEvent](xref:botbuilder-core.ActivityHandler.defaultNextEvent). | ||
*/ | ||
onInstallationUpdateActivity(context) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
yield this.handle(context, 'InstallationUpdate', this.defaultNextEvent(context)); | ||
}); | ||
} | ||
/** | ||
* Runs all registered _unrecognized activity type_ handlers and then continues the event emission process. | ||
@@ -491,0 +522,0 @@ * |
@@ -130,2 +130,12 @@ /** | ||
/** | ||
* Provides a hook for emitting the _installationupdate_ event. | ||
* | ||
* @param context The context object for the current turn. | ||
* | ||
* @remarks | ||
* Overwrite this method to run registered _installationupdate_ handlers and then continue the event | ||
* emission process. | ||
*/ | ||
protected onInstallationUpdateActivity(context: TurnContext): Promise<void>; | ||
/** | ||
* Provides a hook for emitting the _unrecognized_ event. | ||
@@ -132,0 +142,0 @@ * |
@@ -86,2 +86,5 @@ "use strict"; | ||
break; | ||
case _1.ActivityTypes.InstallationUpdate: | ||
yield this.onInstallationUpdateActivity(context); | ||
break; | ||
default: | ||
@@ -218,2 +221,16 @@ // handler for unknown or unhandled types | ||
/** | ||
* Provides a hook for emitting the _installationupdate_ event. | ||
* | ||
* @param context The context object for the current turn. | ||
* | ||
* @remarks | ||
* Overwrite this method to run registered _installationupdate_ handlers and then continue the event | ||
* emission process. | ||
*/ | ||
onInstallationUpdateActivity(context) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
return; | ||
}); | ||
} | ||
/** | ||
* Provides a hook for emitting the _unrecognized_ event. | ||
@@ -220,0 +237,0 @@ * |
@@ -9,3 +9,3 @@ /** | ||
/** | ||
* Internal interface representing the "WebResource" from @azure/ms-rest-js@1.2.6 | ||
* Internal interface representing the "WebResource" from @azure/ms-rest-js | ||
*/ | ||
@@ -21,3 +21,3 @@ interface CoreWebResource { | ||
* @remarks | ||
* Runtime-agnostic interface representing "ServiceClientCredentials" from @azure/ms-rest-js@1.2.6 | ||
* Runtime-agnostic interface representing "ServiceClientCredentials" from @azure/ms-rest-js | ||
*/ | ||
@@ -24,0 +24,0 @@ export interface CoreAppCredentials { |
@@ -36,2 +36,3 @@ /** | ||
export * from './storage'; | ||
export * from './stringUtils'; | ||
export * from './telemetryLoggerMiddleware'; | ||
@@ -38,0 +39,0 @@ export * from './testAdapter'; |
@@ -39,2 +39,3 @@ "use strict"; | ||
__export(require("./storage")); | ||
__export(require("./stringUtils")); | ||
__export(require("./telemetryLoggerMiddleware")); | ||
@@ -41,0 +42,0 @@ __export(require("./testAdapter")); |
@@ -41,3 +41,3 @@ /** | ||
* Gets the SkillConversationReference created using createSkillConversationId() for a skillConversationId. | ||
* @param skillConversationId Gets the SkillConversationReference used during CreateSkillConversationIdAsync for a skillConversationId. | ||
* @param skillConversationId Gets the SkillConversationReference used during createSkillConversationId for a skillConversationId. | ||
*/ | ||
@@ -44,0 +44,0 @@ getSkillConversationReference(skillConversationId: string): Promise<SkillConversationReference>; |
@@ -46,3 +46,3 @@ "use strict"; | ||
* Gets the SkillConversationReference created using createSkillConversationId() for a skillConversationId. | ||
* @param skillConversationId Gets the SkillConversationReference used during CreateSkillConversationIdAsync for a skillConversationId. | ||
* @param skillConversationId Gets the SkillConversationReference used during createSkillConversationId for a skillConversationId. | ||
*/ | ||
@@ -49,0 +49,0 @@ getSkillConversationReference(skillConversationId) { |
@@ -0,17 +1,20 @@ | ||
/** | ||
* Defines names of common properties for use with a [BotTelemetryClient](xref:botbuilder-core.BotTelemetryClient) object. | ||
*/ | ||
export declare class TelemetryConstants { | ||
readonly channelIdProperty: string; | ||
readonly conversationIdProperty: string; | ||
readonly conversationNameProperty: string; | ||
readonly dialogIdProperty: string; | ||
readonly fromIdProperty: string; | ||
readonly fromNameProperty: string; | ||
readonly localeProperty: string; | ||
readonly recipientIdProperty: string; | ||
readonly recipientNameProperty: string; | ||
readonly replyActivityIdProperty: string; | ||
readonly textProperty: string; | ||
readonly speakProperty: string; | ||
readonly userIdProperty: string; | ||
readonly attachmentsProperty: string; | ||
static readonly channelIdProperty: string; | ||
static readonly conversationIdProperty: string; | ||
static readonly conversationNameProperty: string; | ||
static readonly dialogIdProperty: string; | ||
static readonly fromIdProperty: string; | ||
static readonly fromNameProperty: string; | ||
static readonly localeProperty: string; | ||
static readonly recipientIdProperty: string; | ||
static readonly recipientNameProperty: string; | ||
static readonly replyActivityIdProperty: string; | ||
static readonly textProperty: string; | ||
static readonly speakProperty: string; | ||
static readonly userIdProperty: string; | ||
static readonly attachmentsProperty: string; | ||
} | ||
//# sourceMappingURL=telemetryConstants.d.ts.map |
"use strict"; | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// Licensed under the MIT License | ||
// Licensed under the MIT License. | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
/** | ||
* Defines names of common properties for use with a [BotTelemetryClient](xref:botbuilder-core.BotTelemetryClient) object. | ||
*/ | ||
class TelemetryConstants { | ||
constructor() { | ||
this.channelIdProperty = 'channelId'; | ||
this.conversationIdProperty = 'conversationId'; | ||
this.conversationNameProperty = 'conversationName'; | ||
this.dialogIdProperty = 'dialogId'; | ||
this.fromIdProperty = 'fromId'; | ||
this.fromNameProperty = 'fromName'; | ||
this.localeProperty = 'locale'; | ||
this.recipientIdProperty = 'recipientId'; | ||
this.recipientNameProperty = 'recipientName'; | ||
this.replyActivityIdProperty = 'replyActivityId'; | ||
this.textProperty = 'text'; | ||
this.speakProperty = 'speak'; | ||
this.userIdProperty = 'userId'; | ||
this.attachmentsProperty = 'attachments'; | ||
} | ||
} | ||
TelemetryConstants.channelIdProperty = 'channelId'; | ||
TelemetryConstants.conversationIdProperty = 'conversationId'; | ||
TelemetryConstants.conversationNameProperty = 'conversationName'; | ||
TelemetryConstants.dialogIdProperty = 'dialogId'; | ||
TelemetryConstants.fromIdProperty = 'fromId'; | ||
TelemetryConstants.fromNameProperty = 'fromName'; | ||
TelemetryConstants.localeProperty = 'locale'; | ||
TelemetryConstants.recipientIdProperty = 'recipientId'; | ||
TelemetryConstants.recipientNameProperty = 'recipientName'; | ||
TelemetryConstants.replyActivityIdProperty = 'replyActivityId'; | ||
TelemetryConstants.textProperty = 'text'; | ||
TelemetryConstants.speakProperty = 'speak'; | ||
TelemetryConstants.userIdProperty = 'userId'; | ||
TelemetryConstants.attachmentsProperty = 'attachments'; | ||
exports.TelemetryConstants = TelemetryConstants; | ||
//# sourceMappingURL=telemetryConstants.js.map |
@@ -5,3 +5,2 @@ import { BotTelemetryClient } from './botTelemetryClient'; | ||
import { Activity } from 'botframework-schema'; | ||
import { TelemetryConstants } from './telemetryConstants'; | ||
/** | ||
@@ -29,3 +28,2 @@ * Middleware for logging incoming, outgoing, updated or deleted Activity messages. | ||
private readonly _telemetryClient; | ||
readonly telemetryConstants: TelemetryConstants; | ||
private readonly _logPersonalInformation; | ||
@@ -130,3 +128,4 @@ /** | ||
}>; | ||
private populateAdditionalChannelProperties; | ||
} | ||
//# sourceMappingURL=telemetryLoggerMiddleware.d.ts.map |
@@ -29,3 +29,2 @@ "use strict"; | ||
constructor(telemetryClient, logPersonalInformation = false) { | ||
this.telemetryConstants = new telemetryConstants_1.TelemetryConstants(); | ||
this._telemetryClient = telemetryClient || new botTelemetryClient_1.NullTelemetryClient(); | ||
@@ -155,20 +154,27 @@ this._logPersonalInformation = logPersonalInformation; | ||
const properties = {}; | ||
properties[this.telemetryConstants.fromIdProperty] = activity.from ? activity.from.id : ''; | ||
properties[this.telemetryConstants.conversationNameProperty] = activity.conversation.name || ''; | ||
properties[this.telemetryConstants.localeProperty] = activity.locale || ''; | ||
properties[this.telemetryConstants.recipientIdProperty] = activity.recipient.id; | ||
properties[this.telemetryConstants.recipientNameProperty] = activity.recipient.name; | ||
// Use the LogPersonalInformation flag to toggle logging PII data, text and user name are common examples | ||
if (this.logPersonalInformation) { | ||
if (activity.from && activity.from.name && activity.from.name.trim()) { | ||
properties[this.telemetryConstants.fromNameProperty] = activity.from ? activity.from.name : ''; | ||
; | ||
if (activity) { | ||
properties[telemetryConstants_1.TelemetryConstants.fromIdProperty] = (activity.from && activity.from.id) ? activity.from.id : ''; | ||
properties[telemetryConstants_1.TelemetryConstants.conversationNameProperty] = (activity.conversation && activity.conversation.name) ? activity.conversation.name : ''; | ||
properties[telemetryConstants_1.TelemetryConstants.localeProperty] = activity.locale || ''; | ||
properties[telemetryConstants_1.TelemetryConstants.recipientIdProperty] = (activity.recipient && activity.recipient.id) ? activity.recipient.id : ''; | ||
properties[telemetryConstants_1.TelemetryConstants.recipientNameProperty] = (activity.recipient && activity.recipient.name) ? activity.recipient.name : ''; | ||
// Use the LogPersonalInformation flag to toggle logging PII data, text and user name are common examples | ||
if (this.logPersonalInformation) { | ||
if (activity.from && activity.from.name && activity.from.name.trim()) { | ||
properties[telemetryConstants_1.TelemetryConstants.fromNameProperty] = activity.from ? activity.from.name : ''; | ||
; | ||
} | ||
if (activity.text && activity.text.trim()) { | ||
properties[telemetryConstants_1.TelemetryConstants.textProperty] = activity.text; | ||
} | ||
if (activity.speak && activity.speak.trim()) { | ||
properties[telemetryConstants_1.TelemetryConstants.speakProperty] = activity.speak; | ||
} | ||
} | ||
if (activity.text && activity.text.trim()) { | ||
properties[this.telemetryConstants.textProperty] = activity.text; | ||
// Additional Properties can override "stock" properties. | ||
if (telemetryProperties) { | ||
return Object.assign({}, properties, telemetryProperties); | ||
} | ||
if (activity.speak && activity.speak.trim()) { | ||
properties[this.telemetryConstants.speakProperty] = activity.speak; | ||
} | ||
} | ||
this.populateAdditionalChannelProperties(activity, properties); | ||
// Additional Properties can override "stock" properties. | ||
@@ -191,25 +197,27 @@ if (telemetryProperties) { | ||
const properties = {}; | ||
properties[this.telemetryConstants.replyActivityIdProperty] = activity.replyToId || ''; | ||
properties[this.telemetryConstants.recipientIdProperty] = activity.recipient.id; | ||
properties[this.telemetryConstants.conversationNameProperty] = activity.conversation.name; | ||
properties[this.telemetryConstants.localeProperty] = activity.locale || ''; | ||
// Use the LogPersonalInformation flag to toggle logging PII data, text and user name are common examples | ||
if (this.logPersonalInformation) { | ||
if (activity.recipient.name && activity.recipient.name.trim()) { | ||
properties[this.telemetryConstants.recipientNameProperty] = activity.recipient.name; | ||
if (activity) { | ||
properties[telemetryConstants_1.TelemetryConstants.replyActivityIdProperty] = activity.replyToId || ''; | ||
properties[telemetryConstants_1.TelemetryConstants.recipientIdProperty] = (activity.recipient && activity.recipient.id) ? activity.recipient.id : ''; | ||
properties[telemetryConstants_1.TelemetryConstants.conversationNameProperty] = (activity.conversation && activity.conversation.name) ? activity.conversation.name : ''; | ||
properties[telemetryConstants_1.TelemetryConstants.localeProperty] = activity.locale || ''; | ||
// Use the LogPersonalInformation flag to toggle logging PII data, text and user name are common examples | ||
if (this.logPersonalInformation) { | ||
if (activity.recipient && activity.recipient.name && activity.recipient.name.trim()) { | ||
properties[telemetryConstants_1.TelemetryConstants.recipientNameProperty] = activity.recipient.name; | ||
} | ||
if (activity.text && activity.text.trim()) { | ||
properties[telemetryConstants_1.TelemetryConstants.textProperty] = activity.text; | ||
} | ||
if (activity.speak && activity.speak.trim()) { | ||
properties[telemetryConstants_1.TelemetryConstants.speakProperty] = activity.speak; | ||
} | ||
if (activity.attachments && activity.attachments.length > 0) { | ||
properties[telemetryConstants_1.TelemetryConstants.attachmentsProperty] = JSON.stringify(activity.attachments); | ||
} | ||
} | ||
if (activity.text && activity.text.trim()) { | ||
properties[this.telemetryConstants.textProperty] = activity.text; | ||
// Additional Properties can override "stock" properties. | ||
if (telemetryProperties) { | ||
return Object.assign({}, properties, telemetryProperties); | ||
} | ||
if (activity.speak && activity.speak.trim()) { | ||
properties[this.telemetryConstants.speakProperty] = activity.speak; | ||
} | ||
if (activity.attachments && activity.attachments.length > 0) { | ||
properties[this.telemetryConstants.attachmentsProperty] = JSON.stringify(activity.attachments); | ||
} | ||
} | ||
// Additional Properties can override "stock" properties. | ||
if (telemetryProperties) { | ||
return Object.assign({}, properties, telemetryProperties); | ||
} | ||
return properties; | ||
@@ -230,14 +238,16 @@ }); | ||
const properties = {}; | ||
properties[this.telemetryConstants.recipientIdProperty] = activity.recipient.id; | ||
properties[this.telemetryConstants.conversationIdProperty] = activity.conversation.id; | ||
properties[this.telemetryConstants.conversationNameProperty] = activity.conversation.name; | ||
properties[this.telemetryConstants.localeProperty] = activity.locale || ''; | ||
// Use the LogPersonalInformation flag to toggle logging PII data, text is a common example | ||
if (this.logPersonalInformation && activity.text && activity.text.trim()) { | ||
properties[this.telemetryConstants.textProperty] = activity.text; | ||
if (activity) { | ||
properties[telemetryConstants_1.TelemetryConstants.recipientIdProperty] = (activity.recipient && activity.recipient.id) ? activity.recipient.id : ''; | ||
properties[telemetryConstants_1.TelemetryConstants.conversationIdProperty] = (activity.conversation && activity.conversation.id) ? activity.conversation.id : ''; | ||
properties[telemetryConstants_1.TelemetryConstants.conversationNameProperty] = (activity.conversation && activity.conversation.name) ? activity.conversation.name : ''; | ||
properties[telemetryConstants_1.TelemetryConstants.localeProperty] = activity.locale || ''; | ||
// Use the LogPersonalInformation flag to toggle logging PII data, text is a common example | ||
if (this.logPersonalInformation && activity.text && activity.text.trim()) { | ||
properties[telemetryConstants_1.TelemetryConstants.textProperty] = activity.text; | ||
} | ||
// Additional Properties can override "stock" properties. | ||
if (telemetryProperties) { | ||
return Object.assign({}, properties, telemetryProperties); | ||
} | ||
} | ||
// Additional Properties can override "stock" properties. | ||
if (telemetryProperties) { | ||
return Object.assign({}, properties, telemetryProperties); | ||
} | ||
return properties; | ||
@@ -256,9 +266,11 @@ }); | ||
const properties = {}; | ||
properties[this.telemetryConstants.channelIdProperty] = activity.channelId; | ||
properties[this.telemetryConstants.recipientIdProperty] = activity.recipient.id; | ||
properties[this.telemetryConstants.conversationIdProperty] = activity.conversation.id; | ||
properties[this.telemetryConstants.conversationNameProperty] = activity.conversation.name; | ||
// Additional Properties can override "stock" properties. | ||
if (telemetryProperties) { | ||
return Object.assign({}, properties, telemetryProperties); | ||
if (activity) { | ||
properties[telemetryConstants_1.TelemetryConstants.channelIdProperty] = activity.channelId || ''; | ||
properties[telemetryConstants_1.TelemetryConstants.recipientIdProperty] = (activity.recipient && activity.recipient.id) ? activity.recipient.id : ''; | ||
properties[telemetryConstants_1.TelemetryConstants.conversationIdProperty] = (activity.conversation && activity.conversation.id) ? activity.conversation.id : ''; | ||
properties[telemetryConstants_1.TelemetryConstants.conversationNameProperty] = (activity.conversation && activity.conversation.name) ? activity.conversation.name : ''; | ||
// Additional Properties can override "stock" properties. | ||
if (telemetryProperties) { | ||
return Object.assign({}, properties, telemetryProperties); | ||
} | ||
} | ||
@@ -268,2 +280,18 @@ return properties; | ||
} | ||
populateAdditionalChannelProperties(activity, properties) { | ||
if (activity) { | ||
switch (activity.channelId) { | ||
case 'msteams': | ||
const channelData = activity.channelData; | ||
properties['TeamsTenantId'] = channelData.tenant ? channelData.tenant.id : ''; | ||
properties['TeamsUserAadObjectId'] = activity.from ? activity.from.aadObjectId : ''; | ||
if (channelData.team) { | ||
properties['TeamsTeamInfo'] = JSON.stringify(channelData.team); | ||
} | ||
break; | ||
default: | ||
break; | ||
} | ||
} | ||
} | ||
} | ||
@@ -270,0 +298,0 @@ /** |
@@ -188,2 +188,15 @@ import { Activity, ConversationReference, ResourceResponse, TokenResponse, TokenExchangeRequest, SignInUrlResponse } from 'botframework-schema'; | ||
/** | ||
* Asynchronously retrieves the token status for each configured connection for the given user. | ||
* In testAdapter, retrieves tokens which were previously added via addUserToken. | ||
* | ||
* @param context The context object for the turn. | ||
* @param userId The ID of the user to retrieve the token status for. | ||
* @param includeFilter Optional. A comma-separated list of connection's to include. If present, | ||
* the `includeFilter` parameter limits the tokens this method returns. | ||
* @param oAuthAppCredentials AppCredentials for OAuth. | ||
* | ||
* @returns The [TokenStatus](xref:botframework-connector.TokenStatus) objects retrieved. | ||
*/ | ||
getTokenStatus(context: TurnContext, userId: string, includeFilter?: string, oAuthAppCredentials?: any): Promise<any[]>; | ||
/** | ||
* Retrieves the OAuth token for a user that is in a sign-in flow. | ||
@@ -190,0 +203,0 @@ * @param context Context for the current turn of conversation with the user. |
@@ -263,2 +263,46 @@ "use strict"; | ||
/** | ||
* Asynchronously retrieves the token status for each configured connection for the given user. | ||
* In testAdapter, retrieves tokens which were previously added via addUserToken. | ||
* | ||
* @param context The context object for the turn. | ||
* @param userId The ID of the user to retrieve the token status for. | ||
* @param includeFilter Optional. A comma-separated list of connection's to include. If present, | ||
* the `includeFilter` parameter limits the tokens this method returns. | ||
* @param oAuthAppCredentials AppCredentials for OAuth. | ||
* | ||
* @returns The [TokenStatus](xref:botframework-connector.TokenStatus) objects retrieved. | ||
*/ | ||
getTokenStatus(context, userId, includeFilter, oAuthAppCredentials) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
if (!context || !context.activity) { | ||
throw new Error('testAdapter.getTokenStatus(): context with activity is required'); | ||
} | ||
if (!userId && (!context.activity.from || !context.activity.from.id)) { | ||
throw new Error(`testAdapter.getTokenStatus(): missing userId, from or from.id`); | ||
} | ||
const filter = (includeFilter ? includeFilter.split(',') : undefined); | ||
if (!userId) { | ||
userId = context.activity.from.id; | ||
} | ||
const match = this._userTokens.filter(x => x.ChannelId === context.activity.channelId | ||
&& x.UserId === userId | ||
&& (!filter || filter.includes(x.ConnectionName))); | ||
if (match && match.length > 0) { | ||
const tokenStatuses = []; | ||
for (var i = 0; i < match.length; i++) { | ||
tokenStatuses.push({ | ||
ConnectionName: match[i].ConnectionName, | ||
HasToken: true, | ||
ServiceProviderDisplayName: match[i].ConnectionName | ||
}); | ||
} | ||
return tokenStatuses; | ||
} | ||
else { | ||
// not found | ||
return undefined; | ||
} | ||
}); | ||
} | ||
/** | ||
* Retrieves the OAuth token for a user that is in a sign-in flow. | ||
@@ -265,0 +309,0 @@ * @param context Context for the current turn of conversation with the user. |
@@ -29,2 +29,10 @@ /** | ||
/** | ||
* Retrieves the token status for each configured connection for the given user, using the bot's AppCredentials. | ||
* @param context Context for the current turn of conversation with the user. | ||
* @param userId The user Id for which token status is retrieved. | ||
* @param includeFilter Comma separated list of connection's to include. Blank will return token status for all configured connections. | ||
* @param oAuthAppCredentials The app credentials for OAuth. | ||
*/ | ||
getTokenStatus(context: TurnContext, userId: string, includeFilter?: string, oAuthAppCredentials?: any): Promise<any[]>; | ||
/** | ||
* Gets a signin link from the token server that can be sent as part of a SigninCard. | ||
@@ -31,0 +39,0 @@ * @param context Context for the current turn of conversation with the user. |
@@ -5,3 +5,3 @@ { | ||
"description": "Core components for Microsoft Bot Builder. Components in this library can run either in a browser or on the server.", | ||
"version": "4.9.3", | ||
"version": "4.10.0-dev.20200805.aa06ea2", | ||
"license": "MIT", | ||
@@ -25,10 +25,10 @@ "keywords": [ | ||
"assert": "^1.4.1", | ||
"botframework-schema": "4.9.3" | ||
"botframework-schema": "4.10.0-dev.20200805.aa06ea2" | ||
}, | ||
"devDependencies": { | ||
"@microsoft/api-extractor": "^7.7.12", | ||
"@types/mocha": "^2.2.47", | ||
"@types/node": "^12.6.9", | ||
"mocha": "^5.2.0", | ||
"nyc": "^15.0.0", | ||
"@types/mocha": "^5.2.7", | ||
"@types/node": "^10.17.27", | ||
"mocha": "^6.2.3", | ||
"nyc": "^15.1.0", | ||
"source-map-support": "^0.5.3", | ||
@@ -44,3 +44,3 @@ "ts-node": "^4.1.0", | ||
"clean": "erase /q /s .\\lib", | ||
"set-version": "npm version --allow-same-version 4.9.3", | ||
"set-version": "npm version --allow-same-version 4.10.0-dev.20200805.aa06ea2", | ||
"test": "tsc && nyc mocha tests/", | ||
@@ -47,0 +47,0 @@ "test:compat": "api-extractor run --verbose" |
@@ -17,4 +17,2 @@ /** | ||
private static readonly lgType = 'lgType'; | ||
private static readonly errorPrefix = '[ERROR]'; | ||
private static readonly warningPrefix = '[WARNING]'; | ||
private static adaptiveCardType: string = CardFactory.contentTypes.adaptiveCard; | ||
@@ -43,2 +41,8 @@ | ||
private static readonly attachmentProperties: string[] = ['contentType', 'contentUrl', 'content', 'name', 'thumbnailUrl']; | ||
private static readonly cardProperties: string[] = ['title', 'subtitle', 'text', 'images', 'image', 'buttons', 'tap', 'media', | ||
'shareable', 'autoloop', 'autostart', 'aspect', 'duration', 'value', 'connectionName', 'tokenExchangeResource', | ||
'facts', 'items', 'total', 'tax', 'vat']; | ||
/** | ||
@@ -49,44 +53,10 @@ * Generate the activity. | ||
public static fromObject(lgResult: any): Partial<Activity> { | ||
const diagnostics: string[] = this.checkLGResult(lgResult); | ||
const errors: string[] = diagnostics.filter((u: string): boolean => u.startsWith(this.errorPrefix)); | ||
if (errors !== undefined && errors.length > 0) { | ||
throw new Error(`${ errors.join('\n') }`); | ||
} | ||
if (typeof lgResult === 'string') { | ||
const structuredLGResult: any = this.parseStructuredLGResult(lgResult.trim()); | ||
return structuredLGResult === undefined ? | ||
this.buildActivityFromText(lgResult.trim()) | ||
:this.buildActivityFromLGStructuredResult(lgResult); | ||
return this.buildActivityFromText(lgResult.trim()); | ||
} | ||
return this.buildActivityFromLGStructuredResult(lgResult); | ||
} | ||
/** | ||
* check the LG result before generate an Activity. | ||
* @param lgResult lg output. | ||
* @returns Diagnostic list. | ||
*/ | ||
public static checkLGResult(lgResult: any): string[] { | ||
if (lgResult === undefined) { | ||
return [this.buildDiagnostic('LG output is empty', false)]; | ||
} | ||
if (typeof lgResult === 'string') { | ||
if (!lgResult.startsWith('{') || !lgResult.endsWith('}')) { | ||
return [this.buildDiagnostic('LG output is not a json object, and will fallback to string format.', false)]; | ||
} | ||
let lgStructuredResult: any = undefined; | ||
try { | ||
lgStructuredResult = JSON.parse(lgResult); | ||
} catch (error) { | ||
return [this.buildDiagnostic('LG output is not a json object, and will fallback to string format.', false)]; | ||
} | ||
return this.checkStructuredResult(lgStructuredResult); | ||
if (typeof lgResult === 'object') { | ||
return this.buildActivityFromLGStructuredResult(lgResult); | ||
} else { | ||
return this.checkStructuredResult(lgResult); | ||
return this.buildActivityFromText(JSON.stringify(lgResult).trim()); | ||
} | ||
@@ -101,7 +71,10 @@ } | ||
const msg: Partial<Activity> = { | ||
type: ActivityTypes.Message, | ||
text: text, | ||
speak: text | ||
type: ActivityTypes.Message | ||
}; | ||
if (text) { | ||
msg.text = text; | ||
msg.speak = text; | ||
} | ||
return msg; | ||
@@ -147,10 +120,3 @@ } | ||
default: | ||
var properties = this.activityProperties.map((u: string): string => u.toLowerCase()); | ||
if (properties.includes(property.toLowerCase())) | ||
{ | ||
var realPropertyName = this.activityProperties[properties.indexOf(property.toLowerCase())]; | ||
activity[realPropertyName] = value; | ||
} else { | ||
activity[property.toLowerCase()] = value; | ||
} | ||
activity[this.realProperty(property, this.activityProperties)] = value; | ||
break; | ||
@@ -202,16 +168,3 @@ } | ||
} | ||
const value: any = action[key]; | ||
switch (property.toLowerCase()) { | ||
case 'displaytext': | ||
cardAction.displayText = value; | ||
break; | ||
case 'channeldata': | ||
cardAction.channelData = value; | ||
break; | ||
default: | ||
cardAction[property.toLowerCase()] = value; | ||
break; | ||
} | ||
cardAction[this.realProperty(property, this.cardActionProperties)] = action[key]; | ||
} | ||
@@ -224,5 +177,2 @@ } | ||
private static getAttachments(input: any): Attachment[] { | ||
@@ -277,10 +227,4 @@ const attachments: Attachment[] = []; | ||
break; | ||
case 'contenturl': | ||
attachment.contentUrl = value; | ||
break; | ||
case 'thumbnailurl': | ||
attachment.thumbnailUrl = value; | ||
break; | ||
default: | ||
attachment[property.toLowerCase()] = value; | ||
attachment[this.realProperty(property, this.attachmentProperties)] = value; | ||
break; | ||
@@ -311,6 +255,6 @@ } | ||
const imageList: string[] = this.normalizedToList(value).map((u): string => u.toString()); | ||
imageList.forEach( (u): any => card['images'].push({url : u})); | ||
const imageList = this.normalizedToList(value); | ||
imageList.forEach( (u): any => card['images'].push(this.normalizedToMediaOrImage(u))); | ||
} else { | ||
card['image'] = {url: value.toString()}; | ||
card['image'] = this.normalizedToMediaOrImage(value); | ||
} | ||
@@ -323,4 +267,4 @@ break; | ||
const mediaList: string[] = this.normalizedToList(value).map((u): string => u.toString()); | ||
mediaList.forEach( (u): any => card['media'].push({url : u})); | ||
const mediaList = this.normalizedToList(value); | ||
mediaList.forEach( (u): any => card['media'].push(this.normalizedToMediaOrImage(u))); | ||
break; | ||
@@ -341,9 +285,8 @@ case 'buttons': | ||
card[property] = boolValue; | ||
} else { | ||
card[property] = value; | ||
} | ||
break; | ||
case 'connectionname': | ||
card['connectionName'] = value; | ||
break; | ||
default: | ||
card[property.toLowerCase()] = value; | ||
card[this.realProperty(key.trim(), this.cardProperties)] = value; | ||
break; | ||
@@ -361,2 +304,12 @@ } | ||
private static realProperty(property: string, builtinProperties: string[]): string { | ||
const properties = builtinProperties.map((u: string): string => u.toLowerCase()); | ||
if (properties.includes(property.toLowerCase())) | ||
{ | ||
return builtinProperties[properties.indexOf(property.toLowerCase())]; | ||
} else { | ||
return property; | ||
} | ||
} | ||
private static normalizedToList(item: any): any[] { | ||
@@ -372,236 +325,2 @@ if (item === undefined) { | ||
private static parseStructuredLGResult(lgStringResult: string): any | ||
{ | ||
let lgStructuredResult: any = undefined; | ||
if (lgStringResult === undefined || lgStringResult === '') { | ||
return undefined; | ||
} | ||
lgStringResult = lgStringResult.trim(); | ||
if (lgStringResult === '' || !lgStringResult.startsWith('{') || !lgStringResult.endsWith('}')) { | ||
return undefined; | ||
} | ||
try { | ||
lgStructuredResult = JSON.parse(lgStringResult); | ||
const type = this.getStructureType(lgStringResult); | ||
if (!type || type.trim() === '') { | ||
return undefined; | ||
} | ||
} catch (error) { | ||
return undefined; | ||
} | ||
return lgStructuredResult; | ||
} | ||
private static checkStructuredResult(input: any): string[] { | ||
const result: string[] = []; | ||
const type: string = this.getStructureType(input); | ||
if (!type || type.trim() === '') { | ||
return result; | ||
} | ||
if (this.genericCardTypeMapping.has(type) || type === 'attachment') { | ||
result.push(...this.checkAttachment(input)); | ||
} else if (type === 'activity') { | ||
result.push(...this.checkActivity(input)); | ||
} else { | ||
const diagnosticMessage = `Type '${ type }' is not supported currently.`; | ||
result.push(this.buildDiagnostic(diagnosticMessage, false)); | ||
} | ||
return result; | ||
} | ||
private static checkActivity(input: any): string[] { | ||
const result: string[] = []; | ||
let activityType: string = undefined; | ||
if ('type' in input) { | ||
activityType = input['type'].toString().trim(); | ||
} | ||
result.push(...this.checkActivityType(activityType)); | ||
result.push(...this.checkActivityPropertyName(input)); | ||
result.push(...this.checkActivityProperties(input)); | ||
return result; | ||
} | ||
private static checkActivityType(activityType: string): string[] { | ||
if (activityType !== undefined) { | ||
if (!Object.values(ActivityTypes).map((u: string): string => u.toLowerCase()).includes(activityType.toLowerCase())) { | ||
return [this.buildDiagnostic(`'${ activityType }' is not a valid activity type.`)]; | ||
} | ||
} | ||
return []; | ||
} | ||
private static checkActivityPropertyName(input: any): string[] { | ||
const invalidProperties: string[] = []; | ||
for (const property of Object.keys(input)) { | ||
if (property === this.lgType) { | ||
continue; | ||
} | ||
if (!this.activityProperties.map((u: string): string => u.toLowerCase()).includes(property.toLowerCase())) { | ||
invalidProperties.push(property); | ||
} | ||
} | ||
if (invalidProperties.length > 0) { | ||
return [this.buildDiagnostic(`'${ invalidProperties.join(',') }' not support in Activity.`, false)]; | ||
} | ||
return []; | ||
} | ||
private static checkActivityProperties(input: any): string[] { | ||
const result: string[] = []; | ||
for (const key of Object.keys(input)) { | ||
const property: string = key.trim(); | ||
const value: any = input[key]; | ||
switch (property.toLowerCase()) { | ||
case 'attachments': | ||
result.push(...this.checkAttachments(value)); | ||
break; | ||
case 'suggestedactions': | ||
result.push(...this.checkSuggestions(value)); | ||
break; | ||
default: | ||
break; | ||
} | ||
} | ||
return result; | ||
} | ||
private static checkSuggestions(value: any): string[] { | ||
const actions: any[] = this.normalizedToList(value); | ||
return this.checkCardActions(actions); | ||
} | ||
private static checkButtons(value: any): string[] { | ||
const actions: any[] = this.normalizedToList(value); | ||
return this.checkCardActions(actions); | ||
} | ||
private static checkCardActions(actions: any[]): string[] { | ||
const result: string[] = []; | ||
actions.forEach((u: any): void => { result.push(...this.checkCardAction(u)); }); | ||
return result; | ||
} | ||
private static checkCardAction(value: any): string[] { | ||
const result: string[] = []; | ||
if (typeof value === 'string') { | ||
return result; | ||
} | ||
if (typeof value === 'object') { | ||
const type: string = this.getStructureType(value); | ||
if (type !== 'cardaction') { | ||
result.push(this.buildDiagnostic(`'${ type }' is not card action type.`, false)); | ||
} else { | ||
result.push(...this.checkCardActionPropertyName(value)); | ||
if ('type' in value) { | ||
result.push(...this.checkCardActionType(value['type'])); | ||
} | ||
} | ||
} else { | ||
result.push(this.buildDiagnostic(`'${ value }' is not a valid card action format.`, false)); | ||
} | ||
return result; | ||
} | ||
private static checkCardActionPropertyName(input: any): string[] { | ||
const invalidProperties: string[] = []; | ||
for (const property of Object.keys(input)) { | ||
if (property === this.lgType) { | ||
continue; | ||
} | ||
if (!this.cardActionProperties.map((u: string): string => u.toLowerCase()).includes(property.toLowerCase())) { | ||
invalidProperties.push(property); | ||
} | ||
} | ||
if (invalidProperties.length > 0) { | ||
return [this.buildDiagnostic(`'${ invalidProperties.join(',') }' not support in card action.`, false)]; | ||
} | ||
return []; | ||
} | ||
private static checkCardActionType(cardActionType: string): string[] { | ||
const result: string[] = []; | ||
if (!cardActionType) { | ||
return result; | ||
} | ||
if (!Object.values(ActionTypes).map((u: string): string => u.toLowerCase()).includes(cardActionType.toLowerCase())) { | ||
return [this.buildDiagnostic(`'${ cardActionType }' is not a valid card action type.`)]; | ||
} | ||
return result; | ||
} | ||
private static checkAttachments(value: any): string[] { | ||
const result: string[] = []; | ||
const attachmentsJsonList: any[] = this.normalizedToList(value); | ||
for (const attachmentsJson of attachmentsJsonList) { | ||
if (typeof attachmentsJson === 'object') { | ||
result.push(...this.checkAttachment(attachmentsJson)); | ||
} | ||
} | ||
return result; | ||
} | ||
private static checkAttachment(value: any): string[] { | ||
const result: string[] = []; | ||
const type: string = this.getStructureType(value); | ||
if (this.genericCardTypeMapping.has(type)) { | ||
result.push(...this.checkCardAttachment(value)); | ||
} else if (type === 'adaptivecard') { | ||
// TODO | ||
// check adaptivecard format | ||
} else if (type === 'attachment') { | ||
// TODO | ||
// Check attachment format | ||
} else { | ||
result.push(this.buildDiagnostic(`'${ type }' is not an attachment type.`, false)); | ||
} | ||
return result; | ||
} | ||
private static checkCardAttachment(input: any): string[] { | ||
const result: string[] = []; | ||
for (const key of Object.keys(input)) { | ||
const property: string = key.trim().toLowerCase(); | ||
const value: any = input[key]; | ||
switch (property) { | ||
case 'buttons': | ||
result.push(...this.checkButtons(value)); | ||
break; | ||
case 'autostart': | ||
case 'shareable': | ||
case 'autoloop': | ||
const boolValue: boolean = this.getValidBooleanValue(value.toString()); | ||
if (boolValue === undefined) { | ||
result.push(this.buildDiagnostic(`'${ value.toString() }' is not a boolean value.`)); | ||
} | ||
break; | ||
default: | ||
break; | ||
} | ||
} | ||
return result; | ||
} | ||
private static getStructureType(input: any): string { | ||
@@ -622,4 +341,15 @@ let result = ''; | ||
private static getValidBooleanValue(boolValue: string): boolean{ | ||
private static normalizedToMediaOrImage(item: any): object { | ||
if (!item) { | ||
return {}; | ||
} else if (typeof item === 'string') { | ||
return {url: item}; | ||
} else return item; | ||
} | ||
private static getValidBooleanValue(boolValue: any): boolean{ | ||
if (typeof boolValue === 'boolean') { | ||
return boolValue; | ||
} | ||
if (boolValue.toLowerCase() === 'true') | ||
@@ -636,7 +366,2 @@ { | ||
} | ||
private static buildDiagnostic(message: string, isError: boolean = true): string { | ||
message = message === undefined ? '' : message; | ||
return isError ? this.errorPrefix + message : this.warningPrefix + message; | ||
} | ||
} |
@@ -291,2 +291,17 @@ /** | ||
/** | ||
* Registers an activity event handler for the _installationupdate_ activity. | ||
* | ||
* @param handler The event handler. | ||
* | ||
* @remarks | ||
* Returns a reference to the [ActivityHandler](xref:botbuilder-core.ActivityHandler) object. | ||
* | ||
* To handle a InstallationUpdate event, use the | ||
* [onInstallationUpdate](xref:botbuilder-core.ActivityHandler.onInstallationUpdate) type-specific event handler. | ||
*/ | ||
public onInstallationUpdate(handler: BotHandler): this { | ||
return this.on('InstallationUpdate', handler); | ||
} | ||
/** | ||
* Registers an activity event handler for the _tokens-response_ event, emitted for any incoming | ||
@@ -503,2 +518,18 @@ * `tokens/response` event activity. These are generated as part of the OAuth authentication flow. | ||
/** | ||
* Runs all registered _instllationupdate_ handlers and then continues the event emission process. | ||
* | ||
* @param context The context object for the current turn. | ||
* | ||
* @remarks | ||
* Overwrite this method to support channel-specific behavior across multiple channels. | ||
* | ||
* The default logic is to call any handlers registered via | ||
* [onInstallationUpdateActivity](xref:botbuilder-core.ActivityHandler.onInstallationUpdateActivity), | ||
* and then continue by calling [defaultNextEvent](xref:botbuilder-core.ActivityHandler.defaultNextEvent). | ||
*/ | ||
protected async onInstallationUpdateActivity(context: TurnContext): Promise<void> { | ||
await this.handle(context, 'InstallationUpdate', this.defaultNextEvent(context)); | ||
} | ||
/** | ||
* Runs all registered _unrecognized activity type_ handlers and then continues the event emission process. | ||
@@ -505,0 +536,0 @@ * |
@@ -82,2 +82,5 @@ /** | ||
break; | ||
case ActivityTypes.InstallationUpdate: | ||
await this.onInstallationUpdateActivity(context); | ||
break; | ||
default: | ||
@@ -205,2 +208,15 @@ // handler for unknown or unhandled types | ||
/** | ||
* Provides a hook for emitting the _installationupdate_ event. | ||
* | ||
* @param context The context object for the current turn. | ||
* | ||
* @remarks | ||
* Overwrite this method to run registered _installationupdate_ handlers and then continue the event | ||
* emission process. | ||
*/ | ||
protected async onInstallationUpdateActivity(context: TurnContext): Promise<void> { | ||
return; | ||
} | ||
/** | ||
* Provides a hook for emitting the _unrecognized_ event. | ||
@@ -207,0 +223,0 @@ * |
@@ -10,3 +10,3 @@ /** | ||
/** | ||
* Internal interface representing the "WebResource" from @azure/ms-rest-js@1.2.6 | ||
* Internal interface representing the "WebResource" from @azure/ms-rest-js | ||
*/ | ||
@@ -24,3 +24,3 @@ interface CoreWebResource { | ||
* @remarks | ||
* Runtime-agnostic interface representing "ServiceClientCredentials" from @azure/ms-rest-js@1.2.6 | ||
* Runtime-agnostic interface representing "ServiceClientCredentials" from @azure/ms-rest-js | ||
*/ | ||
@@ -27,0 +27,0 @@ export interface CoreAppCredentials { |
@@ -43,2 +43,3 @@ /** | ||
export * from './storage'; | ||
export * from './stringUtils'; | ||
export * from './telemetryLoggerMiddleware'; | ||
@@ -45,0 +46,0 @@ export * from './testAdapter'; |
@@ -53,3 +53,3 @@ /** | ||
* Gets the SkillConversationReference created using createSkillConversationId() for a skillConversationId. | ||
* @param skillConversationId Gets the SkillConversationReference used during CreateSkillConversationIdAsync for a skillConversationId. | ||
* @param skillConversationId Gets the SkillConversationReference used during createSkillConversationId for a skillConversationId. | ||
*/ | ||
@@ -56,0 +56,0 @@ public getSkillConversationReference(skillConversationId: string): Promise<SkillConversationReference> { |
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// Licensed under the MIT License | ||
// Licensed under the MIT License. | ||
/** | ||
* Defines names of common properties for use with a [BotTelemetryClient](xref:botbuilder-core.BotTelemetryClient) object. | ||
*/ | ||
export class TelemetryConstants { | ||
public readonly channelIdProperty: string = 'channelId'; | ||
public readonly conversationIdProperty: string = 'conversationId'; | ||
public readonly conversationNameProperty: string = 'conversationName'; | ||
public readonly dialogIdProperty: string = 'dialogId'; | ||
public readonly fromIdProperty: string = 'fromId'; | ||
public readonly fromNameProperty: string = 'fromName'; | ||
public readonly localeProperty: string = 'locale'; | ||
public readonly recipientIdProperty: string = 'recipientId'; | ||
public readonly recipientNameProperty: string = 'recipientName'; | ||
public readonly replyActivityIdProperty: string = 'replyActivityId'; | ||
public readonly textProperty: string = 'text'; | ||
public readonly speakProperty: string = 'speak'; | ||
public readonly userIdProperty: string = 'userId'; | ||
public readonly attachmentsProperty: string = 'attachments'; | ||
} | ||
public static readonly channelIdProperty: string = 'channelId'; | ||
public static readonly conversationIdProperty: string = 'conversationId'; | ||
public static readonly conversationNameProperty: string = 'conversationName'; | ||
public static readonly dialogIdProperty: string = 'dialogId'; | ||
public static readonly fromIdProperty: string = 'fromId'; | ||
public static readonly fromNameProperty: string = 'fromName'; | ||
public static readonly localeProperty: string = 'locale'; | ||
public static readonly recipientIdProperty: string = 'recipientId'; | ||
public static readonly recipientNameProperty: string = 'recipientName'; | ||
public static readonly replyActivityIdProperty: string = 'replyActivityId'; | ||
public static readonly textProperty: string = 'text'; | ||
public static readonly speakProperty: string = 'speak'; | ||
public static readonly userIdProperty: string = 'userId'; | ||
public static readonly attachmentsProperty: string = 'attachments'; | ||
} |
@@ -7,3 +7,3 @@ // Copyright (c) Microsoft Corporation. All rights reserved. | ||
import { TurnContext } from './turnContext'; | ||
import { Activity, ActivityTypes, ConversationReference, ResourceResponse } from 'botframework-schema'; | ||
import { Activity, ActivityTypes, ConversationReference, ResourceResponse, TeamsChannelData } from 'botframework-schema'; | ||
import { TelemetryConstants } from './telemetryConstants'; | ||
@@ -37,3 +37,2 @@ | ||
private readonly _telemetryClient: BotTelemetryClient; | ||
public readonly telemetryConstants: TelemetryConstants = new TelemetryConstants(); | ||
@@ -193,27 +192,35 @@ // tslint:disable:variable-name | ||
properties[this.telemetryConstants.fromIdProperty] = activity.from ? activity.from.id : ''; | ||
properties[this.telemetryConstants.conversationNameProperty] = activity.conversation.name || ''; | ||
properties[this.telemetryConstants.localeProperty] = activity.locale || ''; | ||
properties[this.telemetryConstants.recipientIdProperty] = activity.recipient.id; | ||
properties[this.telemetryConstants.recipientNameProperty] = activity.recipient.name; | ||
if (activity) { | ||
properties[TelemetryConstants.fromIdProperty] = (activity.from && activity.from.id) ? activity.from.id : ''; | ||
properties[TelemetryConstants.conversationNameProperty] = (activity.conversation && activity.conversation.name) ? activity.conversation.name : ''; | ||
properties[TelemetryConstants.localeProperty] = activity.locale || ''; | ||
properties[TelemetryConstants.recipientIdProperty] = (activity.recipient && activity.recipient.id) ? activity.recipient.id : ''; | ||
properties[TelemetryConstants.recipientNameProperty] = (activity.recipient && activity.recipient.name) ? activity.recipient.name : ''; | ||
// Use the LogPersonalInformation flag to toggle logging PII data, text and user name are common examples | ||
if (this.logPersonalInformation) { | ||
// Use the LogPersonalInformation flag to toggle logging PII data, text and user name are common examples | ||
if (this.logPersonalInformation) { | ||
if (activity.from && activity.from.name && activity.from.name.trim()) { | ||
properties[TelemetryConstants.fromNameProperty] = activity.from ? activity.from.name : '';; | ||
} | ||
if (activity.from && activity.from.name && activity.from.name.trim()) { | ||
properties[this.telemetryConstants.fromNameProperty] = activity.from ? activity.from.name : '';; | ||
} | ||
if (activity.text && activity.text.trim()) { | ||
properties[TelemetryConstants.textProperty] = activity.text; | ||
} | ||
if (activity.text && activity.text.trim()) { | ||
properties[this.telemetryConstants.textProperty] = activity.text; | ||
if (activity.speak && activity.speak.trim()) { | ||
properties[TelemetryConstants.speakProperty] = activity.speak; | ||
} | ||
} | ||
if (activity.speak && activity.speak.trim()) { | ||
properties[this.telemetryConstants.speakProperty] = activity.speak; | ||
// Additional Properties can override "stock" properties. | ||
if (telemetryProperties) | ||
{ | ||
return Object.assign({}, properties, telemetryProperties); | ||
} | ||
} | ||
this.populateAdditionalChannelProperties(activity, properties); | ||
// Additional Properties can override "stock" properties. | ||
if (telemetryProperties) | ||
{ | ||
if (telemetryProperties) { | ||
return Object.assign({}, properties, telemetryProperties); | ||
@@ -235,32 +242,33 @@ } | ||
properties[this.telemetryConstants.replyActivityIdProperty] = activity.replyToId || ''; | ||
properties[this.telemetryConstants.recipientIdProperty] = activity.recipient.id; | ||
properties[this.telemetryConstants.conversationNameProperty] = activity.conversation.name; | ||
properties[this.telemetryConstants.localeProperty] = activity.locale || ''; | ||
if (activity) { | ||
properties[TelemetryConstants.replyActivityIdProperty] = activity.replyToId || ''; | ||
properties[TelemetryConstants.recipientIdProperty] = (activity.recipient && activity.recipient.id) ? activity.recipient.id : ''; | ||
properties[TelemetryConstants.conversationNameProperty] = (activity.conversation && activity.conversation.name) ? activity.conversation.name : ''; | ||
properties[TelemetryConstants.localeProperty] = activity.locale || ''; | ||
// Use the LogPersonalInformation flag to toggle logging PII data, text and user name are common examples | ||
if (this.logPersonalInformation) { | ||
if (activity.recipient.name && activity.recipient.name.trim()) { | ||
properties[this.telemetryConstants.recipientNameProperty] = activity.recipient.name; | ||
} | ||
// Use the LogPersonalInformation flag to toggle logging PII data, text and user name are common examples | ||
if (this.logPersonalInformation) { | ||
if (activity.recipient && activity.recipient.name && activity.recipient.name.trim()) { | ||
properties[TelemetryConstants.recipientNameProperty] = activity.recipient.name; | ||
} | ||
if (activity.text && activity.text.trim()) { | ||
properties[this.telemetryConstants.textProperty] = activity.text; | ||
} | ||
if (activity.text && activity.text.trim()) { | ||
properties[TelemetryConstants.textProperty] = activity.text; | ||
} | ||
if (activity.speak && activity.speak.trim()) { | ||
properties[this.telemetryConstants.speakProperty] = activity.speak; | ||
if (activity.speak && activity.speak.trim()) { | ||
properties[TelemetryConstants.speakProperty] = activity.speak; | ||
} | ||
if (activity.attachments && activity.attachments.length > 0) { | ||
properties[TelemetryConstants.attachmentsProperty] = JSON.stringify(activity.attachments); | ||
} | ||
} | ||
if (activity.attachments && activity.attachments.length > 0) { | ||
properties[this.telemetryConstants.attachmentsProperty] = JSON.stringify(activity.attachments); | ||
// Additional Properties can override "stock" properties. | ||
if (telemetryProperties) { | ||
return Object.assign({}, properties, telemetryProperties); | ||
} | ||
} | ||
// Additional Properties can override "stock" properties. | ||
if (telemetryProperties) | ||
{ | ||
return Object.assign({}, properties, telemetryProperties); | ||
} | ||
return properties; | ||
@@ -280,19 +288,20 @@ } | ||
const properties: { [key: string]: string } = {}; | ||
properties[this.telemetryConstants.recipientIdProperty] = activity.recipient.id; | ||
properties[this.telemetryConstants.conversationIdProperty] = activity.conversation.id; | ||
properties[this.telemetryConstants.conversationNameProperty] = activity.conversation.name; | ||
properties[this.telemetryConstants.localeProperty] = activity.locale || ''; | ||
// Use the LogPersonalInformation flag to toggle logging PII data, text is a common example | ||
if (this.logPersonalInformation && activity.text && activity.text.trim()) { | ||
properties[this.telemetryConstants.textProperty] = activity.text; | ||
} | ||
if (activity) { | ||
properties[TelemetryConstants.recipientIdProperty] = (activity.recipient && activity.recipient.id) ? activity.recipient.id : ''; | ||
properties[TelemetryConstants.conversationIdProperty] = (activity.conversation && activity.conversation.id) ? activity.conversation.id : ''; | ||
properties[TelemetryConstants.conversationNameProperty] = (activity.conversation && activity.conversation.name) ? activity.conversation.name : ''; | ||
properties[TelemetryConstants.localeProperty] = activity.locale || ''; | ||
// Additional Properties can override "stock" properties. | ||
if (telemetryProperties) | ||
{ | ||
return Object.assign({}, properties, telemetryProperties); | ||
// Use the LogPersonalInformation flag to toggle logging PII data, text is a common example | ||
if (this.logPersonalInformation && activity.text && activity.text.trim()) { | ||
properties[TelemetryConstants.textProperty] = activity.text; | ||
} | ||
// Additional Properties can override "stock" properties. | ||
if (telemetryProperties) { | ||
return Object.assign({}, properties, telemetryProperties); | ||
} | ||
} | ||
return properties; | ||
@@ -310,11 +319,13 @@ } | ||
const properties: { [key: string]: string } = {}; | ||
properties[this.telemetryConstants.channelIdProperty] = activity.channelId; | ||
properties[this.telemetryConstants.recipientIdProperty] = activity.recipient.id; | ||
properties[this.telemetryConstants.conversationIdProperty] = activity.conversation.id; | ||
properties[this.telemetryConstants.conversationNameProperty] = activity.conversation.name; | ||
// Additional Properties can override "stock" properties. | ||
if (telemetryProperties) | ||
{ | ||
return Object.assign({}, properties, telemetryProperties); | ||
if (activity) { | ||
properties[TelemetryConstants.channelIdProperty] = activity.channelId || ''; | ||
properties[TelemetryConstants.recipientIdProperty] = (activity.recipient && activity.recipient.id) ? activity.recipient.id : ''; | ||
properties[TelemetryConstants.conversationIdProperty] = (activity.conversation && activity.conversation.id) ? activity.conversation.id : ''; | ||
properties[TelemetryConstants.conversationNameProperty] = (activity.conversation && activity.conversation.name) ? activity.conversation.name : ''; | ||
// Additional Properties can override "stock" properties. | ||
if (telemetryProperties) { | ||
return Object.assign({}, properties, telemetryProperties); | ||
} | ||
} | ||
@@ -324,2 +335,22 @@ | ||
} | ||
} | ||
private populateAdditionalChannelProperties(activity: Activity, properties?: {[key: string]: string}): void { | ||
if (activity) { | ||
switch (activity.channelId) { | ||
case 'msteams': | ||
const channelData = activity.channelData as TeamsChannelData; | ||
properties['TeamsTenantId'] = channelData.tenant ? channelData.tenant.id : ''; | ||
properties['TeamsUserAadObjectId'] = activity.from ? activity.from.aadObjectId : ''; | ||
if (channelData.team) { | ||
properties['TeamsTeamInfo'] = JSON.stringify(channelData.team); | ||
} | ||
break; | ||
default: | ||
break; | ||
} | ||
} | ||
} | ||
} |
@@ -313,2 +313,54 @@ /** | ||
/** | ||
* Asynchronously retrieves the token status for each configured connection for the given user. | ||
* In testAdapter, retrieves tokens which were previously added via addUserToken. | ||
* | ||
* @param context The context object for the turn. | ||
* @param userId The ID of the user to retrieve the token status for. | ||
* @param includeFilter Optional. A comma-separated list of connection's to include. If present, | ||
* the `includeFilter` parameter limits the tokens this method returns. | ||
* @param oAuthAppCredentials AppCredentials for OAuth. | ||
* | ||
* @returns The [TokenStatus](xref:botframework-connector.TokenStatus) objects retrieved. | ||
*/ | ||
public async getTokenStatus(context: TurnContext, userId: string, includeFilter?: string, oAuthAppCredentials?: any): Promise<any[]> { | ||
if (!context || !context.activity) { | ||
throw new Error('testAdapter.getTokenStatus(): context with activity is required'); | ||
} | ||
if (!userId && (!context.activity.from || !context.activity.from.id)) { | ||
throw new Error(`testAdapter.getTokenStatus(): missing userId, from or from.id`); | ||
} | ||
const filter = (includeFilter ? includeFilter.split(',') : undefined); | ||
if(!userId) { | ||
userId = context.activity.from.id; | ||
} | ||
const match = this._userTokens.filter(x => x.ChannelId === context.activity.channelId | ||
&& x.UserId === userId | ||
&& (!filter || filter.includes(x.ConnectionName))); | ||
if (match && match.length > 0) | ||
{ | ||
const tokenStatuses = []; | ||
for (var i = 0; i < match.length; i++) { | ||
tokenStatuses.push( | ||
{ | ||
ConnectionName: match[i].ConnectionName, | ||
HasToken: true, | ||
ServiceProviderDisplayName: match[i].ConnectionName | ||
}); | ||
} | ||
return tokenStatuses; | ||
} | ||
else | ||
{ | ||
// not found | ||
return undefined; | ||
} | ||
} | ||
/** | ||
@@ -315,0 +367,0 @@ * Retrieves the OAuth token for a user that is in a sign-in flow. |
@@ -33,2 +33,11 @@ /** | ||
/** | ||
* Retrieves the token status for each configured connection for the given user, using the bot's AppCredentials. | ||
* @param context Context for the current turn of conversation with the user. | ||
* @param userId The user Id for which token status is retrieved. | ||
* @param includeFilter Comma separated list of connection's to include. Blank will return token status for all configured connections. | ||
* @param oAuthAppCredentials The app credentials for OAuth. | ||
*/ | ||
getTokenStatus(context: TurnContext, userId: string, includeFilter?: string, oAuthAppCredentials?: any): Promise<any[]>; | ||
/** | ||
* Gets a signin link from the token server that can be sent as part of a SigninCard. | ||
@@ -35,0 +44,0 @@ * @param context Context for the current turn of conversation with the user. |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
232
794308
15543
2
+ Addedbotframework-schema@4.10.0-dev.20200805.aa06ea2(transitive)
- Removedbotframework-schema@4.9.3(transitive)