0
# Turn Context & Activities
1
2
Turn context management and activity manipulation utilities. TurnContext represents the context of a single conversational turn and provides methods for sending responses, managing turn state, and working with activities.
3
4
## Capabilities
5
6
### TurnContext
7
8
Central context object for a single conversational turn that encapsulates the current activity, provides methods for sending responses, and manages turn-specific state and services.
9
10
```python { .api }
11
class TurnContext:
12
def __init__(self, adapter, activity):
13
"""
14
Initialize turn context.
15
16
Args:
17
adapter (BotAdapter): The bot adapter
18
activity (Activity): The incoming activity
19
"""
20
self.adapter = adapter
21
self.activity = activity
22
self.responded = False
23
self.services = {}
24
self.turn_state = {}
25
26
async def send_activity(self, activity_or_text, speak: str = None, input_hint=None):
27
"""
28
Send a single activity response.
29
30
Args:
31
activity_or_text: Activity object or text string
32
speak (str, optional): Speech text for voice channels
33
input_hint (optional): Input hint for the client
34
35
Returns:
36
ResourceResponse: Response from sending the activity
37
"""
38
39
async def send_activities(self, activities):
40
"""
41
Send multiple activities in sequence.
42
43
Args:
44
activities (list): List of Activity objects to send
45
46
Returns:
47
list: List of ResourceResponse objects
48
"""
49
50
async def update_activity(self, activity):
51
"""
52
Update an existing activity.
53
54
Args:
55
activity (Activity): Activity with updated content
56
57
Returns:
58
ResourceResponse: Response from the update operation
59
"""
60
61
async def delete_activity(self, id_or_reference):
62
"""
63
Delete an activity.
64
65
Args:
66
id_or_reference: Activity ID string or ConversationReference
67
"""
68
69
@property
70
def responded(self):
71
"""
72
Check if a response has been sent during this turn.
73
74
Returns:
75
bool: True if a response was sent
76
"""
77
78
@property
79
def turn_state(self):
80
"""
81
Get turn-specific state dictionary.
82
83
Returns:
84
dict: Turn state storage
85
"""
86
87
@property
88
def services(self):
89
"""
90
Get services dictionary for dependency injection.
91
92
Returns:
93
dict: Services container
94
"""
95
96
def get(self, key: str):
97
"""
98
Get a service from the services collection.
99
100
Args:
101
key (str): Service key
102
103
Returns:
104
object: Service instance or None
105
"""
106
107
def has(self, key: str):
108
"""
109
Check if a service exists in the collection.
110
111
Args:
112
key (str): Service key
113
114
Returns:
115
bool: True if service exists
116
"""
117
118
def set(self, key: str, value):
119
"""
120
Set a service in the services collection.
121
122
Args:
123
key (str): Service key
124
value (object): Service instance
125
"""
126
127
def on_send_activities(self, handler):
128
"""
129
Register handler for send activities events.
130
131
Args:
132
handler: Event handler function
133
134
Returns:
135
TurnContext: Self for chaining
136
"""
137
138
def on_update_activity(self, handler):
139
"""
140
Register handler for update activity events.
141
142
Args:
143
handler: Event handler function
144
145
Returns:
146
TurnContext: Self for chaining
147
"""
148
149
def on_delete_activity(self, handler):
150
"""
151
Register handler for delete activity events.
152
153
Args:
154
handler: Event handler function
155
156
Returns:
157
TurnContext: Self for chaining
158
"""
159
160
@staticmethod
161
def get_conversation_reference(activity):
162
"""
163
Get conversation reference from an activity.
164
165
Args:
166
activity (Activity): Activity to extract reference from
167
168
Returns:
169
ConversationReference: Conversation reference
170
"""
171
172
@staticmethod
173
def apply_conversation_reference(activity, reference, is_incoming=False):
174
"""
175
Apply conversation reference to an activity.
176
177
Args:
178
activity (Activity): Activity to modify
179
reference (ConversationReference): Reference to apply
180
is_incoming (bool): Whether this is an incoming activity
181
182
Returns:
183
Activity: Modified activity
184
"""
185
186
@staticmethod
187
def remove_recipient_mention(activity):
188
"""
189
Remove @mentions of the recipient (bot) from activity text.
190
191
Args:
192
activity (Activity): Activity to process
193
194
Returns:
195
str: Text with recipient mentions removed
196
"""
197
198
@staticmethod
199
def get_mentions(activity):
200
"""
201
Get all @mentions from an activity.
202
203
Args:
204
activity (Activity): Activity to analyze
205
206
Returns:
207
list: List of Mention objects
208
"""
209
```
210
211
### Activity Properties and Methods
212
213
Core properties and methods available on the Activity object that represents messages and other interactions in the Bot Framework.
214
215
```python { .api }
216
class Activity:
217
"""Represents a Bot Framework activity."""
218
219
# Core properties
220
type: str # Activity type (message, invoke, event, etc.)
221
id: str # Unique activity ID
222
timestamp: str # When activity was created
223
local_timestamp: str # Local timestamp
224
service_url: str # Service URL for the channel
225
channel_id: str # Channel identifier
226
from_property: ChannelAccount # Who sent the activity
227
conversation: ConversationAccount # Conversation context
228
recipient: ChannelAccount # Who receives the activity
229
230
# Message-specific properties
231
text: str # Text content of message
232
speak: str # Speech text for voice channels
233
input_hint: str # Input hint for client
234
summary: str # Summary of the activity
235
236
# Rich content
237
attachments: list # List of Attachment objects
238
entities: list # List of Entity objects
239
channel_data: object # Channel-specific data
240
241
# Interaction properties
242
action: str # Action being performed
243
reply_to_id: str # ID of activity this replies to
244
value: object # Value for invoke/event activities
245
name: str # Name for invoke/event activities
246
relate_to: ConversationReference # Related conversation
247
248
# Group conversation properties
249
members_added: list # Members added to conversation
250
members_removed: list # Members removed from conversation
251
reactions_added: list # Reactions added to message
252
reactions_removed: list # Reactions removed from message
253
254
# Suggested actions
255
suggested_actions: SuggestedActions # Suggested actions for user
256
257
def as_message_activity():
258
"""Convert to message activity."""
259
260
def as_contact_relation_update_activity():
261
"""Convert to contact relation update activity."""
262
263
def as_installation_update_activity():
264
"""Convert to installation update activity."""
265
266
def as_message_reaction_activity():
267
"""Convert to message reaction activity."""
268
269
def as_event_activity():
270
"""Convert to event activity."""
271
272
def as_invoke_activity():
273
"""Convert to invoke activity."""
274
275
def as_handoff_activity():
276
"""Convert to handoff activity."""
277
278
def create_reply(text: str = "", locale: str = ""):
279
"""
280
Create a reply to this activity.
281
282
Args:
283
text (str): Reply text
284
locale (str): Locale for the reply
285
286
Returns:
287
Activity: Reply activity
288
"""
289
290
def get_conversation_reference():
291
"""
292
Get conversation reference for this activity.
293
294
Returns:
295
ConversationReference: Conversation reference
296
"""
297
298
def apply_conversation_reference(reference, is_incoming: bool = False):
299
"""
300
Apply conversation reference to this activity.
301
302
Args:
303
reference (ConversationReference): Reference to apply
304
is_incoming (bool): Whether this is incoming
305
"""
306
307
def create_trace(name: str, value: object = None, value_type: str = None, label: str = None):
308
"""
309
Create a trace activity.
310
311
Args:
312
name (str): Trace name
313
value (object): Trace value
314
value_type (str): Value type
315
label (str): Trace label
316
317
Returns:
318
Activity: Trace activity
319
"""
320
```
321
322
### Conversation Reference Utilities
323
324
Utilities for working with conversation references that enable proactive messaging and conversation tracking.
325
326
```python { .api }
327
def get_conversation_reference(activity):
328
"""
329
Extract conversation reference from activity.
330
331
Args:
332
activity (Activity): Source activity
333
334
Returns:
335
ConversationReference: Conversation reference
336
"""
337
338
def apply_conversation_reference(activity, reference, is_incoming=False):
339
"""
340
Apply conversation reference to activity.
341
342
Args:
343
activity (Activity): Target activity
344
reference (ConversationReference): Reference to apply
345
is_incoming (bool): Whether activity is incoming
346
347
Returns:
348
Activity: Modified activity
349
"""
350
351
def get_reply_conversation_reference(activity, reply):
352
"""
353
Get conversation reference for a reply.
354
355
Args:
356
activity (Activity): Original activity
357
reply (ResourceResponse): Reply response
358
359
Returns:
360
ConversationReference: Reply conversation reference
361
"""
362
```
363
364
## Usage Examples
365
366
### Basic Turn Context Usage
367
368
```python
369
from botbuilder.core import ActivityHandler, TurnContext, MessageFactory
370
371
class BasicBot(ActivityHandler):
372
async def on_message_activity(self, turn_context: TurnContext):
373
# Access the incoming activity
374
user_message = turn_context.activity.text
375
user_name = turn_context.activity.from_property.name
376
377
# Send a simple response
378
reply = f"Hello {user_name}, you said: {user_message}"
379
await turn_context.send_activity(MessageFactory.text(reply))
380
381
# Check if we've responded
382
print(f"Responded: {turn_context.has_responded()}")
383
```
384
385
### Sending Multiple Activities
386
387
```python
388
async def on_message_activity(self, turn_context: TurnContext):
389
activities = [
390
MessageFactory.text("First message"),
391
MessageFactory.text("Second message"),
392
MessageFactory.text("Third message")
393
]
394
395
# Send all activities at once
396
responses = await turn_context.send_activities(activities)
397
398
print(f"Sent {len(responses)} activities")
399
```
400
401
### Working with Conversation References
402
403
```python
404
async def on_message_activity(self, turn_context: TurnContext):
405
# Get conversation reference for proactive messaging
406
conv_ref = TurnContext.get_conversation_reference(turn_context.activity)
407
408
# Store conversation reference for later use
409
await self.store_conversation_reference(conv_ref)
410
411
await turn_context.send_activity(MessageFactory.text("I'll remember this conversation!"))
412
413
async def send_proactive_message(self, stored_conv_ref, message):
414
async def proactive_callback(proactive_turn_context):
415
await proactive_turn_context.send_activity(MessageFactory.text(message))
416
417
await self.adapter.continue_conversation(
418
stored_conv_ref,
419
proactive_callback
420
)
421
```
422
423
### Updating and Deleting Activities
424
425
```python
426
async def on_message_activity(self, turn_context: TurnContext):
427
# Send initial message
428
response = await turn_context.send_activity(MessageFactory.text("Processing..."))
429
430
# Simulate some work
431
await asyncio.sleep(2)
432
433
# Update the message
434
updated_activity = MessageFactory.text("Processing complete!")
435
updated_activity.id = response.id
436
await turn_context.update_activity(updated_activity)
437
438
# Later, delete the message if needed
439
# await turn_context.delete_activity(response.id)
440
```
441
442
### Handling Mentions
443
444
```python
445
async def on_message_activity(self, turn_context: TurnContext):
446
# Remove bot mentions from text
447
clean_text = TurnContext.remove_recipient_mention(turn_context.activity)
448
449
# Get all mentions in the activity
450
mentions = TurnContext.get_mentions(turn_context.activity)
451
452
if mentions:
453
mention_info = f"Found {len(mentions)} mentions"
454
await turn_context.send_activity(MessageFactory.text(mention_info))
455
456
# Process the clean text
457
reply = f"You said: {clean_text.strip()}"
458
await turn_context.send_activity(MessageFactory.text(reply))
459
```
460
461
### Turn State Management
462
463
```python
464
async def on_message_activity(self, turn_context: TurnContext):
465
# Store data in turn state
466
turn_context.turn_state["user_message_count"] = turn_context.turn_state.get("user_message_count", 0) + 1
467
468
# Access turn services
469
if "custom_service" not in turn_context.services:
470
turn_context.services["custom_service"] = CustomService()
471
472
service = turn_context.services["custom_service"]
473
result = await service.process(turn_context.activity.text)
474
475
await turn_context.send_activity(MessageFactory.text(f"Processed: {result}"))
476
```
477
478
## Types
479
480
```python { .api }
481
class ConversationReference:
482
"""Reference to a conversation."""
483
activity_id: str
484
user: ChannelAccount
485
bot: ChannelAccount
486
conversation: ConversationAccount
487
channel_id: str
488
service_url: str
489
locale: str
490
491
class ResourceResponse:
492
"""Response from activity operations."""
493
id: str
494
495
class ChannelAccount:
496
"""Channel account information."""
497
id: str
498
name: str
499
aad_object_id: str
500
role: str
501
502
class ConversationAccount:
503
"""Conversation information."""
504
is_group: bool
505
conversation_type: str
506
id: str
507
name: str
508
aad_object_id: str
509
role: str
510
tenant_id: str
511
512
class Attachment:
513
"""File or media attachment."""
514
content_type: str
515
content_url: str
516
content: object
517
name: str
518
thumbnail_url: str
519
520
class Entity:
521
"""Named entity in activity."""
522
type: str
523
524
class SuggestedActions:
525
"""Suggested actions for user."""
526
to: list
527
actions: list
528
529
class Mention:
530
"""@mention in activity."""
531
mentioned: ChannelAccount
532
text: str
533
type: str
534
```