@@ -247,8 +247,12 @@ export const INVOKE_RESPONSE_KEY: symbol = Symbol('invokeResponse');
247
247
* ```
248
248
*/
249
249
export class BotFrameworkAdapter extends BotAdapter implements IUserTokenProvider , RequestHandler {
250
- public static readonly BotIdentityKey : string = 'BotIdentity' ;
251
- public static readonly ConnectorClientKey : string = 'ConnectorClient' ;
250
+ // These keys are public to permit access to the keys from the adapter when it's a being
251
+ // from library that does not have access to static properties off of BotFrameworkAdapter.
252
+ // E.g. botbuilder-dialogs
253
+ public readonly BotIdentityKey : Symbol = Symbol ( 'BotIdentity' ) ;
254
+ public readonly ConnectorClientKey : Symbol = Symbol ( 'ConnectorClient' ) ;
255
+
252
256
protected readonly credentials : AppCredentials ;
253
257
protected readonly credentialsProvider : SimpleCredentialProvider ;
254
258
protected readonly settings : BotFrameworkAdapterSettings ;
@@ -489,7 +493,7 @@ export class BotFrameworkAdapter extends BotAdapter implements IUserTokenProvide
489
493
throw new Error ( `BotFrameworkAdapter.deleteActivity(): missing conversation or conversation.id` ) ;
490
494
}
491
495
if ( ! reference . activityId ) { throw new Error ( `BotFrameworkAdapter.deleteActivity(): missing activityId` ) ; }
492
- const client : ConnectorClient = this . createConnectorClient ( reference . serviceUrl ) ;
496
+ const client : ConnectorClient = this . getOrCreateConnectorClient ( context , reference . serviceUrl , this . credentials ) ;
493
497
await client . conversations . deleteActivity ( reference . conversation . id , reference . activityId ) ;
494
498
}
495
499
@@ -511,7 +515,7 @@ export class BotFrameworkAdapter extends BotAdapter implements IUserTokenProvide
511
515
}
512
516
const serviceUrl : string = context . activity . serviceUrl ;
513
517
const conversationId : string = context . activity . conversation . id ;
514
- const client : ConnectorClient = this . createConnectorClient ( serviceUrl ) ;
518
+ const client : ConnectorClient = this . getOrCreateConnectorClient ( context , serviceUrl , this . credentials ) ;
515
519
await client . conversations . deleteConversationMember ( conversationId , memberId ) ;
516
520
}
517
521
@@ -542,7 +546,7 @@ export class BotFrameworkAdapter extends BotAdapter implements IUserTokenProvide
542
546
}
543
547
const serviceUrl : string = context . activity . serviceUrl ;
544
548
const conversationId : string = context . activity . conversation . id ;
545
- const client : ConnectorClient = this . createConnectorClient ( serviceUrl ) ;
549
+ const client : ConnectorClient = this . getOrCreateConnectorClient ( context , serviceUrl , this . credentials ) ;
546
550
547
551
return await client . conversations . getActivityMembers ( conversationId , activityId ) ;
548
552
}
@@ -569,7 +573,7 @@ export class BotFrameworkAdapter extends BotAdapter implements IUserTokenProvide
569
573
}
570
574
const serviceUrl : string = context . activity . serviceUrl ;
571
575
const conversationId : string = context . activity . conversation . id ;
572
- const client : ConnectorClient = this . createConnectorClient ( serviceUrl ) ;
576
+ const client : ConnectorClient = this . getOrCreateConnectorClient ( context , serviceUrl , this . credentials ) ;
573
577
574
578
return await client . conversations . getConversationMembers ( conversationId ) ;
575
579
}
@@ -599,8 +603,13 @@ export class BotFrameworkAdapter extends BotAdapter implements IUserTokenProvide
599
603
* `contextOrServiceUrl`.[activity](xref:botbuilder-core.TurnContext.activity).[serviceUrl](xref:botframework-schema.Activity.serviceUrl).
600
604
*/
601
605
public async getConversations ( contextOrServiceUrl : TurnContext | string , continuationToken ?: string ) : Promise < ConversationsResult > {
602
- const url : string = typeof contextOrServiceUrl === 'object' ? contextOrServiceUrl . activity . serviceUrl : contextOrServiceUrl ;
603
- const client : ConnectorClient = this . createConnectorClient ( url ) ;
606
+ let client : ConnectorClient ;
607
+ if ( typeof contextOrServiceUrl === 'object' ) {
608
+ const context : TurnContext = contextOrServiceUrl as TurnContext ;
609
+ client = this . getOrCreateConnectorClient ( context , context . activity . serviceUrl , this . credentials ) ;
610
+ } else {
611
+ client = this . createConnectorClient ( contextOrServiceUrl as string ) ;
612
+ }
604
613
605
614
return await client . conversations . getConversations ( continuationToken ? { continuationToken : continuationToken } : undefined ) ;
606
615
}
@@ -803,16 +812,16 @@ export class BotFrameworkAdapter extends BotAdapter implements IUserTokenProvide
803
812
// Authenticate the incoming request
804
813
status = 401 ;
805
814
const authHeader : string = req . headers . authorization || req . headers . Authorization || '' ;
806
- await this . authenticateRequest ( request , authHeader ) ;
807
815
808
816
const identity = await this . authenticateRequestInternal ( request , authHeader ) ;
809
817
810
818
// Process received activity
811
819
status = 500 ;
812
820
const context : TurnContext = this . createContext ( request ) ;
813
- context . turnState . set ( BotFrameworkAdapter . BotIdentityKey , identity ) ;
821
+ context . turnState . set ( this . BotIdentityKey , identity ) ;
814
822
const connectorClient = await this . createConnectorClientWithIdentity ( request . serviceUrl , identity ) ;
815
- context . turnState . set ( BotFrameworkAdapter . ConnectorClientKey , connectorClient ) ;
823
+ context . turnState . set ( this . ConnectorClientKey , connectorClient ) ;
824
+
816
825
context . turnState . set ( BotCallbackHandlerKey , logic ) ;
817
826
await this . runMiddleware ( context , logic ) ;
818
827
@@ -935,7 +944,7 @@ export class BotFrameworkAdapter extends BotAdapter implements IUserTokenProvide
935
944
if ( activity && BotFrameworkAdapter . isStreamingServiceUrl ( activity . serviceUrl ) ) {
936
945
TokenResolver . checkForOAuthCards ( this , context , activity as Activity ) ;
937
946
}
938
- const client : ConnectorClient = this . createConnectorClient ( activity . serviceUrl ) ;
947
+ const client = this . getOrCreateConnectorClient ( context , activity . serviceUrl , this . credentials ) ;
939
948
if ( activity . type === 'trace' && activity . channelId !== 'emulator' ) {
940
949
// Just eat activity
941
950
responses . push ( { } as ResourceResponse ) ;
@@ -976,7 +985,7 @@ export class BotFrameworkAdapter extends BotAdapter implements IUserTokenProvide
976
985
throw new Error ( `BotFrameworkAdapter.updateActivity(): missing conversation or conversation.id` ) ;
977
986
}
978
987
if ( ! activity . id ) { throw new Error ( `BotFrameworkAdapter.updateActivity(): missing activity.id` ) ; }
979
- const client : ConnectorClient = this . createConnectorClient ( activity . serviceUrl ) ;
988
+ const client : ConnectorClient = this . getOrCreateConnectorClient ( context , activity . serviceUrl , this . credentials ) ;
980
989
await client . conversations . updateActivity (
981
990
activity . conversation . id ,
982
991
activity . id ,
@@ -1063,6 +1072,26 @@ export class BotFrameworkAdapter extends BotAdapter implements IUserTokenProvide
1063
1072
return new ConnectorClient ( credentials , { baseUri : serviceUrl , userAgent : USER_AGENT } ) ;
1064
1073
}
1065
1074
1075
+ /**
1076
+ * @private
1077
+ * Retrieves the ConnectorClient from the TurnContext or creates a new ConnectorClient with the provided serviceUrl and credentials.
1078
+ * @param context
1079
+ * @param serviceUrl
1080
+ * @param credentials
1081
+ */
1082
+ private getOrCreateConnectorClient ( context : TurnContext , serviceUrl : string , credentials : AppCredentials ) : ConnectorClient {
1083
+ if ( ! context || ! context . turnState ) throw new Error ( 'invalid context parameter' ) ;
1084
+ if ( ! serviceUrl ) throw new Error ( 'invalid serviceUrl' ) ;
1085
+ if ( ! credentials ) throw new Error ( 'invalid credentials' ) ;
1086
+
1087
+ let client : ConnectorClient = context . turnState . get ( this . ConnectorClientKey ) ;
1088
+ if ( ! client ) {
1089
+ client = this . createConnectorClientInternal ( serviceUrl , credentials ) ;
1090
+ }
1091
+
1092
+ return client ;
1093
+ }
1094
+
1066
1095
/**
1067
1096
*
1068
1097
* @remarks
@@ -1073,7 +1102,7 @@ export class BotFrameworkAdapter extends BotAdapter implements IUserTokenProvide
1073
1102
// There is no cache for AppCredentials in JS as opposed to C#.
1074
1103
// Instead of retrieving an AppCredentials from the Adapter instance, generate a new one
1075
1104
const appPassword = await this . credentialsProvider . getAppPassword ( appId ) ;
1076
- return new MicrosoftAppCredentials ( appId , appPassword , oAuthScope ) ;
1105
+ return new MicrosoftAppCredentials ( appId , appPassword , undefined , oAuthScope ) ;
1077
1106
}
1078
1107
1079
1108
/**
0 commit comments