microsoft/teams.net

Public

mirrored from https://github.com/microsoft/teams.netAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
kavin/agents-sdk-interop

Branches

Tags

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

Clone

HTTPS

Download ZIP

core/src/Microsoft.Teams.Apps/Api/Clients/ApiClient.cs

164lines · modecode

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4using Microsoft.Extensions.DependencyInjection;
5using Microsoft.Extensions.Logging;
6using Microsoft.Teams.Core.Http;
7
8using CoreConversationClient = Microsoft.Teams.Core.ConversationClient;
9using CoreUserTokenClient = Microsoft.Teams.Core.UserTokenClient;
10
11namespace Microsoft.Teams.Apps.Api.Clients;
12
13/// <summary>
14/// Top-level API client that provides access to all Teams Bot API sub-clients.
15/// </summary>
16/// <remarks>
17/// <para>
18/// This client can be constructed in two ways:
19/// </para>
20/// <list type="bullet">
21/// <item><b>DI-friendly (no serviceUrl)</b> — Use <see cref="ApiClient(HttpClient, CoreConversationClient, CoreUserTokenClient, ILogger)"/>
22/// and call <see cref="ForServiceUrl"/> per-request to create a scoped instance.</item>
23/// <item><b>Fully initialized</b> — Use <see cref="ApiClient(Uri, HttpClient, CoreConversationClient, CoreUserTokenClient, ILogger)"/>
24/// when the service URL is known upfront.</item>
25/// </list>
26/// </remarks>
27public class ApiClient
28{
29 private readonly BotHttpClient _http;
30
31 internal CoreConversationClient ConversationClient { get; }
32
33 internal CoreUserTokenClient UserTokenClient { get; }
34
35 /// <summary>
36 /// The service URL used by this client.
37 /// Null when constructed without a service URL (DI-friendly constructor).
38 /// Call <see cref="ForServiceUrl"/> to create a scoped instance with a service URL.
39 /// </summary>
40 public virtual Uri ServiceUrl { get; }
41
42 /// <summary>
43 /// Client for bot-level operations (token, sign-in).
44 /// </summary>
45 public virtual BotClient Bots { get; }
46
47 /// <summary>
48 /// Client for conversation operations (activities, members, reactions).
49 /// </summary>
50 public virtual ConversationApiClient Conversations { get; }
51
52 /// <summary>
53 /// Client for user-level operations (token).
54 /// </summary>
55 public virtual UserClient Users { get; }
56
57 /// <summary>
58 /// Client for team operations.
59 /// </summary>
60 public virtual TeamClient Teams { get; }
61
62 /// <summary>
63 /// Client for meeting operations.
64 /// </summary>
65 public virtual MeetingClient Meetings { get; }
66
67 /// <summary>
68 /// Creates a new <see cref="ApiClient"/> without a service URL (DI-friendly).
69 /// Use <see cref="ForServiceUrl"/> to create a scoped instance bound to a specific service URL.
70 /// </summary>
71 /// <param name="httpClient">An <see cref="HttpClient"/> configured with authentication (e.g., via DI with <c>BotAuthenticationHandler</c>).</param>
72 /// <param name="conversationClient">The core conversation client for conversation/activity/member operations.</param>
73 /// <param name="userTokenClient">The core user token client for sign-in and token operations.</param>
74 /// <param name="logger">Optional logger.</param>
75 [ActivatorUtilitiesConstructor]
76 public ApiClient(HttpClient httpClient, CoreConversationClient conversationClient, CoreUserTokenClient userTokenClient, ILogger? logger = null)
77 {
78 ArgumentNullException.ThrowIfNull(httpClient);
79 ArgumentNullException.ThrowIfNull(conversationClient);
80 ArgumentNullException.ThrowIfNull(userTokenClient);
81
82 _http = new BotHttpClient(httpClient, logger);
83 ConversationClient = conversationClient;
84 UserTokenClient = userTokenClient;
85 Bots = new BotClient(userTokenClient);
86 Users = new UserClient(userTokenClient);
87
88 // ServiceUrl-dependent sub-clients require ForServiceUrl() before use
89 ServiceUrl = null!;
90 Conversations = null!;
91 Teams = null!;
92 Meetings = null!;
93 }
94
95 /// <summary>
96 /// Creates a new <see cref="ApiClient"/> bound to a specific service URL.
97 /// </summary>
98 /// <param name="serviceUrl">The Bot Framework service URL.</param>
99 /// <param name="httpClient">An <see cref="HttpClient"/> configured with authentication (e.g., via DI with <c>BotAuthenticationHandler</c>).</param>
100 /// <param name="conversationClient">The core conversation client for conversation/activity/member operations.</param>
101 /// <param name="userTokenClient">The core user token client for sign-in and token operations.</param>
102 /// <param name="logger">Optional logger.</param>
103 internal ApiClient(Uri serviceUrl, HttpClient httpClient, CoreConversationClient conversationClient, CoreUserTokenClient userTokenClient, ILogger? logger = null)
104 {
105 ArgumentNullException.ThrowIfNull(serviceUrl);
106 ArgumentNullException.ThrowIfNull(httpClient);
107 ArgumentNullException.ThrowIfNull(conversationClient);
108 ArgumentNullException.ThrowIfNull(userTokenClient);
109
110 _http = new BotHttpClient(httpClient, logger);
111 ConversationClient = conversationClient;
112 UserTokenClient = userTokenClient;
113 ServiceUrl = serviceUrl;
114 Bots = new BotClient(userTokenClient);
115 Conversations = new ConversationApiClient(serviceUrl, conversationClient);
116 Users = new UserClient(userTokenClient);
117 Teams = new TeamClient(serviceUrl.ToString(), _http);
118 Meetings = new MeetingClient(serviceUrl.ToString(), _http);
119 }
120
121 /// <summary>
122 /// Creates a copy of an existing <see cref="ApiClient"/> with the same configuration.
123 /// </summary>
124 internal ApiClient(ApiClient client)
125 {
126 ArgumentNullException.ThrowIfNull(client);
127
128 ServiceUrl = client.ServiceUrl;
129 _http = client._http;
130 ConversationClient = client.ConversationClient;
131 UserTokenClient = client.UserTokenClient;
132 Bots = client.Bots;
133 Conversations = client.Conversations;
134 Users = client.Users;
135 Teams = client.Teams;
136 Meetings = client.Meetings;
137 }
138
139 // Private constructor for ForServiceUrl — shares BotHttpClient, ConversationClient, and UserTokenClient
140 private ApiClient(BotHttpClient http, CoreConversationClient conversationClient, CoreUserTokenClient userTokenClient, Uri serviceUrl)
141 {
142 _http = http;
143 ConversationClient = conversationClient;
144 UserTokenClient = userTokenClient;
145 ServiceUrl = serviceUrl;
146 Bots = new BotClient(userTokenClient);
147 Conversations = new ConversationApiClient(serviceUrl, conversationClient);
148 Users = new UserClient(userTokenClient);
149 Teams = new TeamClient(serviceUrl.ToString(), http);
150 Meetings = new MeetingClient(serviceUrl.ToString(), http);
151 }
152
153 /// <summary>
154 /// Creates a new <see cref="ApiClient"/> scoped to the specified service URL,
155 /// sharing the underlying HTTP client and authentication.
156 /// </summary>
157 /// <param name="serviceUrl">The Bot Framework service URL for this scope.</param>
158 /// <returns>A new <see cref="ApiClient"/> bound to the given service URL.</returns>
159 public virtual ApiClient ForServiceUrl(Uri serviceUrl)
160 {
161 ArgumentNullException.ThrowIfNull(serviceUrl);
162 return new ApiClient(_http, ConversationClient, UserTokenClient, serviceUrl);
163 }
164}
165