0
# Core Activity Management
1
2
The foundational Activity model and supporting types that enable communication between bots and users across all Bot Framework channels. The Activity class serves as the central communication primitive containing all message types, events, and conversation updates.
3
4
## Capabilities
5
6
### Activity Class
7
8
The Activity class is the basic communication type for the Bot Framework 3.0 protocol, handling all types of messages, events, and conversation updates with comprehensive properties and methods.
9
10
```python { .api }
11
class Activity(Model):
12
def __init__(self, *,
13
type: str = None,
14
id: str = None,
15
timestamp: datetime = None,
16
local_timestamp: datetime = None,
17
local_timezone: str = None,
18
service_url: str = None,
19
channel_id: str = None,
20
from_property = None, # ChannelAccount
21
conversation = None, # ConversationAccount
22
recipient = None, # ChannelAccount
23
text_format: str = None,
24
attachment_layout: str = None,
25
members_added: List = None,
26
members_removed: List = None,
27
reactions_added: List = None,
28
reactions_removed: List = None,
29
topic_name: str = None,
30
history_disclosed: bool = None,
31
locale: str = None,
32
text: str = None,
33
speak: str = None,
34
input_hint: str = None,
35
summary: str = None,
36
suggested_actions = None, # SuggestedActions
37
attachments: List = None,
38
entities: List = None,
39
channel_data = None,
40
action: str = None,
41
reply_to_id: str = None,
42
label: str = None,
43
value_type: str = None,
44
value = None,
45
name: str = None,
46
relates_to = None, # ConversationReference
47
code: str = None,
48
expiration: datetime = None,
49
importance: str = None,
50
delivery_mode: str = None,
51
listen_for: List[str] = None,
52
text_highlights: List = None,
53
semantic_action = None, # SemanticAction
54
caller_id: str = None,
55
**kwargs):
56
"""
57
An Activity is the basic communication type for the Bot Framework 3.0 protocol.
58
59
Parameters:
60
- type: Activity type (message, conversationUpdate, typing, etc.)
61
- id: Unique identifier for the activity on the channel
62
- timestamp: UTC timestamp when message was sent (ISO-8601)
63
- local_timestamp: Local timestamp (ISO-8601)
64
- local_timezone: IANA timezone name
65
- service_url: Channel's service endpoint URL
66
- channel_id: Unique channel identifier
67
- from_property: Sender of the message (ChannelAccount)
68
- conversation: Conversation this activity belongs to (ConversationAccount)
69
- recipient: Recipient of the message (ChannelAccount)
70
- text_format: Format of text fields (markdown, plain, xml)
71
- attachment_layout: Layout hint for multiple attachments (list, carousel)
72
- members_added: Members added to conversation (List[ChannelAccount])
73
- members_removed: Members removed from conversation (List[ChannelAccount])
74
- reactions_added: Reactions added (List[MessageReaction])
75
- reactions_removed: Reactions removed (List[MessageReaction])
76
- topic_name: Updated topic name of conversation
77
- history_disclosed: Whether prior history is disclosed
78
- locale: Locale name for text field contents (BCP-47)
79
- text: Text content of the message
80
- speak: Text to speak (SSML)
81
- input_hint: Bot's input expectation (accepting, ignoring, expecting)
82
- summary: Text to display if channel cannot render cards
83
- suggested_actions: Suggested actions for the activity
84
- attachments: File attachments (List[Attachment])
85
- entities: Entities mentioned in message (List[Entity])
86
- channel_data: Channel-specific content
87
- action: Contact relation update action (add/remove)
88
- reply_to_id: ID of message this is replying to
89
- label: Descriptive label for activity
90
- value_type: Type of activity's value object
91
- value: Value associated with activity
92
- name: Operation name for invoke/event activities
93
- relates_to: Reference to another conversation/activity
94
- code: End of conversation code
95
- expiration: When activity should expire
96
- importance: Activity importance (low, normal, high)
97
- delivery_mode: Delivery hint (normal, notification, expectReplies, ephemeral)
98
- listen_for: Phrases for speech/language priming
99
- text_highlights: Text fragments to highlight
100
- semantic_action: Programmatic action accompanying request
101
- caller_id: IRI identifying the caller of a bot
102
"""
103
```
104
105
### Activity Reply and Reference Methods
106
107
Methods for creating replies and managing conversation references.
108
109
```python { .api }
110
def create_reply(self, text: str = None) -> 'Activity':
111
"""
112
Create a reply message activity to this activity.
113
114
Parameters:
115
- text: Reply text content
116
117
Returns:
118
New Activity configured as a reply with swapped from/recipient
119
"""
120
121
def apply_conversation_reference(self, reference: 'ConversationReference',
122
is_incoming: bool = False) -> 'Activity':
123
"""
124
Updates this activity with delivery information from conversation reference.
125
126
Parameters:
127
- reference: Conversation reference with delivery info
128
- is_incoming: Whether this is an incoming activity
129
130
Returns:
131
Updated activity with conversation reference applied
132
"""
133
134
def get_conversation_reference(self) -> 'ConversationReference':
135
"""
136
Create a ConversationReference based on this Activity.
137
138
Returns:
139
ConversationReference with activity's conversation info
140
"""
141
142
def get_reply_conversation_reference(self) -> 'ConversationReference':
143
"""
144
Create a ConversationReference for replies with swapped bot/user.
145
146
Returns:
147
ConversationReference configured for creating replies
148
"""
149
```
150
151
### Activity Content and Validation Methods
152
153
Methods for checking activity content and validation.
154
155
```python { .api }
156
def has_content(self) -> bool:
157
"""
158
Check if activity has any content to send.
159
160
Returns:
161
True if activity has text, attachments, or suggested actions
162
"""
163
164
def is_from_streaming_connection(self) -> bool:
165
"""
166
Determine if activity is from a streaming connection.
167
168
Returns:
169
True if from streaming connection, False otherwise
170
"""
171
172
def get_mentions(self) -> List['Mention']:
173
"""
174
Get all Mention entities from this activity.
175
176
Returns:
177
List of Mention entities found in activity.entities
178
"""
179
```
180
181
### Activity Type Conversion Methods
182
183
Methods that return typed activity objects or None if the activity is not of the specified type.
184
185
```python { .api }
186
def as_message_activity(self) -> 'Activity':
187
"""Returns this activity if type is 'message', None otherwise."""
188
189
def as_conversation_update_activity(self) -> 'Activity':
190
"""Returns this activity if type is 'conversationUpdate', None otherwise."""
191
192
def as_event_activity(self) -> 'Activity':
193
"""Returns this activity if type is 'event', None otherwise."""
194
195
def as_invoke_activity(self) -> 'Activity':
196
"""Returns this activity if type is 'invoke', None otherwise."""
197
198
def as_typing_activity(self) -> 'Activity':
199
"""Returns this activity if type is 'typing', None otherwise."""
200
201
def as_end_of_conversation_activity(self) -> 'Activity':
202
"""Returns this activity if type is 'endOfConversation', None otherwise."""
203
204
def as_installation_update_activity(self) -> 'Activity':
205
"""Returns this activity if type is 'installationUpdate', None otherwise."""
206
207
def as_message_update_activity(self) -> 'Activity':
208
"""Returns this activity if type is 'messageUpdate', None otherwise."""
209
210
def as_message_delete_activity(self) -> 'Activity':
211
"""Returns this activity if type is 'messageDelete', None otherwise."""
212
213
def as_message_reaction_activity(self) -> 'Activity':
214
"""Returns this activity if type is 'messageReaction', None otherwise."""
215
216
def as_suggestion_activity(self) -> 'Activity':
217
"""Returns this activity if type is 'suggestion', None otherwise."""
218
219
def as_trace_activity(self) -> 'Activity':
220
"""Returns this activity if type is 'trace', None otherwise."""
221
222
def as_handoff_activity(self) -> 'Activity':
223
"""Returns this activity if type is 'handoff', None otherwise."""
224
225
def as_command_activity(self) -> 'Activity':
226
"""Returns this activity if type is 'command', None otherwise."""
227
228
def as_command_result_activity(self) -> 'Activity':
229
"""Returns this activity if type is 'commandResult', None otherwise."""
230
231
def as_contact_relation_update_activity(self) -> 'Activity':
232
"""Returns this activity if type is 'contactRelationUpdate', None otherwise."""
233
```
234
235
### Static Factory Methods
236
237
Static methods for creating specific types of activities.
238
239
```python { .api }
240
@staticmethod
241
def create_message_activity() -> 'Activity':
242
"""
243
Create a message activity.
244
245
Returns:
246
New Activity with type set to 'message'
247
"""
248
249
@staticmethod
250
def create_conversation_update_activity() -> 'Activity':
251
"""
252
Create a conversation update activity.
253
254
Returns:
255
New Activity with type set to 'conversationUpdate'
256
"""
257
258
@staticmethod
259
def create_event_activity() -> 'Activity':
260
"""
261
Create an event activity.
262
263
Returns:
264
New Activity with type set to 'event'
265
"""
266
267
@staticmethod
268
def create_trace_activity(name: str, value = None, value_type: str = None,
269
label: str = None) -> 'Activity':
270
"""
271
Create a trace activity for debugging and monitoring.
272
273
Parameters:
274
- name: Name of the trace
275
- value: Value to trace
276
- value_type: Type of the value
277
- label: Optional label
278
279
Returns:
280
New Activity with type set to 'trace'
281
"""
282
```
283
284
### Conversation Reference Model
285
286
Model for referencing a specific point in a conversation.
287
288
```python { .api }
289
class ConversationReference(Model):
290
def __init__(self, *,
291
activity_id: str = None,
292
user = None, # ChannelAccount
293
bot = None, # ChannelAccount
294
conversation = None, # ConversationAccount
295
channel_id: str = None,
296
locale: str = None,
297
service_url: str = None,
298
**kwargs):
299
"""
300
An object relating to a particular point in a conversation.
301
302
Parameters:
303
- activity_id: ID of the activity to refer to
304
- user: User participating in this conversation
305
- bot: Bot participating in this conversation
306
- conversation: Conversation reference
307
- channel_id: Channel ID
308
- locale: Locale name for contents (BCP-47)
309
- service_url: Service endpoint for conversation operations
310
"""
311
```
312
313
### Activity Event Names
314
315
Enumeration of predefined activity event names.
316
317
```python { .api }
318
class ActivityEventNames(str, Enum):
319
continue_conversation = "ContinueConversation"
320
create_conversation = "CreateConversation"
321
```
322
323
## Usage Examples
324
325
### Creating and Sending a Message
326
327
```python
328
from botbuilder.schema import Activity, ActivityTypes, ChannelAccount, ConversationAccount
329
330
# Create a message activity
331
activity = Activity(
332
type=ActivityTypes.message,
333
text="Hello! How can I help you today?",
334
from_property=ChannelAccount(id="bot", name="HelpBot"),
335
recipient=ChannelAccount(id="user123", name="User"),
336
conversation=ConversationAccount(id="conv456"),
337
channel_id="webchat"
338
)
339
340
# Check if activity has content before sending
341
if activity.has_content():
342
# Activity is ready to send
343
pass
344
```
345
346
### Creating a Reply
347
348
```python
349
# Create a reply to an existing message
350
original_message = Activity(
351
type=ActivityTypes.message,
352
text="What's the weather like?",
353
from_property=ChannelAccount(id="user123"),
354
recipient=ChannelAccount(id="bot"),
355
conversation=ConversationAccount(id="conv456"),
356
id="msg789"
357
)
358
359
# Create reply
360
reply = original_message.create_reply("The weather is sunny with 75°F!")
361
# Reply automatically has from/recipient swapped and reply_to_id set
362
```
363
364
### Working with Conversation References
365
366
```python
367
# Get conversation reference from activity
368
conv_ref = activity.get_conversation_reference()
369
370
# Apply conversation reference to a new activity
371
new_activity = Activity(type=ActivityTypes.typing)
372
new_activity = new_activity.apply_conversation_reference(conv_ref)
373
374
# Create a proactive message using conversation reference
375
proactive_message = Activity(
376
type=ActivityTypes.message,
377
text="This is a proactive message"
378
)
379
proactive_message = proactive_message.apply_conversation_reference(conv_ref, is_incoming=False)
380
```
381
382
### Type-Safe Activity Handling
383
384
```python
385
def handle_activity(activity: Activity):
386
# Check activity type using conversion methods
387
if activity.as_message_activity():
388
print(f"Received message: {activity.text}")
389
elif activity.as_conversation_update_activity():
390
if activity.members_added:
391
print(f"Members added: {[m.name for m in activity.members_added]}")
392
elif activity.as_typing_activity():
393
print("User is typing...")
394
```
395
396
## Additional Activity Models
397
398
### Adaptive Card Models
399
400
Models for handling Adaptive Card invoke operations.
401
402
```python { .api }
403
class AdaptiveCardInvokeAction(Model):
404
def __init__(self, *, type: str = None, title: str = None,
405
id: str = None, data = None, **kwargs): ...
406
407
class AdaptiveCardInvokeValue(Model):
408
def __init__(self, *, action = None, authentication = None, **kwargs): ...
409
410
class AdaptiveCardInvokeResponse(Model):
411
def __init__(self, *, status_code: int = None, type: str = None,
412
value = None, **kwargs): ...
413
```
414
415
### Media Event Models
416
417
Models for media-related activity events.
418
419
```python { .api }
420
class MediaEventValue(Model):
421
def __init__(self, *, card_value = None, **kwargs): ...
422
```
423
424
### Conversation Management Models
425
426
Models for managing conversation data and member information.
427
428
```python { .api }
429
class PagedMembersResult(Model):
430
def __init__(self, *, continuation_token: str = None,
431
members: List = None, **kwargs): ...
432
433
class Transcript(Model):
434
def __init__(self, *, activities: List = None, **kwargs): ...
435
```