microsoft/teams.net

Public

mirrored fromhttps://github.com/microsoft/teams.netAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
samples/migration-bot

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

core/src/Microsoft.Teams.Bot.Compat/CompatAdapter.cs

118lines · modecode

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4using Microsoft.AspNetCore.Http;
5using Microsoft.Bot.Builder;
6using Microsoft.Bot.Builder.Integration.AspNet.Core;
7using Microsoft.Bot.Schema;
8using Microsoft.Extensions.Logging;
9using Microsoft.Teams.Bot.Apps;
10using Microsoft.Teams.Bot.Core;
11using Microsoft.Teams.Bot.Core.Schema;
12
13
14namespace Microsoft.Teams.Bot.Compat;
15
16/// <summary>
17/// Provides a compatibility adapter for processing bot activities and HTTP requests using legacy middleware and bot
18/// framework interfaces.
19/// </summary>
20/// <remarks>Use this adapter to bridge between legacy bot framework middleware and newer bot application models.
21/// The adapter allows registration of middleware and error handling delegates, and supports processing HTTP requests
22/// and continuing conversations. Thread safety is not guaranteed; instances should not be shared across concurrent
23/// requests.</remarks>
24public class CompatAdapter : CompatBotAdapter, IBotFrameworkHttpAdapter
25{
26 private readonly TeamsBotApplication _teamsBotApplication;
27
28 /// <summary>
29 /// Creates a new instance of the <see cref="CompatAdapter"/> class.
30 /// </summary>
31 /// <param name="teamsBotApplication">The Teams bot application instance.</param>
32 /// <param name="httpContextAccessor">The HTTP context accessor.</param>
33 /// <param name="logger">The logger instance.</param>
34 public CompatAdapter(
35 TeamsBotApplication teamsBotApplication,
36 IHttpContextAccessor? httpContextAccessor = null,
37 ILogger? logger = null)
38 : base(teamsBotApplication, httpContextAccessor, logger)
39 {
40 _teamsBotApplication = teamsBotApplication;
41 }
42
43 /// <summary>
44 /// Processes an incoming HTTP request and generates an appropriate HTTP response using the provided bot instance.
45 /// </summary>
46 /// <param name="httpRequest">The incoming HTTP request containing the bot activity. Cannot be null.</param>
47 /// <param name="httpResponse">The HTTP response to write results to. Cannot be null.</param>
48 /// <param name="bot">The bot instance that will process the activity. Cannot be null.</param>
49 /// <param name="cancellationToken">A cancellation token that can be used to cancel the asynchronous operation.</param>
50 /// <returns>A task that represents the asynchronous processing operation.</returns>
51 public async Task ProcessAsync(HttpRequest httpRequest, HttpResponse httpResponse, IBot bot, CancellationToken cancellationToken = default)
52 {
53 ArgumentNullException.ThrowIfNull(httpRequest);
54 ArgumentNullException.ThrowIfNull(httpResponse);
55 ArgumentNullException.ThrowIfNull(bot);
56
57 CoreActivity? coreActivity = null;
58 _teamsBotApplication.OnActivity = async (activity, ct) =>
59 {
60 coreActivity = activity;
61 TurnContext turnContext = new(this, activity.ToCompatActivity());
62 turnContext.TurnState.Add<Microsoft.Bot.Connector.Authentication.UserTokenClient>(new CompatUserTokenClient(_teamsBotApplication.UserTokenClient));
63 CompatConnectorClient connectionClient = new(new CompatConversations(_teamsBotApplication.ConversationClient) { ServiceUrl = activity.ServiceUrl?.ToString() });
64 turnContext.TurnState.Add<Microsoft.Bot.Connector.IConnectorClient>(connectionClient);
65 turnContext.TurnState.Add<Microsoft.Teams.Bot.Apps.TeamsApiClient>(_teamsBotApplication.TeamsApiClient);
66 await MiddlewareSet.ReceiveActivityWithStatusAsync(turnContext, bot.OnTurnAsync, ct).ConfigureAwait(false);
67 };
68
69 try
70 {
71 await _teamsBotApplication.ProcessAsync(httpRequest.HttpContext, cancellationToken).ConfigureAwait(false);
72 }
73 catch (Exception ex)
74 {
75 if (OnTurnError != null)
76 {
77 if (ex is BotHandlerException aex)
78 {
79 coreActivity = aex.Activity;
80 using TurnContext turnContext = new(this, coreActivity!.ToCompatActivity());
81 await OnTurnError(turnContext, ex).ConfigureAwait(false);
82 }
83 else
84 {
85 throw;
86 }
87 }
88 else
89 {
90 throw;
91 }
92 }
93 }
94
95 /// <summary>
96 /// Continues an existing bot conversation by invoking the specified callback with the provided conversation
97 /// reference.
98 /// </summary>
99 /// <remarks>Use this method to resume a conversation at a specific point, such as in response to an event
100 /// or proactive message. The callback is executed within the context of the continued conversation.</remarks>
101 /// <param name="botId">The unique identifier of the bot participating in the conversation.</param>
102 /// <param name="reference">A reference to the conversation to continue. Must not be null.</param>
103 /// <param name="callback">A delegate that handles the bot logic for the continued conversation. The callback receives a turn context and
104 /// cancellation token.</param>
105 /// <param name="cancellationToken">A cancellation token that can be used to cancel the operation.</param>
106 /// <returns>A task that represents the asynchronous operation.</returns>
107 public async override Task ContinueConversationAsync(string botId, ConversationReference reference, BotCallbackHandler callback, CancellationToken cancellationToken)
108 {
109 ArgumentNullException.ThrowIfNull(reference);
110 ArgumentNullException.ThrowIfNull(callback);
111
112 using TurnContext turnContext = new(this, reference.GetContinuationActivity());
113 turnContext.TurnState.Add<Microsoft.Bot.Connector.Authentication.UserTokenClient>(new CompatUserTokenClient(_teamsBotApplication.UserTokenClient));
114 turnContext.TurnState.Add<Microsoft.Bot.Connector.IConnectorClient>(new CompatConnectorClient(new CompatConversations(_teamsBotApplication.ConversationClient) { ServiceUrl = reference.ServiceUrl }));
115 turnContext.TurnState.Add<Microsoft.Teams.Bot.Apps.TeamsApiClient>(_teamsBotApplication.TeamsApiClient);
116 await RunPipelineAsync(turnContext, callback, cancellationToken).ConfigureAwait(false);
117 }
118}
119