Skip to content
This repository was archived by the owner on Oct 3, 2025. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions libraries/Client/Conversations.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ namespace Microsoft.Bot.Connector.DirectLine
using Microsoft.Rest;
using Microsoft.Rest.Serialization;
using Newtonsoft.Json;

using System.Net.Http.Json;


/// <summary>
/// Conversations operations.
Expand Down Expand Up @@ -59,7 +60,7 @@ public Conversations(DirectLineClient client)
/// <return>
/// A response object containing the response body and response headers.
/// </return>
public async Task<HttpOperationResponse<Conversation>> StartConversationWithHttpMessagesAsync(Dictionary<string, List<string>> customHeaders = null, CancellationToken cancellationToken = default(CancellationToken))
public async Task<HttpOperationResponse<Conversation>> StartConversationWithHttpMessagesAsync(string siteId = null, Dictionary<string, List<string>> customHeaders = null, CancellationToken cancellationToken = default(CancellationToken))
{
// Tracing
bool _shouldTrace = ServiceClientTracing.IsEnabled;
Expand Down Expand Up @@ -92,6 +93,9 @@ public Conversations(DirectLineClient client)
}
}

// set request param
_httpRequest.Content = JsonContent.Create(new { SiteId = siteId });

// Serialize Request
string _requestContent = null;
// Set Credentials
Expand Down
7 changes: 4 additions & 3 deletions libraries/Client/ConversationsExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// Copyright (c) Microsoft. All rights reserved.

// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license.

// Code generated by Microsoft (R) AutoRest Code Generator 0.16.0.0
Expand Down Expand Up @@ -40,9 +41,9 @@ public static Conversation StartConversation(this IConversations operations)
/// <param name='cancellationToken'>
/// The cancellation token.
/// </param>
public static async Task<Conversation> StartConversationAsync(this IConversations operations, CancellationToken cancellationToken = default(CancellationToken))
public static async Task<Conversation> StartConversationAsync(this IConversations operations, string siteId = null, CancellationToken cancellationToken = default(CancellationToken))
{
using (var _result = await operations.StartConversationWithHttpMessagesAsync(null, cancellationToken).ConfigureAwait(false))
using (var _result = await operations.StartConversationWithHttpMessagesAsync(siteId, null, cancellationToken).ConfigureAwait(false))
{
return _result.Body;
}
Expand Down
2 changes: 1 addition & 1 deletion libraries/Client/IConversations.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public partial interface IConversations
/// <param name='cancellationToken'>
/// The cancellation token.
/// </param>
Task<HttpOperationResponse<Conversation>> StartConversationWithHttpMessagesAsync(Dictionary<string, List<string>> customHeaders = null, CancellationToken cancellationToken = default(CancellationToken));
Task<HttpOperationResponse<Conversation>> StartConversationWithHttpMessagesAsync(string siteId = null, Dictionary<string, List<string>> customHeaders = null, CancellationToken cancellationToken = default(CancellationToken));
/// <summary>
/// Get information about an existing conversation
/// </summary>
Expand Down
2 changes: 1 addition & 1 deletion libraries/Client/ITokens.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public partial interface ITokens
/// <param name='cancellationToken'>
/// The cancellation token.
/// </param>
Task<HttpOperationResponse<Conversation>> RefreshTokenWithHttpMessagesAsync(Dictionary<string, List<string>> customHeaders = null, CancellationToken cancellationToken = default(CancellationToken));
Task<HttpOperationResponse<Conversation>> RefreshTokenWithHttpMessagesAsync(Dictionary<string, List<string>> customHeaders = null, string conversationId = null, Func<Task<string>> tokenRefreshCallback = null, CancellationToken cancellationToken = default(CancellationToken));
/// <summary>
/// Generate a token for a new conversation
/// </summary>
Expand Down
24 changes: 22 additions & 2 deletions libraries/Client/Tokens.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,14 @@ public Tokens(DirectLineClient client)
/// <return>
/// A response object containing the response body and response headers.
/// </return>
public async Task<HttpOperationResponse<Conversation>> RefreshTokenWithHttpMessagesAsync(Dictionary<string, List<string>> customHeaders = null, CancellationToken cancellationToken = default(CancellationToken))
public async Task<HttpOperationResponse<Conversation>> RefreshTokenWithHttpMessagesAsync(Dictionary<string, List<string>> customHeaders = null, string conversationId = null, Func<Task<string>> tokenRefreshCallback = null, CancellationToken cancellationToken = default(CancellationToken))
{
var newToken = await tokenRefreshCallback();

// Tracing
bool _shouldTrace = ServiceClientTracing.IsEnabled;
string _invocationId = null;

if (_shouldTrace)
{
_invocationId = ServiceClientTracing.NextInvocationId.ToString();
Expand All @@ -73,7 +76,8 @@ public Tokens(DirectLineClient client)
}
// Construct URL
var _baseUrl = this.Client.BaseUri.AbsoluteUri;
var _url = new Uri(new Uri(_baseUrl + (_baseUrl.EndsWith("/") ? "" : "/")), "v3/directline/tokens/refresh").ToString();
var path = string .IsNullOrEmpty(newToken) || string.IsNullOrEmpty(conversationId) ? "v3/directline/tokens/refresh" : $"v3/directline/tokens/refresh/{conversationId}";
var _url = new Uri(new Uri(_baseUrl + (_baseUrl.EndsWith("/") ? "" : "/")), path).ToString();
// Create HTTP transport objects
HttpRequestMessage _httpRequest = new HttpRequestMessage();
HttpResponseMessage _httpResponse = null;
Expand All @@ -99,13 +103,20 @@ public Tokens(DirectLineClient client)
{
cancellationToken.ThrowIfCancellationRequested();
await this.Client.Credentials.ProcessHttpRequestAsync(_httpRequest, cancellationToken).ConfigureAwait(false);

}
// Send Request
if (_shouldTrace)
{
ServiceClientTracing.SendRequest(_invocationId, _httpRequest);
}
cancellationToken.ThrowIfCancellationRequested();

if (!(string.IsNullOrEmpty(newToken) || string.IsNullOrEmpty(conversationId)))
{
_httpRequest.Headers.TryAddWithoutValidation(TokensExtensions.Refresh_Token, newToken);
}

_httpResponse = await this.Client.HttpClient.SendAsync(_httpRequest, cancellationToken).ConfigureAwait(false);
if (_shouldTrace)
{
Expand Down Expand Up @@ -142,6 +153,15 @@ public Tokens(DirectLineClient client)
try
{
_result.Body = SafeJsonConvert.DeserializeObject<Conversation>(_responseContent, this.Client.DeserializationSettings);

var cc = this.Client.Credentials as DirectLineClientCredentials;

if(string.Equals(newToken, _result.Body.Token))
{
// Make the new token the new auth token from here on until next token refresh is called
cc.Authorization = _result.Body.Token;
}

}
catch (JsonException ex)
{
Expand Down
72 changes: 50 additions & 22 deletions libraries/Client/TokensExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,33 +20,61 @@ namespace Microsoft.Bot.Connector.DirectLine
/// </summary>
public static partial class TokensExtensions
{
/// <summary>
/// Refresh a token
/// </summary>
/// <param name='operations'>
/// The operations group for this extension method.
/// </param>
public static Conversation RefreshToken(this ITokens operations)
public static readonly string Refresh_Token = "Refresh-Token";

/// <summary>
/// Refresh a token
/// </summary>
/// <param name='operations'>
/// The operations group for this extension method.
/// </param>
public static Conversation RefreshToken(this ITokens operations)
{
return Task.Factory.StartNew(s => ((ITokens)s).RefreshTokenAsync(), operations, CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Default).Unwrap().GetAwaiter().GetResult();
}

/// <summary>
/// Refresh a token
/// </summary>
/// <param name='operations'>
/// The operations group for this extension method.
/// </param>
/// <param name='cancellationToken'>
/// The cancellation token.
/// </param>
public static async Task<Conversation> RefreshTokenAsync(this ITokens operations, CancellationToken cancellationToken = default(CancellationToken))
{
using (var _result = await operations.RefreshTokenWithHttpMessagesAsync(null, null, null, cancellationToken).ConfigureAwait(false))
{
return Task.Factory.StartNew(s => ((ITokens)s).RefreshTokenAsync(), operations, CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Default).Unwrap().GetAwaiter().GetResult();
return _result.Body;
}
}

/// <summary>
/// Refresh a token
/// </summary>
/// <param name='operations'>
/// The operations group for this extension method.
/// </param>
/// <param name='cancellationToken'>
/// The cancellation token.
/// </param>
public static async Task<Conversation> RefreshTokenAsync(this ITokens operations, CancellationToken cancellationToken = default(CancellationToken))
/// <summary>
/// Refresh a token
/// </summary>
/// <param name='operations'>
/// The operations group for this extension method.
/// </param>
/// <param name='refreshToken'>
/// The new AAD token used to continue a conversation.
/// </param>
/// <param name='conversationId'>
/// The conversationId of the conversation to be continued.
/// </param>
/// <param name='tokenRefreshCallback'>
/// A callback function to fetch an AAD token. Must return a token string.
/// </param>
/// <param name='cancellationToken'>
/// The cancellation token.
/// </param>
public static async Task<Conversation> RefreshTokenAsync(this ITokens operations, string conversationId, Func<Task<string>> tokenRefreshCallback = null, CancellationToken cancellationToken = default(CancellationToken))
{
using (var _result = await operations.RefreshTokenWithHttpMessagesAsync(null, conversationId, tokenRefreshCallback, cancellationToken).ConfigureAwait(false))
{
using (var _result = await operations.RefreshTokenWithHttpMessagesAsync(null, cancellationToken).ConfigureAwait(false))
{
return _result.Body;
}
return _result.Body;
}
}

/// <summary>
/// Generate a token for a new conversation
Expand Down
18 changes: 17 additions & 1 deletion libraries/DirectLineClientCredentials.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,15 @@ public class DirectLineClientCredentials : ServiceClientCredentials
#else
// .NET Core does not support System.Configuration API's.
private static Lazy<string> _secret = new Lazy<string>(() => null);
private static Lazy<string> _token = new Lazy<string>(() => null);
private static Lazy<string> _endpoint = new Lazy<string>(() => null);
#endif

public string Secret { get; private set; }

public string Authorization { get; private set; }
public string Token { get; private set; }

public string Authorization { get; internal set; }

public string Endpoint { get; protected set; }

Expand All @@ -44,6 +47,19 @@ public DirectLineClientCredentials(string secret = null, string endpoint = null)
this.Endpoint = endpoint ?? _endpoint.Value ?? "https://directline.botframework.com/";
}

/// <summary>
/// Create a new instance of the DirectLineClientCredentials class
/// </summary>
/// <param name="secret">default will come from Settings["DirectLineSecret"]</param>
/// <param name="token">default will come from Settings["AadToken"]</param>
public DirectLineClientCredentials(string secret, string token, string endpoint = null)
{
this.Secret = secret ?? _secret.Value;
this.Token = token ?? _token.Value;
this.Authorization = this.Secret ?? this.Token;
this.Endpoint = endpoint ?? _endpoint.Value ?? "https://directline.botframework.com/";
}

/// <summary>
/// Apply the credentials to the HTTP request.
/// </summary>
Expand Down
1 change: 1 addition & 0 deletions libraries/Microsoft.Bot.Connector.DirectLine.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,6 @@
<PackageReference Include="Microsoft.Bot.Streaming" Version="4.9.0" />
<PackageReference Include="Microsoft.Rest.ClientRuntime" Version="2.3.20" />
<PackageReference Include="System.Net.Http" Version="4.3.4" />
<PackageReference Include="System.Net.Http.Json" Version="6.0.0" />
</ItemGroup>
</Project>
21 changes: 18 additions & 3 deletions samples/core-DirectLine/DirectLineBot.sln
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.25420.1
# Visual Studio Version 16
VisualStudioVersion = 16.0.31910.167
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DirectLineBot", "DirectLineBot\DirectLineBot.csproj", "{A8BA1066-5695-4D71-ABB4-65E5A5E0C3D4}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DirectLineBot", "DirectLineBot\DirectLineBot.csproj", "{A8BA1066-5695-4D71-ABB4-65E5A5E0C3D4}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DirectLineSampleClient", "DirectLineClient\DirectLineSampleClient.csproj", "{10935995-5C58-438B-B5F0-FA94BEA2667F}"
EndProject
Expand All @@ -12,6 +12,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "README", "README", "{24EE8F
README.md = README.md
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Bot.Connector.DirectLine", "..\..\libraries\Microsoft.Bot.Connector.DirectLine.csproj", "{222A7014-9EA6-4CCB-8F1E-8DBAF58668CA}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DirectLineSampleAcuireTokenClient", "DirectLineClientAcquireToken\DirectLineSampleAcuireTokenClient.csproj", "{305A8431-1C17-4BF2-A0B6-8AC984D8F8AD}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -26,8 +30,19 @@ Global
{10935995-5C58-438B-B5F0-FA94BEA2667F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{10935995-5C58-438B-B5F0-FA94BEA2667F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{10935995-5C58-438B-B5F0-FA94BEA2667F}.Release|Any CPU.Build.0 = Release|Any CPU
{222A7014-9EA6-4CCB-8F1E-8DBAF58668CA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{222A7014-9EA6-4CCB-8F1E-8DBAF58668CA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{222A7014-9EA6-4CCB-8F1E-8DBAF58668CA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{222A7014-9EA6-4CCB-8F1E-8DBAF58668CA}.Release|Any CPU.Build.0 = Release|Any CPU
{305A8431-1C17-4BF2-A0B6-8AC984D8F8AD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{305A8431-1C17-4BF2-A0B6-8AC984D8F8AD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{305A8431-1C17-4BF2-A0B6-8AC984D8F8AD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{305A8431-1C17-4BF2-A0B6-8AC984D8F8AD}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {53F48480-F4AA-49AE-AE20-BB0564D0C452}
EndGlobalSection
EndGlobal
22 changes: 22 additions & 0 deletions samples/core-DirectLine/DirectLineClientAcquireToken/App.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings>
<add key="DirectLineSecret" value="YourBotDirectLineSecret" />
<add key="BotId" value="YourBotId" />
</appSettings>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
</startup>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-13.0.0.0" newVersion="13.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
Loading