microsoft/teams.net
Publicmirrored fromhttps://github.com/microsoft/teams.netAvailable
core/docs/Architecture.md
941lines · modecode
| 1 | # Teams Bot SDK Architecture Documentation |
| 2 | |
| 3 | ## Overview |
| 4 | |
| 5 | The Teams Bot SDK consists of three layered projects that provide a modern, efficient, and backward-compatible framework for building Microsoft Teams bots. |
| 6 | |
| 7 | ```mermaid |
| 8 | graph TB |
| 9 | subgraph "Application Layer" |
| 10 | UserBot[User Bot Application] |
| 11 | end |
| 12 | |
| 13 | subgraph "SDK Layers" |
| 14 | Compat[Microsoft.Teams.Apps.BotBuilder<br/>Bot Framework v4 Compatibility] |
| 15 | Apps[Microsoft.Teams.Apps<br/>Teams-Specific Features] |
| 16 | Core[Microsoft.Teams.Core<br/>Core Bot Infrastructure] |
| 17 | end |
| 18 | |
| 19 | subgraph "External Dependencies" |
| 20 | BotFramework[Bot Framework v4 SDK] |
| 21 | TeamsServices[Microsoft Teams Services] |
| 22 | end |
| 23 | |
| 24 | UserBot --> Compat |
| 25 | UserBot --> Apps |
| 26 | Compat --> Apps |
| 27 | Compat --> BotFramework |
| 28 | Apps --> Core |
| 29 | Core --> TeamsServices |
| 30 | |
| 31 | style Core fill:#e1f5ff |
| 32 | style Apps fill:#fff4e1 |
| 33 | style Compat fill:#ffe1f5 |
| 34 | ``` |
| 35 | |
| 36 | --- |
| 37 | |
| 38 | ## 1. Microsoft.Teams.Core |
| 39 | |
| 40 | **Purpose**: Provides the foundational infrastructure for building Teams bots with a clean, modern API focused on performance and System.Text.Json serialization. |
| 41 | |
| 42 | ### Architecture Overview |
| 43 | |
| 44 | ```mermaid |
| 45 | graph TB |
| 46 | subgraph "Core Components" |
| 47 | BotApp[BotApplication] |
| 48 | ConvClient[ConversationClient] |
| 49 | TokenClient[UserTokenClient] |
| 50 | HttpClient[BotHttpClient] |
| 51 | end |
| 52 | |
| 53 | subgraph "Schema Layer" |
| 54 | CoreActivity[CoreActivity] |
| 55 | AgenticId[AgenticIdentity] |
| 56 | ConvAccount[ConversationAccount] |
| 57 | JsonContext[CoreActivityJsonContext] |
| 58 | end |
| 59 | |
| 60 | subgraph "Middleware Pipeline" |
| 61 | TurnMW[TurnMiddleware] |
| 62 | CustomMW[ITurnMiddleware] |
| 63 | end |
| 64 | |
| 65 | subgraph "Hosting" |
| 66 | AuthHandler[BotAuthenticationHandler] |
| 67 | Extensions[AddBotApplicationExtensions] |
| 68 | Config[BotConfig] |
| 69 | end |
| 70 | |
| 71 | BotApp --> TurnMW |
| 72 | BotApp --> ConvClient |
| 73 | BotApp --> TokenClient |
| 74 | ConvClient --> HttpClient |
| 75 | TokenClient --> HttpClient |
| 76 | TurnMW --> CustomMW |
| 77 | BotApp --> CoreActivity |
| 78 | CoreActivity --> JsonContext |
| 79 | |
| 80 | style BotApp fill:#4a90e2 |
| 81 | style CoreActivity fill:#7ed321 |
| 82 | style TurnMW fill:#f5a623 |
| 83 | ``` |
| 84 | |
| 85 | ### Core Patterns |
| 86 | |
| 87 | #### 1. **Middleware Pipeline Pattern** |
| 88 | |
| 89 | The middleware pipeline allows processing activities through a chain of handlers. |
| 90 | |
| 91 | ```mermaid |
| 92 | sequenceDiagram |
| 93 | participant HTTP as HTTP Request |
| 94 | participant BotApp as BotApplication |
| 95 | participant Pipeline as TurnMiddleware |
| 96 | participant MW1 as Middleware 1 |
| 97 | participant MW2 as Middleware 2 |
| 98 | participant Handler as OnActivity Handler |
| 99 | |
| 100 | HTTP->>BotApp: ProcessAsync(HttpContext) |
| 101 | BotApp->>BotApp: Deserialize CoreActivity |
| 102 | BotApp->>Pipeline: RunPipelineAsync(activity) |
| 103 | Pipeline->>MW1: OnTurnAsync(activity, next) |
| 104 | MW1->>Pipeline: next(activity) |
| 105 | Pipeline->>MW2: OnTurnAsync(activity, next) |
| 106 | MW2->>Pipeline: next(activity) |
| 107 | Pipeline->>Handler: Invoke(activity) |
| 108 | Handler-->>Pipeline: Complete |
| 109 | Pipeline-->>BotApp: Complete |
| 110 | BotApp-->>HTTP: Response |
| 111 | ``` |
| 112 | |
| 113 | **Key Classes**: |
| 114 | - `TurnMiddleware`: Manages the middleware pipeline execution |
| 115 | - `ITurnMiddleware`: Interface for custom middleware components |
| 116 | - `BotApplication`: Orchestrates activity processing |
| 117 | |
| 118 | #### 2. **Client Pattern** |
| 119 | |
| 120 | Separate clients handle different aspects of bot communication. |
| 121 | |
| 122 | ```mermaid |
| 123 | graph LR |
| 124 | subgraph "Client Layer" |
| 125 | ConvClient[ConversationClient] |
| 126 | TokenClient[UserTokenClient] |
| 127 | end |
| 128 | |
| 129 | subgraph "HTTP Layer" |
| 130 | BotHttpClient[BotHttpClient] |
| 131 | RequestOpts[BotRequestOptions] |
| 132 | end |
| 133 | |
| 134 | subgraph "Services" |
| 135 | ConvAPI["/v3/conversations"] |
| 136 | TokenAPI["/api/usertoken"] |
| 137 | end |
| 138 | |
| 139 | ConvClient --> BotHttpClient |
| 140 | TokenClient --> BotHttpClient |
| 141 | BotHttpClient --> RequestOpts |
| 142 | BotHttpClient --> ConvAPI |
| 143 | BotHttpClient --> TokenAPI |
| 144 | |
| 145 | style ConvClient fill:#4a90e2 |
| 146 | style TokenClient fill:#4a90e2 |
| 147 | ``` |
| 148 | |
| 149 | **Key Features**: |
| 150 | - `ConversationClient`: Manages conversation operations (send, reply, get members) |
| 151 | - `UserTokenClient`: Handles OAuth token operations |
| 152 | - `BotHttpClient`: Centralized HTTP client with authentication and retry logic |
| 153 | - `BotRequestOptions`: Configures requests with authentication and custom headers |
| 154 | |
| 155 | #### 3. **Schema with Source Generation** |
| 156 | |
| 157 | Uses System.Text.Json source generators for optimal performance. |
| 158 | |
| 159 | ```csharp |
| 160 | [JsonSerializable(typeof(CoreActivity))] |
| 161 | [JsonSerializable(typeof(ConversationAccount))] |
| 162 | internal partial class CoreActivityJsonContext : JsonSerializerContext |
| 163 | { |
| 164 | } |
| 165 | ``` |
| 166 | |
| 167 | **Benefits**: |
| 168 | - Zero-allocation JSON serialization |
| 169 | - AOT (Ahead-of-Time) compilation support |
| 170 | - Faster startup time |
| 171 | - Smaller deployment size |
| 172 | |
| 173 | ### Key Components |
| 174 | |
| 175 | | Component | Purpose | Pattern | |
| 176 | |-----------|---------|---------| |
| 177 | | `BotApplication` | Main entry point for processing activities | Facade | |
| 178 | | `ConversationClient` | Manages conversation operations | Client | |
| 179 | | `UserTokenClient` | Handles user authentication tokens | Client | |
| 180 | | `BotHttpClient` | Centralized HTTP communication | Client | |
| 181 | | `TurnMiddleware` | Executes middleware pipeline | Chain of Responsibility | |
| 182 | | `CoreActivity` | Activity model with source generation | DTO | |
| 183 | | `AgenticIdentity` | Authentication identity for API calls | DTO | |
| 184 | | `BotAuthenticationHandler` | JWT authentication for ASP.NET Core | Authentication Handler | |
| 185 | |
| 186 | ### Configuration |
| 187 | |
| 188 | ```csharp |
| 189 | services.AddBotApplication(configuration); |
| 190 | // Registers: |
| 191 | // - BotApplication (Singleton) |
| 192 | // - ConversationClient (Singleton) |
| 193 | // - UserTokenClient (Singleton) |
| 194 | // - BotHttpClient (Singleton) |
| 195 | // - Authentication handlers |
| 196 | ``` |
| 197 | |
| 198 | --- |
| 199 | |
| 200 | ## 2. Microsoft.Teams.Apps |
| 201 | |
| 202 | **Purpose**: Extends Core with Teams-specific features, handlers, and the TeamsApiClient for advanced Teams operations. |
| 203 | |
| 204 | ### Architecture Overview |
| 205 | |
| 206 | ```mermaid |
| 207 | graph TB |
| 208 | subgraph "Application Layer" |
| 209 | TeamsBotApp[TeamsBotApplication] |
| 210 | Builder[TeamsBotApplicationBuilder] |
| 211 | end |
| 212 | |
| 213 | subgraph "Handler System" |
| 214 | MsgHandler[MessageHandler] |
| 215 | ConvHandler[ConversationUpdateHandler] |
| 216 | InvokeHandler[InvokeHandler] |
| 217 | InstallHandler[InstallationUpdateHandler] |
| 218 | ReactionHandler[MessageReactionHandler] |
| 219 | end |
| 220 | |
| 221 | subgraph "Teams API Client" |
| 222 | TeamsAPI[TeamsApiClient] |
| 223 | MeetingOps[Meeting Operations] |
| 224 | TeamOps[Team Operations] |
| 225 | BatchOps[Batch Operations] |
| 226 | end |
| 227 | |
| 228 | subgraph "Schema Layer" |
| 229 | TeamsActivity[TeamsActivity] |
| 230 | TeamsChannelData[TeamsChannelData] |
| 231 | TeamsAttachment[TeamsAttachment] |
| 232 | Entities[Entity Types] |
| 233 | end |
| 234 | |
| 235 | subgraph "Context" |
| 236 | Context[Context] |
| 237 | end |
| 238 | |
| 239 | TeamsBotApp --> TeamsAPI |
| 240 | TeamsBotApp --> MsgHandler |
| 241 | TeamsBotApp --> ConvHandler |
| 242 | TeamsBotApp --> InvokeHandler |
| 243 | TeamsBotApp --> InstallHandler |
| 244 | TeamsBotApp --> ReactionHandler |
| 245 | |
| 246 | MsgHandler --> Context |
| 247 | ConvHandler --> Context |
| 248 | InvokeHandler --> Context |
| 249 | |
| 250 | TeamsAPI --> MeetingOps |
| 251 | TeamsAPI --> TeamOps |
| 252 | TeamsAPI --> BatchOps |
| 253 | |
| 254 | TeamsBotApp --> TeamsActivity |
| 255 | TeamsActivity --> TeamsChannelData |
| 256 | |
| 257 | style TeamsBotApp fill:#5856d6 |
| 258 | style TeamsAPI fill:#ff9500 |
| 259 | style Context fill:#34c759 |
| 260 | ``` |
| 261 | |
| 262 | ### Core Patterns |
| 263 | |
| 264 | #### 1. **Handler Pattern with Typed Arguments** |
| 265 | |
| 266 | Teams-specific activities are routed to typed handlers. |
| 267 | |
| 268 | ```mermaid |
| 269 | sequenceDiagram |
| 270 | participant Core as BotApplication |
| 271 | participant Teams as TeamsBotApplication |
| 272 | participant Handler as MessageHandler |
| 273 | participant UserCode as User Handler |
| 274 | |
| 275 | Core->>Teams: OnActivity(CoreActivity) |
| 276 | Teams->>Teams: Convert to TeamsActivity |
| 277 | Teams->>Teams: Create Context |
| 278 | Teams->>Handler: Invoke(MessageArgs, Context) |
| 279 | Handler->>UserCode: Execute(args, context) |
| 280 | UserCode-->>Handler: Complete |
| 281 | Handler-->>Teams: Complete |
| 282 | Teams-->>Core: Complete |
| 283 | ``` |
| 284 | |
| 285 | **Handler Types**: |
| 286 | ```csharp |
| 287 | public delegate Task MessageHandler(MessageArgs args, Context context, CancellationToken ct); |
| 288 | public delegate Task ConversationUpdateHandler(ConversationUpdateArgs args, Context context, CancellationToken ct); |
| 289 | public delegate Task<CoreInvokeResponse> InvokeHandler(Context context, CancellationToken ct); |
| 290 | public delegate Task InstallationUpdateHandler(InstallationUpdateArgs args, Context context, CancellationToken ct); |
| 291 | public delegate Task MessageReactionHandler(MessageReactionArgs args, Context context, CancellationToken ct); |
| 292 | ``` |
| 293 | |
| 294 | #### 2. **Builder Pattern for Application Configuration** |
| 295 | |
| 296 | Fluent API for configuring Teams bot applications. |
| 297 | |
| 298 | ```mermaid |
| 299 | graph LR |
| 300 | Start[TeamsBotApplicationBuilder] --> OnMsg[OnMessage] |
| 301 | OnMsg --> OnConv[OnConversationUpdate] |
| 302 | OnConv --> OnInvoke[OnInvoke] |
| 303 | OnInvoke --> OnInstall[OnInstallationUpdate] |
| 304 | OnInstall --> OnReact[OnMessageReaction] |
| 305 | OnReact --> Build[Build] |
| 306 | Build --> App[TeamsBotApplication] |
| 307 | |
| 308 | style Start fill:#5856d6 |
| 309 | style App fill:#5856d6 |
| 310 | ``` |
| 311 | |
| 312 | **Usage**: |
| 313 | ```csharp |
| 314 | var builder = new TeamsBotApplicationBuilder() |
| 315 | .OnMessage(async (args, context, ct) => { |
| 316 | await context.SendActivityAsync("Hello!"); |
| 317 | }) |
| 318 | .OnConversationUpdate(async (args, context, ct) => { |
| 319 | // Handle member added/removed |
| 320 | }) |
| 321 | .OnInvoke(async (context, ct) => { |
| 322 | return new CoreInvokeResponse { Status = 200 }; |
| 323 | }); |
| 324 | |
| 325 | var app = builder.Build(services); |
| 326 | ``` |
| 327 | |
| 328 | #### 3. **Context Pattern** |
| 329 | |
| 330 | Provides a rich context object for bot operations. |
| 331 | |
| 332 | ```mermaid |
| 333 | graph TB |
| 334 | Context[Context] |
| 335 | |
| 336 | Context --> Activity[TeamsActivity] |
| 337 | Context --> BotApp[TeamsBotApplication] |
| 338 | Context --> Conv[ConversationClient] |
| 339 | Context --> Token[UserTokenClient] |
| 340 | Context --> Teams[TeamsApiClient] |
| 341 | |
| 342 | Context --> Send[SendActivityAsync] |
| 343 | Context --> Reply[ReplyAsync] |
| 344 | Context --> Update[UpdateActivityAsync] |
| 345 | Context --> Delete[DeleteActivityAsync] |
| 346 | |
| 347 | style Context fill:#34c759 |
| 348 | ``` |
| 349 | |
| 350 | **Key Features**: |
| 351 | - Encapsulates current activity and bot application |
| 352 | - Provides convenience methods for common operations |
| 353 | - Access to all clients (Conversation, Token, Teams) |
| 354 | - Simplified response methods |
| 355 | |
| 356 | #### 4. **Teams API Client Pattern** |
| 357 | |
| 358 | Specialized client for Teams-specific operations. |
| 359 | |
| 360 | ```mermaid |
| 361 | graph TB |
| 362 | subgraph "TeamsApiClient" |
| 363 | Client[TeamsApiClient] |
| 364 | end |
| 365 | |
| 366 | subgraph "Meeting Operations" |
| 367 | FetchMeeting[FetchMeetingInfoAsync] |
| 368 | FetchParticipant[FetchParticipantAsync] |
| 369 | SendNotification[SendMeetingNotificationAsync] |
| 370 | end |
| 371 | |
| 372 | subgraph "Team Operations" |
| 373 | FetchTeam[FetchTeamDetailsAsync] |
| 374 | FetchChannels[FetchChannelListAsync] |
| 375 | end |
| 376 | |
| 377 | subgraph "Batch Operations" |
| 378 | SendToUsers[SendMessageToListOfUsersAsync] |
| 379 | SendToChannels[SendMessageToListOfChannelsAsync] |
| 380 | SendToTeam[SendMessageToAllUsersInTeamAsync] |
| 381 | SendToTenant[SendMessageToAllUsersInTenantAsync] |
| 382 | GetOpState[GetOperationStateAsync] |
| 383 | GetFailed[GetPagedFailedEntriesAsync] |
| 384 | Cancel[CancelOperationAsync] |
| 385 | end |
| 386 | |
| 387 | Client --> FetchMeeting |
| 388 | Client --> FetchParticipant |
| 389 | Client --> SendNotification |
| 390 | Client --> FetchTeam |
| 391 | Client --> FetchChannels |
| 392 | Client --> SendToUsers |
| 393 | Client --> SendToChannels |
| 394 | Client --> SendToTeam |
| 395 | Client --> SendToTenant |
| 396 | Client --> GetOpState |
| 397 | Client --> GetFailed |
| 398 | Client --> Cancel |
| 399 | |
| 400 | style Client fill:#ff9500 |
| 401 | ``` |
| 402 | |
| 403 | ### Key Components |
| 404 | |
| 405 | | Component | Purpose | Pattern | |
| 406 | |-----------|---------|---------| |
| 407 | | `TeamsBotApplication` | Teams-specific bot application | Specialization | |
| 408 | | `TeamsBotApplicationBuilder` | Fluent configuration API | Builder | |
| 409 | | `TeamsApiClient` | Teams-specific API operations | Client | |
| 410 | | `Context` | Rich context for handlers | Context Object | |
| 411 | | `TeamsActivity` | Teams-enhanced activity model | DTO | |
| 412 | | `MessageHandler` | Delegate for message handling | Handler | |
| 413 | | `ConversationUpdateHandler` | Delegate for conversation updates | Handler | |
| 414 | | `InvokeHandler` | Delegate for invoke activities | Handler | |
| 415 | | `TeamsChannelData` | Teams-specific channel data | DTO | |
| 416 | | `Entity` | Base class for activity entities | DTO | |
| 417 | |
| 418 | ### REST API Endpoints |
| 419 | |
| 420 | | Operation | Endpoint | Description | |
| 421 | |-----------|----------|-------------| |
| 422 | | Meeting Info | `GET /v1/meetings/{meetingId}` | Get meeting details | |
| 423 | | Participant | `GET /v1/meetings/{meetingId}/participants/{participantId}` | Get participant info | |
| 424 | | Notification | `POST /v1/meetings/{meetingId}/notification` | Send in-meeting notification | |
| 425 | | Team Details | `GET /v3/teams/{teamId}` | Get team information | |
| 426 | | Channels | `GET /v3/teams/{teamId}/channels` | List team channels | |
| 427 | | Batch Users | `POST /v3/batch/conversation/users/` | Message multiple users | |
| 428 | | Batch Channels | `POST /v3/batch/conversation/channels/` | Message multiple channels | |
| 429 | | Batch Team | `POST /v3/batch/conversation/team/` | Message all team members | |
| 430 | | Batch Tenant | `POST /v3/batch/conversation/tenant/` | Message entire tenant | |
| 431 | | Operation State | `GET /v3/batch/conversation/{operationId}` | Get batch operation status | |
| 432 | | Failed Entries | `GET /v3/batch/conversation/failedentries/{operationId}` | Get failed batch entries | |
| 433 | | Cancel Operation | `DELETE /v3/batch/conversation/{operationId}` | Cancel batch operation | |
| 434 | |
| 435 | ### Configuration |
| 436 | |
| 437 | ```csharp |
| 438 | services.AddTeamsBotApplication(configuration); |
| 439 | // Registers everything from Core plus: |
| 440 | // - TeamsBotApplication (Singleton) |
| 441 | // - TeamsApiClient (Singleton) |
| 442 | // - IHttpContextAccessor |
| 443 | ``` |
| 444 | |
| 445 | --- |
| 446 | |
| 447 | ## 3. Microsoft.Teams.Apps.BotBuilder |
| 448 | |
| 449 | **Purpose**: Provides backward compatibility with Bot Framework v4 SDK, allowing existing bots to migrate incrementally to the new Teams SDK. |
| 450 | |
| 451 | ### Architecture Overview |
| 452 | |
| 453 | ```mermaid |
| 454 | graph TB |
| 455 | subgraph "Compatibility Layer" |
| 456 | TeamsBotFrameworkHttpAdapter[TeamsBotFrameworkHttpAdapter] |
| 457 | TeamsBotAdapter[TeamsBotAdapter] |
| 458 | CompatMiddleware[CompatAdapterMiddleware] |
| 459 | end |
| 460 | |
| 461 | subgraph "Client Adapters" |
| 462 | CompatConnector[CompatConnectorClient] |
| 463 | CompatConversations[CompatConversations] |
| 464 | CompatUserToken[CompatUserTokenClient] |
| 465 | end |
| 466 | |
| 467 | subgraph "Static Helpers" |
| 468 | TeamsApiClient[TeamsApiClient] |
| 469 | ActivitySchemaMapper[ActivitySchemaMapper Extensions] |
| 470 | end |
| 471 | |
| 472 | subgraph "Bot Framework v4" |
| 473 | BFAdapter[IBotFrameworkHttpAdapter] |
| 474 | BFBot[IBot] |
| 475 | BFMiddleware[IMiddleware] |
| 476 | TurnContext[ITurnContext] |
| 477 | end |
| 478 | |
| 479 | subgraph "Teams SDK" |
| 480 | TeamsBotApp[TeamsBotApplication] |
| 481 | ConvClient[ConversationClient] |
| 482 | TokenClient[UserTokenClient] |
| 483 | TeamsAPI[TeamsApiClient] |
| 484 | end |
| 485 | |
| 486 | TeamsBotFrameworkHttpAdapter -.implements.-> BFAdapter |
| 487 | CompatMiddleware -.implements.-> ITurnMiddleware |
| 488 | |
| 489 | TeamsBotFrameworkHttpAdapter --> TeamsBotApp |
| 490 | TeamsBotFrameworkHttpAdapter --> TeamsBotAdapter |
| 491 | TeamsBotFrameworkHttpAdapter --> CompatMiddleware |
| 492 | |
| 493 | CompatConnector --> CompatConversations |
| 494 | CompatConversations --> ConvClient |
| 495 | CompatUserToken --> TokenClient |
| 496 | |
| 497 | TeamsApiClient --> ConvClient |
| 498 | TeamsApiClient --> TeamsAPI |
| 499 | TeamsApiClient --> ActivitySchemaMapper |
| 500 | |
| 501 | BFBot --> TurnContext |
| 502 | TurnContext --> CompatConnector |
| 503 | |
| 504 | style TeamsBotFrameworkHttpAdapter fill:#ff2d55 |
| 505 | style TeamsApiClient fill:#ff2d55 |
| 506 | ``` |
| 507 | |
| 508 | ### Core Patterns |
| 509 | |
| 510 | #### 1. **Adapter Pattern** |
| 511 | |
| 512 | Bridges Bot Framework v4 interfaces to Teams SDK implementations. |
| 513 | |
| 514 | ```mermaid |
| 515 | sequenceDiagram |
| 516 | participant BF as Bot Framework Bot (IBot) |
| 517 | participant Adapter as TeamsBotFrameworkHttpAdapter |
| 518 | participant Core as TeamsBotApplication |
| 519 | participant Handler as User Handler |
| 520 | |
| 521 | BF->>Adapter: ProcessAsync(request, response) |
| 522 | Adapter->>Adapter: Register OnActivity handler |
| 523 | Adapter->>Core: ProcessAsync(HttpContext) |
| 524 | Core->>Core: Process CoreActivity |
| 525 | Core->>Adapter: OnActivity callback |
| 526 | Adapter->>Adapter: Convert CoreActivity to Activity |
| 527 | Adapter->>Adapter: Create TurnContext |
| 528 | Adapter->>Adapter: Add clients to TurnState |
| 529 | Adapter->>BF: bot.OnTurnAsync(turnContext) |
| 530 | BF->>Handler: User code executes |
| 531 | Handler-->>BF: Complete |
| 532 | BF-->>Adapter: Complete |
| 533 | Adapter-->>Core: Complete |
| 534 | ``` |
| 535 | |
| 536 | **Key Adaptations**: |
| 537 | - `IBotFrameworkHttpAdapter` → `TeamsBotApplication` |
| 538 | - `IBot.OnTurnAsync` → `BotApplication.OnActivity` |
| 539 | - `ITurnContext` → `CoreActivity` |
| 540 | - `IConnectorClient` → `ConversationClient` |
| 541 | - `UserTokenClient` → `UserTokenClient` |
| 542 | |
| 543 | #### 2. **Wrapper Pattern for Clients** |
| 544 | |
| 545 | Wraps Core SDK clients to implement Bot Framework v4 interfaces. |
| 546 | |
| 547 | ```mermaid |
| 548 | graph TB |
| 549 | subgraph "Bot Framework Interfaces" |
| 550 | IConnector[IConnectorClient] |
| 551 | IConversations[IConversations] |
| 552 | IUserToken[UserTokenClient BF] |
| 553 | end |
| 554 | |
| 555 | subgraph "Compatibility Wrappers" |
| 556 | CompatConn[CompatConnectorClient] |
| 557 | CompatConv[CompatConversations] |
| 558 | CompatToken[CompatUserTokenClient] |
| 559 | end |
| 560 | |
| 561 | subgraph "Core SDK Clients" |
| 562 | ConvClient[ConversationClient] |
| 563 | TokenClient[UserTokenClient] |
| 564 | end |
| 565 | |
| 566 | CompatConn -.implements.-> IConnector |
| 567 | CompatConv -.implements.-> IConversations |
| 568 | CompatToken -.implements.-> IUserToken |
| 569 | |
| 570 | CompatConn --> CompatConv |
| 571 | CompatConv --> ConvClient |
| 572 | CompatToken --> TokenClient |
| 573 | |
| 574 | style CompatConn fill:#ff3b30 |
| 575 | style CompatConv fill:#ff3b30 |
| 576 | style CompatToken fill:#ff3b30 |
| 577 | ``` |
| 578 | |
| 579 | #### 3. **Static Helper Adaptation Pattern** |
| 580 | |
| 581 | Replicates Bot Framework TeamsInfo static methods using Core SDK. |
| 582 | |
| 583 | ```mermaid |
| 584 | graph LR |
| 585 | subgraph "Bot Framework v4" |
| 586 | TeamsInfo[TeamsInfo static class] |
| 587 | end |
| 588 | |
| 589 | subgraph "Compatibility Layer" |
| 590 | TeamsApiClient[TeamsApiClient static class] |
| 591 | Conversions[ActivitySchemaMapper Extensions] |
| 592 | end |
| 593 | |
| 594 | subgraph "Core SDK" |
| 595 | ConvClient[ConversationClient] |
| 596 | TeamsAPI[TeamsApiClient] |
| 597 | end |
| 598 | |
| 599 | TeamsInfo -.replicated by.-> TeamsApiClient |
| 600 | |
| 601 | TeamsApiClient --> ConvClient |
| 602 | TeamsApiClient --> TeamsAPI |
| 603 | TeamsApiClient --> Conversions |
| 604 | |
| 605 | Conversions --> JSONRoundTrip["JSON Round-Trip Serialization"] |
| 606 | Conversions --> DirectMap["Direct Property Mapping"] |
| 607 | |
| 608 | style TeamsApiClient fill:#ff9500 |
| 609 | ``` |
| 610 | |
| 611 | **Key Methods** (19 total): |
| 612 | - Member operations: GetMemberAsync, GetPagedMembersAsync, etc. |
| 613 | - Meeting operations: GetMeetingInfoAsync, SendMeetingNotificationAsync |
| 614 | - Team operations: GetTeamDetailsAsync, GetTeamChannelsAsync |
| 615 | - Batch operations: SendMessageToListOfUsersAsync, GetOperationStateAsync |
| 616 | |
| 617 | #### 4. **Middleware Bridge Pattern** |
| 618 | |
| 619 | Allows Bot Framework middleware to work with Core SDK middleware pipeline. |
| 620 | |
| 621 | ```mermaid |
| 622 | sequenceDiagram |
| 623 | participant Core as Core Pipeline |
| 624 | participant Bridge as CompatAdapterMiddleware |
| 625 | participant BFMiddleware as Bot Framework Middleware |
| 626 | participant Next as Next Handler |
| 627 | |
| 628 | Core->>Bridge: OnTurnAsync(activity, next) |
| 629 | Bridge->>Bridge: Convert CoreActivity to Activity |
| 630 | Bridge->>Bridge: Create TurnContext |
| 631 | Bridge->>BFMiddleware: OnTurnAsync(turnContext, nextDelegate) |
| 632 | BFMiddleware->>Next: nextDelegate() |
| 633 | Next-->>BFMiddleware: Complete |
| 634 | BFMiddleware-->>Bridge: Complete |
| 635 | Bridge->>Core: await next(activity) |
| 636 | Core-->>Bridge: Complete |
| 637 | ``` |
| 638 | |
| 639 | #### 5. **Model Conversion Pattern** |
| 640 | |
| 641 | Two strategies for converting between Bot Framework and Core models: |
| 642 | |
| 643 | **Strategy 1: Direct Property Mapping** |
| 644 | ```csharp |
| 645 | public static TeamsChannelAccount ToCompatTeamsChannelAccount( |
| 646 | this TeamsConversationAccount account) |
| 647 | { |
| 648 | return new TeamsChannelAccount |
| 649 | { |
| 650 | Id = account.Id, |
| 651 | Name = account.Name, |
| 652 | AadObjectId = account.AadObjectId, |
| 653 | Email = account.Email, |
| 654 | GivenName = account.GivenName, |
| 655 | Surname = account.Surname, |
| 656 | UserPrincipalName = account.UserPrincipalName, |
| 657 | UserRole = account.UserRole, |
| 658 | TenantId = account.TenantId |
| 659 | }; |
| 660 | } |
| 661 | ``` |
| 662 | |
| 663 | **Strategy 2: JSON Round-Trip** (for complex models) |
| 664 | ```csharp |
| 665 | public static TeamDetails ToCompatTeamDetails(this Apps.TeamDetails teamDetails) |
| 666 | { |
| 667 | var json = System.Text.Json.JsonSerializer.Serialize(teamDetails); |
| 668 | return Newtonsoft.Json.JsonConvert.DeserializeObject<TeamDetails>(json)!; |
| 669 | } |
| 670 | ``` |
| 671 | |
| 672 | ### Key Components |
| 673 | |
| 674 | | Component | Purpose | Pattern | |
| 675 | |-----------|---------|---------| |
| 676 | | `TeamsBotFrameworkHttpAdapter` | Main adapter implementing Bot Framework interface | Adapter | |
| 677 | | `TeamsBotAdapter` | Base adapter for turn context creation | Adapter | |
| 678 | | `CompatConnectorClient` | Wraps connector client functionality | Wrapper | |
| 679 | | `CompatConversations` | Wraps conversation operations | Wrapper | |
| 680 | | `CompatUserTokenClient` | Wraps token client functionality | Wrapper | |
| 681 | | `CompatAdapterMiddleware` | Bridges middleware systems | Bridge | |
| 682 | | `TeamsApiClient` | Static helper methods for Teams operations | Static Helper | |
| 683 | | `ActivitySchemaMapper` | Extension methods for model conversion | Extension Methods | |
| 684 | |
| 685 | ### Migration Path |
| 686 | |
| 687 | ```mermaid |
| 688 | graph LR |
| 689 | subgraph Phase1["Phase 1: Drop-in Replacement"] |
| 690 | BFBot1[Existing Bot Framework Bot] |
| 691 | AddAdapter1[services.AddTeamsBotFrameworkHttpAdapter] |
| 692 | BFBot1 --> AddAdapter1 |
| 693 | end |
| 694 | |
| 695 | subgraph Phase2["Phase 2: Incremental Migration"] |
| 696 | BFBot2[Mixed Usage] |
| 697 | UseCore[Use Core SDK for new features] |
| 698 | KeepBF[Keep BF code for existing] |
| 699 | BFBot2 --> UseCore |
| 700 | BFBot2 --> KeepBF |
| 701 | end |
| 702 | |
| 703 | subgraph Phase3["Phase 3: Full Migration"] |
| 704 | CoreBot[Pure Teams SDK Bot] |
| 705 | TeamsBotApp[TeamsBotApplication] |
| 706 | Handlers[Typed Handlers] |
| 707 | CoreBot --> TeamsBotApp |
| 708 | CoreBot --> Handlers |
| 709 | end |
| 710 | |
| 711 | AddAdapter1 -.Next Phase.-> BFBot2 |
| 712 | KeepBF -.Next Phase.-> CoreBot |
| 713 | |
| 714 | style Phase1 fill:#ff3b30 |
| 715 | style Phase2 fill:#ff9500 |
| 716 | style Phase3 fill:#34c759 |
| 717 | ``` |
| 718 | |
| 719 | ### Configuration |
| 720 | |
| 721 | ```csharp |
| 722 | services.AddTeamsBotFrameworkHttpAdapter(configuration); |
| 723 | // Registers everything from Apps plus: |
| 724 | // - TeamsBotFrameworkHttpAdapter as IBotFrameworkHttpAdapter (Singleton) |
| 725 | // - TeamsBotAdapter (Singleton) |
| 726 | ``` |
| 727 | |
| 728 | --- |
| 729 | |
| 730 | ## Cross-Cutting Patterns |
| 731 | |
| 732 | ### 1. **Dependency Injection Pattern** |
| 733 | |
| 734 | All three projects use ASP.NET Core DI extensively. |
| 735 | |
| 736 | ```mermaid |
| 737 | graph TB |
| 738 | subgraph "DI Container" |
| 739 | Services[IServiceCollection] |
| 740 | end |
| 741 | |
| 742 | subgraph "Core Registrations" |
| 743 | BotApp[BotApplication] |
| 744 | ConvClient[ConversationClient] |
| 745 | TokenClient[UserTokenClient] |
| 746 | HttpClient[BotHttpClient] |
| 747 | end |
| 748 | |
| 749 | subgraph "Apps Registrations" |
| 750 | TeamsBotApp[TeamsBotApplication] |
| 751 | TeamsAPI[TeamsApiClient] |
| 752 | HttpCtx[IHttpContextAccessor] |
| 753 | end |
| 754 | |
| 755 | subgraph "Compat Registrations" |
| 756 | Adapter[TeamsBotFrameworkHttpAdapter] |
| 757 | BotAdapter[TeamsBotAdapter] |
| 758 | end |
| 759 | |
| 760 | Services --> BotApp |
| 761 | Services --> ConvClient |
| 762 | Services --> TokenClient |
| 763 | Services --> HttpClient |
| 764 | Services --> TeamsBotApp |
| 765 | Services --> TeamsAPI |
| 766 | Services --> HttpCtx |
| 767 | Services --> Adapter |
| 768 | Services --> BotAdapter |
| 769 | |
| 770 | TeamsBotApp -.extends.-> BotApp |
| 771 | Adapter -.uses.-> TeamsBotApp |
| 772 | ``` |
| 773 | |
| 774 | ### 2. **Configuration Pattern** |
| 775 | |
| 776 | Hierarchical configuration with conventions. |
| 777 | |
| 778 | ```json |
| 779 | { |
| 780 | "AzureAd": { |
| 781 | "TenantId": "...", |
| 782 | "ClientId": "...", |
| 783 | "ClientCredentials": [ |
| 784 | { |
| 785 | "SourceType": "ClientSecret", |
| 786 | "ClientSecret": "..." |
| 787 | } |
| 788 | ] |
| 789 | } |
| 790 | } |
| 791 | ``` |
| 792 | |
| 793 | **Configuration Sources** (standard ASP.NET Core resolution order, lowest to highest priority): |
| 794 | 1. `appsettings.json` |
| 795 | 2. `appsettings.{Environment}.json` |
| 796 | 3. User Secrets (Development environment only) |
| 797 | 4. Environment variables (e.g. `AzureAd__ClientId`) |
| 798 | 5. Command-line arguments |
| 799 | |
| 800 | ### 3. **Authentication Pattern** |
| 801 | |
| 802 | JWT bearer token authentication for API calls. |
| 803 | |
| 804 | ```mermaid |
| 805 | sequenceDiagram |
| 806 | participant Client as Bot Client |
| 807 | participant Auth as BotAuthenticationHandler |
| 808 | participant AAD as Azure AD |
| 809 | participant API as Teams API |
| 810 | |
| 811 | Client->>Auth: Request with credentials |
| 812 | Auth->>AAD: Get access token |
| 813 | AAD-->>Auth: JWT token |
| 814 | Auth->>Auth: Add Authorization header |
| 815 | Auth->>API: Request with Bearer token |
| 816 | API-->>Auth: Response |
| 817 | Auth-->>Client: Response |
| 818 | ``` |
| 819 | |
| 820 | ### 4. **Error Handling Pattern** |
| 821 | |
| 822 | Structured exception handling with custom exceptions. |
| 823 | |
| 824 | ```csharp |
| 825 | public class BotHandlerException : Exception |
| 826 | { |
| 827 | public CoreActivity Activity { get; } |
| 828 | public BotHandlerException(CoreActivity activity, string message, Exception? innerException) |
| 829 | : base(message, innerException) |
| 830 | { |
| 831 | Activity = activity; |
| 832 | } |
| 833 | } |
| 834 | ``` |
| 835 | |
| 836 | ### 5. **Logging Pattern** |
| 837 | |
| 838 | Structured logging with scopes and log levels. |
| 839 | |
| 840 | ```csharp |
| 841 | using (_logger.BeginScope("Processing activity {Type} {Id}", activity.Type, activity.Id)) |
| 842 | { |
| 843 | _logger.LogInformation("Processing activity {Type}", activity.Type); |
| 844 | _logger.LogTrace("Activity details: {Activity}", activity.ToJson()); |
| 845 | } |
| 846 | ``` |
| 847 | |
| 848 | --- |
| 849 | |
| 850 | ## Performance Considerations |
| 851 | |
| 852 | ### 1. **System.Text.Json Source Generation** |
| 853 | |
| 854 | - **Core SDK**: Uses source-generated JSON serializers for zero-allocation deserialization |
| 855 | - **AOT Ready**: Supports ahead-of-time compilation |
| 856 | - **Performance**: 2-3x faster than reflection-based serialization |
| 857 | |
| 858 | ### 2. **Object Pooling** |
| 859 | |
| 860 | - Reuses objects where possible to reduce GC pressure |
| 861 | - Particularly important for high-throughput scenarios |
| 862 | |
| 863 | ### 3. **Async/Await Best Practices** |
| 864 | |
| 865 | - ConfigureAwait(false) used throughout to avoid context switching |
| 866 | - Cancellation token support for graceful shutdown |
| 867 | - ValueTask for hot paths where appropriate |
| 868 | |
| 869 | ### 4. **Minimal Allocations** |
| 870 | |
| 871 | - Uses Span<T> and Memory<T> where applicable |
| 872 | - Avoids unnecessary string allocations |
| 873 | - Lazy initialization of expensive resources |
| 874 | |
| 875 | --- |
| 876 | |
| 877 | ## Testing Strategy |
| 878 | |
| 879 | ```mermaid |
| 880 | graph TB |
| 881 | subgraph "Test Levels" |
| 882 | Unit[Unit Tests] |
| 883 | Integration[Integration Tests] |
| 884 | E2E[End-to-End Tests] |
| 885 | end |
| 886 | |
| 887 | subgraph "Test Projects" |
| 888 | CoreTests[Microsoft.Teams.Core.UnitTests] |
| 889 | AppsTests[Microsoft.Teams.Apps.UnitTests] |
| 890 | CompatTests[Microsoft.Teams.Apps.BotBuilder.UnitTests] |
| 891 | IntTests[Microsoft.Teams.Core.Tests] |
| 892 | end |
| 893 | |
| 894 | Unit --> CoreTests |
| 895 | Unit --> AppsTests |
| 896 | Unit --> CompatTests |
| 897 | |
| 898 | Integration --> IntTests |
| 899 | |
| 900 | style Unit fill:#34c759 |
| 901 | style Integration fill:#ff9500 |
| 902 | style E2E fill:#ff3b30 |
| 903 | ``` |
| 904 | |
| 905 | ### Test Patterns |
| 906 | |
| 907 | 1. **Unit Tests**: Mock dependencies, test in isolation |
| 908 | 2. **Integration Tests**: Test with live services (requires credentials) |
| 909 | 3. **Compatibility Tests**: Verify Bot Framework v4 compatibility |
| 910 | |
| 911 | --- |
| 912 | |
| 913 | ## Summary |
| 914 | |
| 915 | ### Design Principles |
| 916 | |
| 917 | 1. **Separation of Concerns**: Clear layering with distinct responsibilities |
| 918 | 2. **Dependency Inversion**: Depend on abstractions, not implementations |
| 919 | 3. **Single Responsibility**: Each class has one reason to change |
| 920 | 4. **Open/Closed**: Open for extension, closed for modification |
| 921 | 5. **Performance First**: Optimized for high-throughput scenarios |
| 922 | 6. **Backward Compatibility**: Smooth migration path from Bot Framework v4 |
| 923 | |
| 924 | ### Key Takeaways |
| 925 | |
| 926 | | Layer | Primary Pattern | Main Benefit | |
| 927 | |-------|----------------|--------------| |
| 928 | | **Core** | Middleware Pipeline | Extensible activity processing | |
| 929 | | **Apps** | Handler Pattern | Type-safe Teams-specific routing | |
| 930 | | **Compat** | Adapter Pattern | Seamless migration from Bot Framework v4 | |
| 931 | |
| 932 | ### Evolution Path |
| 933 | |
| 934 | ```mermaid |
| 935 | timeline |
| 936 | title SDK Evolution |
| 937 | Phase 1 (Current) : Bot Framework v4 with Compat layer |
| 938 | Phase 2 (Transition) : Mixed usage - Core for new features |
| 939 | Phase 3 (Target) : Pure Teams SDK with typed handlers |
| 940 | Phase 4 (Future) : Cloud-native with additional performance optimizations |
| 941 | ``` |
| 942 | |