0
# Microsoft Teams Integration
1
2
Teams-specific models for meetings, task modules, messaging extensions, O365 connector cards, and file handling within Microsoft Teams environments. This module extends the core Bot Framework schema with Teams-specific functionality.
3
4
## Core Teams Models
5
6
### Teams Channel Account
7
8
Extended channel account with Teams-specific properties.
9
10
```python { .api }
11
class TeamsChannelAccount(Model):
12
def __init__(self, *, id: str = None, name: str = None,
13
aad_object_id: str = None, role: str = None,
14
user_principal_name: str = None, teams_user_id: str = None, **kwargs): ...
15
```
16
17
```python
18
from botbuilder.schema.teams import TeamsChannelAccount
19
20
teams_user = TeamsChannelAccount(
21
id="29:1234567890",
22
name="John Doe",
23
aad_object_id="12345678-1234-1234-1234-123456789012",
24
user_principal_name="john.doe@company.com",
25
teams_user_id="teams-user-123"
26
)
27
```
28
29
### Teams Channel Data
30
31
Contains Teams-specific channel information including team, channel, and meeting details.
32
33
```python { .api }
34
class TeamsChannelData(Model):
35
def __init__(self, *, team = None, channel = None, meeting = None,
36
settings = None, tenant = None, source_event_time: str = None, **kwargs): ...
37
38
class TeamInfo(Model):
39
def __init__(self, *, id: str = None, name: str = None, **kwargs): ...
40
41
class ChannelInfo(Model):
42
def __init__(self, *, id: str = None, name: str = None, **kwargs): ...
43
44
class TenantInfo(Model):
45
def __init__(self, *, id: str = None, **kwargs): ...
46
47
class TeamsPagedMembersResult(Model):
48
def __init__(self, *, continuation_token: str = None,
49
members: List = None, **kwargs): ...
50
```
51
52
```python
53
from botbuilder.schema.teams import TeamsChannelData, TeamInfo, ChannelInfo, TenantInfo
54
55
teams_data = TeamsChannelData(
56
team=TeamInfo(id="19:team-id", name="Development Team"),
57
channel=ChannelInfo(id="19:channel-id", name="General"),
58
tenant=TenantInfo(id="tenant-id-12345")
59
)
60
```
61
62
## Meeting Models
63
64
### Teams Meeting Info
65
66
Core meeting information for Teams meetings.
67
68
```python { .api }
69
class TeamsMeetingInfo(Model):
70
def __init__(self, *, id: str = None, organized: str = None,
71
join_url: str = None, **kwargs): ...
72
73
class TeamsMeetingParticipant(Model):
74
def __init__(self, *, user = None, meeting = None, conversation = None, **kwargs): ...
75
76
class MeetingDetails(Model):
77
def __init__(self, *, id: str = None, ms_graph_resource_id: str = None,
78
scheduled_start_time: str = None, scheduled_end_time: str = None,
79
title: str = None, join_url: str = None, **kwargs): ...
80
```
81
82
```python
83
from botbuilder.schema.teams import TeamsMeetingInfo, MeetingDetails
84
85
meeting_info = TeamsMeetingInfo(
86
id="meeting-id-12345",
87
organized="2023-10-15T14:00:00Z",
88
join_url="https://teams.microsoft.com/l/meetup-join/..."
89
)
90
91
meeting_details = MeetingDetails(
92
id="meeting-id-12345",
93
title="Sprint Planning Meeting",
94
scheduled_start_time="2023-10-15T14:00:00Z",
95
scheduled_end_time="2023-10-15T15:00:00Z",
96
join_url="https://teams.microsoft.com/l/meetup-join/..."
97
)
98
```
99
100
### Meeting Events
101
102
Models for meeting lifecycle events.
103
104
```python { .api }
105
class MeetingStartEventDetails(Model):
106
def __init__(self, *, start_time: str = None, title: str = None,
107
type: str = None, id: str = None, **kwargs): ...
108
109
class MeetingEndEventDetails(Model):
110
def __init__(self, *, end_time: str = None, title: str = None,
111
type: str = None, id: str = None, **kwargs): ...
112
113
class MeetingParticipantsEventDetails(Model):
114
def __init__(self, *, members: List = None, **kwargs): ...
115
```
116
117
```python
118
from botbuilder.schema.teams import MeetingStartEventDetails, MeetingEndEventDetails
119
120
meeting_start = MeetingStartEventDetails(
121
start_time="2023-10-15T14:00:00Z",
122
title="Sprint Planning Meeting",
123
type="meetingStart",
124
id="meeting-id-12345"
125
)
126
127
meeting_end = MeetingEndEventDetails(
128
end_time="2023-10-15T15:00:00Z",
129
title="Sprint Planning Meeting",
130
type="meetingEnd",
131
id="meeting-id-12345"
132
)
133
```
134
135
## Task Modules
136
137
### Task Module Request and Response
138
139
Models for Teams task modules (dialogs).
140
141
```python { .api }
142
class TaskModuleRequest(Model):
143
def __init__(self, *, data = None, context = None, **kwargs): ...
144
145
class TaskModuleResponse(Model):
146
def __init__(self, *, task = None, **kwargs): ...
147
148
class TaskModuleTaskInfo(Model):
149
def __init__(self, *, title: str = None, height = None, width = None,
150
url: str = None, card = None, fallback_url: str = None,
151
completion_bot_id: str = None, **kwargs): ...
152
```
153
154
```python
155
from botbuilder.schema.teams import (
156
TaskModuleRequest, TaskModuleResponse, TaskModuleTaskInfo
157
)
158
159
# Task module request
160
task_request = TaskModuleRequest(
161
data={"custom_data": "value"},
162
context={"theme": "default"}
163
)
164
165
# Task module response with URL
166
task_info = TaskModuleTaskInfo(
167
title="Configuration Dialog",
168
height=400,
169
width=600,
170
url="https://myapp.com/config"
171
)
172
173
task_response = TaskModuleResponse(task=task_info)
174
```
175
176
### Task Module Response Types
177
178
Different response types for task modules.
179
180
```python { .api }
181
class TaskModuleContinueResponse(Model):
182
def __init__(self, *, type: str = None, task = None, **kwargs): ...
183
184
class TaskModuleMessageResponse(Model):
185
def __init__(self, *, type: str = None, task = None, **kwargs): ...
186
```
187
188
```python
189
from botbuilder.schema.teams import TaskModuleContinueResponse
190
191
continue_response = TaskModuleContinueResponse(
192
type="continue",
193
task=task_info
194
)
195
```
196
197
## Messaging Extensions
198
199
### Messaging Extension Query
200
201
Models for messaging extension queries and responses.
202
203
```python { .api }
204
class MessagingExtensionQuery(Model):
205
def __init__(self, *, command_id: str = None, parameters: List = None,
206
query_options = None, **kwargs): ...
207
208
class MessagingExtensionParameter(Model):
209
def __init__(self, *, name: str = None, value = None, **kwargs): ...
210
211
class MessagingExtensionResponse(Model):
212
def __init__(self, *, compose_extension = None, **kwargs): ...
213
214
class MessagingExtensionResult(Model):
215
def __init__(self, *, attachment_type: str = None, attachments: List = None,
216
activity_preview = None, type: str = None, **kwargs): ...
217
```
218
219
```python
220
from botbuilder.schema.teams import (
221
MessagingExtensionQuery, MessagingExtensionParameter,
222
MessagingExtensionResponse, MessagingExtensionResult,
223
MessagingExtensionAttachment
224
)
225
226
# Query from messaging extension
227
me_query = MessagingExtensionQuery(
228
command_id="searchCommand",
229
parameters=[
230
MessagingExtensionParameter(name="searchText", value="bot framework")
231
]
232
)
233
234
# Response with results
235
me_result = MessagingExtensionResult(
236
type="result",
237
attachment_type="list",
238
attachments=[
239
MessagingExtensionAttachment(
240
content_type="application/vnd.microsoft.card.hero",
241
content=hero_card
242
)
243
]
244
)
245
246
me_response = MessagingExtensionResponse(compose_extension=me_result)
247
```
248
249
### Messaging Extension Actions
250
251
Models for messaging extension actions.
252
253
```python { .api }
254
class MessagingExtensionAction(Model):
255
def __init__(self, *, command_id: str = None, command_context: str = None,
256
bot_id: str = None, bot_message_preview_action: str = None,
257
message_payload = None, **kwargs): ...
258
259
class MessagingExtensionActionResponse(Model):
260
def __init__(self, *, task = None, compose_extension = None, **kwargs): ...
261
```
262
263
```python
264
from botbuilder.schema.teams import MessagingExtensionAction, MessagingExtensionActionResponse
265
266
# Action request
267
me_action = MessagingExtensionAction(
268
command_id="createCard",
269
command_context="compose",
270
bot_id="bot-id-12345"
271
)
272
273
# Action response with task module
274
action_response = MessagingExtensionActionResponse(
275
task=task_info
276
)
277
```
278
279
## File Handling
280
281
### File Consent and Upload
282
283
Models for Teams file handling workflows.
284
285
```python { .api }
286
class FileConsentCard(Model):
287
def __init__(self, *, description: str = None, size_in_bytes: int = None,
288
accept_context = None, decline_context = None, **kwargs): ...
289
290
class FileConsentCardResponse(Model):
291
def __init__(self, *, action: str = None, context = None,
292
upload_info = None, **kwargs): ...
293
294
class FileUploadInfo(Model):
295
def __init__(self, *, content_url: str = None, name: str = None,
296
upload_url: str = None, unique_id: str = None, **kwargs): ...
297
298
class FileDownloadInfo(Model):
299
def __init__(self, *, download_url: str = None, unique_id: str = None,
300
file_type: str = None, **kwargs): ...
301
302
class FileInfoCard(Model):
303
def __init__(self, *, description: str = None, size_in_bytes: int = None,
304
accept_context = None, decline_context = None, **kwargs): ...
305
```
306
307
```python
308
from botbuilder.schema.teams import (
309
FileConsentCard, FileConsentCardResponse, FileUploadInfo
310
)
311
312
# File consent card
313
file_consent = FileConsentCard(
314
description="Project Documentation.pdf",
315
size_in_bytes=2048576,
316
accept_context={"file_id": "doc-123"},
317
decline_context={"file_id": "doc-123"}
318
)
319
320
# File upload info after consent
321
upload_info = FileUploadInfo(
322
content_url="https://graph.microsoft.com/files/...",
323
name="Project Documentation.pdf",
324
upload_url="https://teams.microsoft.com/upload/...",
325
unique_id="file-unique-id-123"
326
)
327
```
328
329
## O365 Connector Cards
330
331
### O365 Connector Card
332
333
Rich connector cards for Office 365 integrations.
334
335
```python { .api }
336
class O365ConnectorCard(Model):
337
def __init__(self, *, title: str = None, text: str = None,
338
summary: str = None, theme_color: str = None,
339
sections: List = None, potential_actions: List = None, **kwargs): ...
340
341
class O365ConnectorCardSection(Model):
342
def __init__(self, *, title: str = None, text: str = None,
343
activity_title: str = None, activity_subtitle: str = None,
344
activity_text: str = None, activity_image: str = None,
345
facts: List = None, images: List = None, **kwargs): ...
346
347
class O365ConnectorCardFact(Model):
348
def __init__(self, *, name: str = None, value: str = None, **kwargs): ...
349
```
350
351
```python
352
from botbuilder.schema.teams import (
353
O365ConnectorCard, O365ConnectorCardSection, O365ConnectorCardFact
354
)
355
356
# O365 connector card
357
connector_card = O365ConnectorCard(
358
title="Build Status",
359
text="Build completed successfully",
360
theme_color="00FF00",
361
sections=[
362
O365ConnectorCardSection(
363
title="Build Details",
364
facts=[
365
O365ConnectorCardFact(name="Duration", value="2m 30s"),
366
O365ConnectorCardFact(name="Tests", value="45 passed")
367
]
368
)
369
]
370
)
371
```
372
373
### O365 Connector Actions
374
375
Action models for O365 connector cards.
376
377
```python { .api }
378
class O365ConnectorCardActionBase(Model):
379
def __init__(self, *, type: str = None, name: str = None,
380
id: str = None, **kwargs): ...
381
382
class O365ConnectorCardHttpPOST(Model):
383
def __init__(self, *, target: str = None, headers: List = None,
384
body: str = None, **kwargs): ...
385
386
class O365ConnectorCardOpenUri(Model):
387
def __init__(self, *, targets: List = None, **kwargs): ...
388
```
389
390
```python
391
from botbuilder.schema.teams import O365ConnectorCardHttpPOST, O365ConnectorCardOpenUri
392
393
# HTTP POST action
394
post_action = O365ConnectorCardHttpPOST(
395
target="https://api.myservice.com/webhook",
396
headers=[{"name": "Authorization", "value": "Bearer token"}],
397
body='{"action": "approve", "id": "123"}'
398
)
399
400
# Open URI action
401
uri_action = O365ConnectorCardOpenUri(
402
targets=[
403
{"os": "default", "uri": "https://myapp.com/details/123"}
404
]
405
)
406
```
407
408
## Tab Support
409
410
### Tab Request and Response
411
412
Models for Teams tab applications.
413
414
```python { .api }
415
class TabRequest(Model):
416
def __init__(self, *, tab_context = None, state = None,
417
properties = None, conversation = None, **kwargs): ...
418
419
class TabResponse(Model):
420
def __init__(self, *, tab = None, **kwargs): ...
421
422
class TabContext(Model):
423
def __init__(self, *, theme: str = None, entity_id: str = None,
424
sub_entity_id: str = None, locale: str = None,
425
channel_id: str = None, team_id: str = None,
426
tenant_id: str = None, **kwargs): ...
427
```
428
429
```python
430
from botbuilder.schema.teams import TabRequest, TabResponse, TabContext
431
432
tab_context = TabContext(
433
theme="default",
434
entity_id="settings",
435
team_id="team-id-12345",
436
channel_id="channel-id-67890",
437
tenant_id="tenant-id-abcde"
438
)
439
440
tab_request = TabRequest(
441
tab_context=tab_context,
442
properties={"custom_prop": "value"}
443
)
444
```
445
446
## Authentication in Teams
447
448
### Teams Authentication
449
450
Teams-specific authentication models.
451
452
```python { .api }
453
class SigninStateVerificationQuery(Model):
454
def __init__(self, *, state: str = None, **kwargs): ...
455
456
class BotConfigAuth(Model):
457
def __init__(self, *, type: str = None, id: str = None,
458
connection_name: str = None, text: str = None,
459
suggested_actions = None, **kwargs): ...
460
```
461
462
```python
463
from botbuilder.schema.teams import SigninStateVerificationQuery, BotConfigAuth
464
465
# State verification for Teams auth
466
state_query = SigninStateVerificationQuery(
467
state="auth-state-token-12345"
468
)
469
470
# Bot configuration auth
471
config_auth = BotConfigAuth(
472
type="oauth",
473
connection_name="TeamsAuth",
474
text="Please sign in to access Teams resources"
475
)
476
```
477
478
## Usage Patterns
479
480
### Teams Bot Setup
481
482
```python
483
from botbuilder.schema import Activity, ActivityTypes
484
from botbuilder.schema.teams import TeamsChannelData
485
486
async def handle_teams_message(activity: Activity):
487
"""Handle message in Teams context"""
488
if hasattr(activity, 'channel_data') and activity.channel_data:
489
teams_data = TeamsChannelData(**activity.channel_data)
490
491
# Access Teams-specific information
492
team_id = teams_data.team.id if teams_data.team else None
493
channel_id = teams_data.channel.id if teams_data.channel else None
494
495
# Handle Teams-specific logic
496
if team_id:
497
return await handle_team_message(activity, team_id, channel_id)
498
499
# Fallback to regular message handling
500
return await handle_regular_message(activity)
501
```
502
503
### Task Module Integration
504
505
```python
506
from botbuilder.schema.teams import TaskModuleRequest, TaskModuleResponse, TaskModuleTaskInfo
507
508
async def handle_task_module_fetch(request: TaskModuleRequest):
509
"""Handle task module fetch request"""
510
# Create task module response
511
task_info = TaskModuleTaskInfo(
512
title="User Settings",
513
height=500,
514
width=400,
515
url="https://myapp.com/settings"
516
)
517
518
return TaskModuleResponse(task=task_info)
519
520
async def handle_task_module_submit(request: TaskModuleRequest):
521
"""Handle task module submit"""
522
user_data = request.data
523
524
# Process submitted data
525
result = await process_user_settings(user_data)
526
527
# Return success message
528
return TaskModuleResponse(
529
task={"type": "message", "value": "Settings saved successfully!"}
530
)
531
```
532
533
### Messaging Extension Implementation
534
535
```python
536
from botbuilder.schema.teams import (
537
MessagingExtensionQuery, MessagingExtensionResponse,
538
MessagingExtensionResult, MessagingExtensionAttachment
539
)
540
541
async def handle_messaging_extension_query(query: MessagingExtensionQuery):
542
"""Handle messaging extension search query"""
543
search_text = ""
544
for param in query.parameters:
545
if param.name == "searchText":
546
search_text = param.value
547
break
548
549
# Perform search
550
results = await search_items(search_text)
551
552
# Create attachments from results
553
attachments = []
554
for item in results:
555
card = create_hero_card(item)
556
attachment = MessagingExtensionAttachment(
557
content_type="application/vnd.microsoft.card.hero",
558
content=card,
559
preview=create_preview_card(item)
560
)
561
attachments.append(attachment)
562
563
# Return response
564
result = MessagingExtensionResult(
565
type="result",
566
attachment_type="list",
567
attachments=attachments
568
)
569
570
return MessagingExtensionResponse(compose_extension=result)
571
```
572
573
## Teams-Specific Features
574
575
### @Mentions in Teams
576
577
```python
578
from botbuilder.schema import Entity
579
from botbuilder.schema.teams import TeamsChannelAccount
580
581
def create_mention_entity(user: TeamsChannelAccount, mentioned_text: str) -> Entity:
582
"""Create mention entity for Teams"""
583
return Entity(
584
type="mention",
585
properties={
586
"mentioned": {
587
"id": user.id,
588
"name": user.name
589
},
590
"text": mentioned_text
591
}
592
)
593
```
594
595
### Teams Meeting Bot
596
597
```python
598
from botbuilder.schema.teams import TeamsMeetingInfo, MeetingStartEventDetails
599
600
async def handle_meeting_events(activity: Activity):
601
"""Handle Teams meeting events"""
602
if activity.name == "application/vnd.microsoft.meetingStart":
603
meeting_start = MeetingStartEventDetails(**activity.value)
604
return await handle_meeting_start(meeting_start)
605
606
elif activity.name == "application/vnd.microsoft.meetingEnd":
607
meeting_end = MeetingEndEventDetails(**activity.value)
608
return await handle_meeting_end(meeting_end)
609
```
610
611
## Message Actions
612
613
### Message Actions Payload
614
615
Models for Teams message action payloads and components.
616
617
```python { .api }
618
class MessageActionsPayload(Model):
619
def __init__(self, *, id: str = None, timestamp: str = None,
620
action: str = None, body = None, attachments: List = None,
621
from_property = None, conversation = None, recipient = None,
622
channel_data = None, reply_to_id: str = None, value = None, **kwargs): ...
623
624
class MessageActionsPayloadApp(Model):
625
def __init__(self, *, id: str = None, display_name: str = None,
626
name: str = None, **kwargs): ...
627
628
class MessageActionsPayloadAttachment(Model):
629
def __init__(self, *, id: str = None, content_type: str = None,
630
content_url: str = None, content = None, name: str = None,
631
thumbnail_url: str = None, **kwargs): ...
632
633
class MessageActionsPayloadBody(Model):
634
def __init__(self, *, content_type: str = None, content = None, **kwargs): ...
635
636
class MessageActionsPayloadConversation(Model):
637
def __init__(self, *, id: str = None, display_name: str = None,
638
name: str = None, conversation_type: str = None,
639
tenant_id: str = None, **kwargs): ...
640
641
class MessageActionsPayloadFrom(Model):
642
def __init__(self, *, id: str = None, display_name: str = None,
643
name: str = None, user_principal_name: str = None, **kwargs): ...
644
645
class MessageActionsPayloadUser(Model):
646
def __init__(self, *, id: str = None, display_name: str = None,
647
name: str = None, **kwargs): ...
648
649
class MessageActionsPayloadMention(Model):
650
def __init__(self, *, mentioned = None, text: str = None,
651
type: str = None, **kwargs): ...
652
653
class MessageActionsPayloadReaction(Model):
654
def __init__(self, *, type: str = None, **kwargs): ...
655
```
656
657
## Additional Teams Models
658
659
### Notifications and Miscellaneous
660
661
```python { .api }
662
class NotificationInfo(Model):
663
def __init__(self, *, alert: bool = None, external_resource_url: str = None, **kwargs): ...
664
665
class ConversationList(Model):
666
def __init__(self, *, conversations: List = None, **kwargs): ...
667
668
class AppBasedLinkQuery(Model):
669
def __init__(self, *, url: str = None, **kwargs): ...
670
671
class CacheInfo(Model):
672
def __init__(self, *, cache_type: str = None, cache_duration: int = None, **kwargs): ...
673
674
class ReadReceiptInfo(Model):
675
def __init__(self, *, user = None, last_read_message_id: str = None, **kwargs): ...
676
677
class OnBehalfOf(Model):
678
def __init__(self, *, display_name: str = None, mri: str = None, **kwargs): ...
679
```
680
681
## Error Handling
682
683
```python
684
from botbuilder.schema import Activity, ActivityTypes
685
686
def create_teams_error_response(error: str) -> Activity:
687
"""Create Teams-appropriate error response"""
688
return Activity(
689
type=ActivityTypes.message,
690
text=f"Teams operation failed: {error}. Please try again or contact your administrator."
691
)
692
```