Skip to content
Draft
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
6 changes: 5 additions & 1 deletion core/src/Microsoft.Teams.Apps/TeamsBotApplication.cs
Original file line number Diff line number Diff line change
Expand Up @@ -124,14 +124,18 @@ public TeamsBotApplication(

Context<TeamsActivity> defaultContext = new(this, teamsActivity);

HttpContext? httpContext = httpContextAccessor.HttpContext;
if (teamsActivity.Type != TeamsActivityType.Invoke)
{
if (httpContext is not null)
{
await httpContext.Response.CompleteAsync().ConfigureAwait(false);
}
await Router.DispatchAsync(defaultContext, cancellationToken).ConfigureAwait(false);
}
else // invokes
{
InvokeResponse invokeResponse = await Router.DispatchWithReturnAsync(defaultContext, cancellationToken).ConfigureAwait(false);
HttpContext? httpContext = httpContextAccessor.HttpContext;
if (httpContext is not null && invokeResponse is not null)
{
httpContext.Response.StatusCode = invokeResponse.Status;
Expand Down
4 changes: 3 additions & 1 deletion core/src/Microsoft.Teams.Core/ConversationClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ public class ConversationClient(HttpClient httpClient, ILogger<ConversationClien

if (activity.ChannelId == "agents")
{
logger.TruncatingConversationId();
logger?.TruncatingConversationId();
string convId = "acf"; //conversationId.Length > 100 ? conversationId[..100] : conversationId;
url = $"{activity.ServiceUrl.ToString().TrimEnd('/')}/v3/conversations/{Uri.EscapeDataString(convId)}/activities/";
}
Expand All @@ -77,6 +77,8 @@ public class ConversationClient(HttpClient httpClient, ILogger<ConversationClien

string body = activity.ToJson();

logger?.SendingActivity(url);

return await _botHttpClient.SendAsync<SendActivityResponse>(
HttpMethod.Post,
url,
Expand Down
3 changes: 3 additions & 0 deletions core/src/Microsoft.Teams.Core/Log.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ internal static partial class Log
[LoggerMessage(EventId = 10, Level = LogLevel.Information, Message = "Truncating conversation ID for 'agents' channel to comply with length restrictions.")]
public static partial void TruncatingConversationId(this ILogger logger);

[LoggerMessage(EventId = 16, Level = LogLevel.Information, Message = "Sending activity to {Url}")]
public static partial void SendingActivity(this ILogger logger, string url);

[LoggerMessage(EventId = 11, Level = LogLevel.Trace, Message = "Updating activity at {Url}: {Activity}")]
public static partial void UpdatingActivity(this ILogger logger, string url, string activity);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,79 @@ public async Task SendActivityAsync_ConstructsCorrectUrl()
Assert.Equal(HttpMethod.Post, capturedRequest.Method);
}

[Fact]
public async Task SendActivityAsync_WithAgentsChannelId_UsesTruncatedConversationId()
{
HttpRequestMessage? capturedRequest = null;
Mock<HttpMessageHandler> mockHttpMessageHandler = new();
mockHttpMessageHandler
.Protected()
.Setup<Task<HttpResponseMessage>>(
"SendAsync",
ItExpr.IsAny<HttpRequestMessage>(),
ItExpr.IsAny<CancellationToken>())
.Callback<HttpRequestMessage, CancellationToken>((req, ct) => capturedRequest = req)
.ReturnsAsync(new HttpResponseMessage
{
StatusCode = HttpStatusCode.OK,
Content = new StringContent("{\"id\":\"activity123\"}")
});

HttpClient httpClient = new(mockHttpMessageHandler.Object);
ConversationClient conversationClient = new(httpClient);

CoreActivity activity = new()
{
Type = ActivityType.Message,
ChannelId = "agents",
ServiceUrl = new Uri("https://test.service.url/"),
Conversation = new("conv123")
};

await conversationClient.SendActivityAsync(activity);

Assert.NotNull(capturedRequest);
Assert.Equal("https://test.service.url/v3/conversations/acf/activities/", capturedRequest.RequestUri?.ToString());
}

[Fact]
public async Task SendActivityAsync_WithAgentsChannelIdAndIsTargeted_AppendsQueryString()
{
HttpRequestMessage? capturedRequest = null;
Mock<HttpMessageHandler> mockHttpMessageHandler = new();
mockHttpMessageHandler
.Protected()
.Setup<Task<HttpResponseMessage>>(
"SendAsync",
ItExpr.IsAny<HttpRequestMessage>(),
ItExpr.IsAny<CancellationToken>())
.Callback<HttpRequestMessage, CancellationToken>((req, ct) => capturedRequest = req)
.ReturnsAsync(new HttpResponseMessage
{
StatusCode = HttpStatusCode.OK,
Content = new StringContent("{\"id\":\"activity123\"}")
});

HttpClient httpClient = new(mockHttpMessageHandler.Object);
ConversationClient conversationClient = new(httpClient);

#pragma warning disable ExperimentalTeamsTargeted
CoreActivity activity = new()
{
Type = ActivityType.Message,
ChannelId = "agents",
ServiceUrl = new Uri("https://test.service.url/"),
Conversation = new("conv123"),
Recipient = new ConversationAccount { IsTargeted = true }
};
#pragma warning restore ExperimentalTeamsTargeted

await conversationClient.SendActivityAsync(activity);

Assert.NotNull(capturedRequest);
Assert.Equal("https://test.service.url/v3/conversations/acf/activities/?isTargetedActivity=true", capturedRequest.RequestUri?.ToString());
}

[Fact]
public async Task SendActivityAsync_WithIsTargeted_AppendsQueryString()
{
Expand Down
Loading