0
# Message & Card Factories
1
2
Factory classes for creating rich message activities and card attachments. Simplifies the creation of formatted responses, cards, and other rich content types supported by the Bot Framework.
3
4
## Capabilities
5
6
### MessageFactory
7
8
Static factory class that provides convenient methods for creating various types of message activities, including text messages, attachments, suggested actions, and rich content.
9
10
```python { .api }
11
class MessageFactory:
12
@staticmethod
13
def text(text: str, speak: str = None, input_hint=None):
14
"""
15
Create a text message activity.
16
17
Args:
18
text (str): Message text to display
19
speak (str, optional): Text to speak for voice channels
20
input_hint (optional): Input hint for the client
21
22
Returns:
23
Activity: Message activity with text
24
"""
25
26
@staticmethod
27
def suggested_actions(actions, text: str = None, speak: str = None, input_hint=None):
28
"""
29
Create a message with suggested actions.
30
31
Args:
32
actions (list): List of CardAction objects or strings
33
text (str, optional): Message text
34
speak (str, optional): Text to speak
35
input_hint (optional): Input hint
36
37
Returns:
38
Activity: Message activity with suggested actions
39
"""
40
41
@staticmethod
42
def attachment(attachment, text: str = None, speak: str = None, input_hint=None):
43
"""
44
Create a message with a single attachment.
45
46
Args:
47
attachment (Attachment): Attachment to include
48
text (str, optional): Message text
49
speak (str, optional): Text to speak
50
input_hint (optional): Input hint
51
52
Returns:
53
Activity: Message activity with attachment
54
"""
55
56
@staticmethod
57
def list(attachments, text: str = None, speak: str = None, input_hint=None):
58
"""
59
Create a message with multiple attachments displayed as a list.
60
61
Args:
62
attachments (list): List of Attachment objects
63
text (str, optional): Message text
64
speak (str, optional): Text to speak
65
input_hint (optional): Input hint
66
67
Returns:
68
Activity: Message activity with attachment list
69
"""
70
71
@staticmethod
72
def carousel(attachments, text: str = None, speak: str = None, input_hint=None):
73
"""
74
Create a message with multiple attachments displayed as a carousel.
75
76
Args:
77
attachments (list): List of Attachment objects
78
text (str, optional): Message text
79
speak (str, optional): Text to speak
80
input_hint (optional): Input hint
81
82
Returns:
83
Activity: Message activity with carousel layout
84
"""
85
86
@staticmethod
87
def content_url(url: str, content_type: str, name: str = None, text: str = None,
88
speak: str = None):
89
"""
90
Create a message with a content URL attachment.
91
92
Args:
93
url (str): URL to the content
94
content_type (str): MIME type of the content
95
name (str, optional): Name of the attachment
96
text (str, optional): Message text
97
speak (str, optional): Text to speak
98
99
Returns:
100
Activity: Message activity with content URL
101
"""
102
```
103
104
### CardFactory
105
106
Static factory class that provides methods for creating various types of card attachments supported by the Bot Framework, including Hero Cards, Adaptive Cards, and other rich card types.
107
108
```python { .api }
109
class CardFactory:
110
@staticmethod
111
def adaptive_card(card):
112
"""
113
Create an Adaptive Card attachment.
114
115
Args:
116
card (dict or AdaptiveCard): Adaptive Card JSON or object
117
118
Returns:
119
Attachment: Adaptive Card attachment
120
"""
121
122
@staticmethod
123
def hero_card(title: str, subtitle: str = None, text: str = None, images=None,
124
buttons=None, tap=None):
125
"""
126
Create a Hero Card attachment.
127
128
Args:
129
title (str): Card title
130
subtitle (str, optional): Card subtitle
131
text (str, optional): Card text
132
images (list, optional): List of CardImage objects
133
buttons (list, optional): List of CardAction objects
134
tap (CardAction, optional): Tap action
135
136
Returns:
137
Attachment: Hero Card attachment
138
"""
139
140
@staticmethod
141
def thumbnail_card(title: str, subtitle: str = None, text: str = None, images=None,
142
buttons=None, tap=None):
143
"""
144
Create a Thumbnail Card attachment.
145
146
Args:
147
title (str): Card title
148
subtitle (str, optional): Card subtitle
149
text (str, optional): Card text
150
images (list, optional): List of CardImage objects
151
buttons (list, optional): List of CardAction objects
152
tap (CardAction, optional): Tap action
153
154
Returns:
155
Attachment: Thumbnail Card attachment
156
"""
157
158
@staticmethod
159
def receipt_card(title: str, facts=None, items=None, tap=None, total: str = None,
160
tax: str = None, vat: str = None, buttons=None):
161
"""
162
Create a Receipt Card attachment.
163
164
Args:
165
title (str): Card title
166
facts (list, optional): List of Fact objects
167
items (list, optional): List of ReceiptItem objects
168
tap (CardAction, optional): Tap action
169
total (str, optional): Total amount
170
tax (str, optional): Tax amount
171
vat (str, optional): VAT amount
172
buttons (list, optional): List of CardAction objects
173
174
Returns:
175
Attachment: Receipt Card attachment
176
"""
177
178
@staticmethod
179
def signin_card(text: str, url: str):
180
"""
181
Create a Sign-in Card attachment.
182
183
Args:
184
text (str): Sign-in prompt text
185
url (str): Sign-in URL
186
187
Returns:
188
Attachment: Sign-in Card attachment
189
"""
190
191
@staticmethod
192
def oauth_card(connection_name: str, title: str, text: str = None, url: str = None):
193
"""
194
Create an OAuth Card attachment.
195
196
Args:
197
connection_name (str): OAuth connection name
198
title (str): Card title
199
text (str, optional): Card text
200
url (str, optional): Sign-in URL
201
202
Returns:
203
Attachment: OAuth Card attachment
204
"""
205
206
@staticmethod
207
def animation_card(title: str, subtitle: str = None, text: str = None, image=None,
208
media=None, buttons=None, shareable: bool = None,
209
autoloop: bool = None, autostart: bool = None, aspect: str = None):
210
"""
211
Create an Animation Card attachment.
212
213
Args:
214
title (str): Card title
215
subtitle (str, optional): Card subtitle
216
text (str, optional): Card text
217
image (CardImage, optional): Thumbnail image
218
media (list, optional): List of MediaUrl objects
219
buttons (list, optional): List of CardAction objects
220
shareable (bool, optional): Whether card is shareable
221
autoloop (bool, optional): Whether to autoloop
222
autostart (bool, optional): Whether to autostart
223
aspect (str, optional): Aspect ratio
224
225
Returns:
226
Attachment: Animation Card attachment
227
"""
228
229
@staticmethod
230
def audio_card(title: str, subtitle: str = None, text: str = None, image=None,
231
media=None, buttons=None, shareable: bool = None,
232
autoloop: bool = None, autostart: bool = None):
233
"""
234
Create an Audio Card attachment.
235
236
Args:
237
title (str): Card title
238
subtitle (str, optional): Card subtitle
239
text (str, optional): Card text
240
image (CardImage, optional): Thumbnail image
241
media (list, optional): List of MediaUrl objects
242
buttons (list, optional): List of CardAction objects
243
shareable (bool, optional): Whether card is shareable
244
autoloop (bool, optional): Whether to autoloop
245
autostart (bool, optional): Whether to autostart
246
247
Returns:
248
Attachment: Audio Card attachment
249
"""
250
251
@staticmethod
252
def video_card(title: str, subtitle: str = None, text: str = None, image=None,
253
media=None, buttons=None, shareable: bool = None,
254
autoloop: bool = None, autostart: bool = None, aspect: str = None):
255
"""
256
Create a Video Card attachment.
257
258
Args:
259
title (str): Card title
260
subtitle (str, optional): Card subtitle
261
text (str, optional): Card text
262
image (CardImage, optional): Thumbnail image
263
media (list, optional): List of MediaUrl objects
264
buttons (list, optional): List of CardAction objects
265
shareable (bool, optional): Whether card is shareable
266
autoloop (bool, optional): Whether to autoloop
267
autostart (bool, optional): Whether to autostart
268
aspect (str, optional): Aspect ratio
269
270
Returns:
271
Attachment: Video Card attachment
272
"""
273
274
@staticmethod
275
def actions(actions):
276
"""
277
Create card actions from a list.
278
279
Args:
280
actions (list): List of action dictionaries or CardAction objects
281
282
Returns:
283
list: List of CardAction objects
284
"""
285
286
@staticmethod
287
def images(images):
288
"""
289
Create card images from a list.
290
291
Args:
292
images (list): List of image URLs or CardImage objects
293
294
Returns:
295
list: List of CardImage objects
296
"""
297
298
@staticmethod
299
def media(media):
300
"""
301
Create media URLs from a list.
302
303
Args:
304
media (list): List of media URLs or profile objects
305
306
Returns:
307
list: List of MediaUrl objects
308
"""
309
```
310
311
## Usage Examples
312
313
### Basic Text Messages
314
315
```python
316
from botbuilder.core import MessageFactory, TurnContext
317
318
async def on_message_activity(self, turn_context: TurnContext):
319
# Simple text message
320
reply = MessageFactory.text("Hello! How can I help you today?")
321
await turn_context.send_activity(reply)
322
323
# Text with speech for voice channels
324
reply_with_speech = MessageFactory.text(
325
text="Welcome to our service!",
326
speak="Welcome to our service! How may I assist you today?"
327
)
328
await turn_context.send_activity(reply_with_speech)
329
```
330
331
### Suggested Actions
332
333
```python
334
async def show_options(self, turn_context: TurnContext):
335
# Create suggested actions
336
suggested_actions = [
337
"View Menu",
338
"Place Order",
339
"Contact Support",
340
"About Us"
341
]
342
343
reply = MessageFactory.suggested_actions(
344
actions=suggested_actions,
345
text="What would you like to do?"
346
)
347
348
await turn_context.send_activity(reply)
349
```
350
351
### Hero Card Example
352
353
```python
354
from botbuilder.core import CardFactory, MessageFactory
355
356
async def show_product_card(self, turn_context: TurnContext):
357
# Create hero card
358
card = CardFactory.hero_card(
359
title="Premium Coffee Blend",
360
subtitle="Artisan roasted beans",
361
text="A perfect blend of Colombian and Ethiopian beans, carefully roasted to perfection.",
362
images=[CardFactory.images(["https://example.com/coffee.jpg"])],
363
buttons=[
364
{"type": "imBack", "title": "Buy Now", "value": "buy premium coffee"},
365
{"type": "openUrl", "title": "Learn More", "value": "https://example.com/coffee"},
366
{"type": "postBack", "title": "Add to Cart", "value": "add_to_cart:premium_coffee"}
367
]
368
)
369
370
reply = MessageFactory.attachment(card)
371
await turn_context.send_activity(reply)
372
```
373
374
### Adaptive Card Example
375
376
```python
377
async def show_adaptive_card(self, turn_context: TurnContext):
378
# Define Adaptive Card JSON
379
card_json = {
380
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
381
"type": "AdaptiveCard",
382
"version": "1.2",
383
"body": [
384
{
385
"type": "TextBlock",
386
"text": "Feedback Form",
387
"weight": "Bolder",
388
"size": "Medium"
389
},
390
{
391
"type": "TextBlock",
392
"text": "Please rate your experience:"
393
},
394
{
395
"type": "Input.ChoiceSet",
396
"id": "rating",
397
"style": "compact",
398
"choices": [
399
{"title": "Excellent", "value": "5"},
400
{"title": "Good", "value": "4"},
401
{"title": "Average", "value": "3"},
402
{"title": "Poor", "value": "2"},
403
{"title": "Very Poor", "value": "1"}
404
]
405
},
406
{
407
"type": "Input.Text",
408
"id": "comments",
409
"placeholder": "Additional comments",
410
"isMultiline": True
411
}
412
],
413
"actions": [
414
{
415
"type": "Action.Submit",
416
"title": "Submit Feedback",
417
"data": {"action": "submit_feedback"}
418
}
419
]
420
}
421
422
# Create adaptive card attachment
423
card = CardFactory.adaptive_card(card_json)
424
reply = MessageFactory.attachment(card)
425
426
await turn_context.send_activity(reply)
427
```
428
429
### Carousel of Cards
430
431
```python
432
async def show_product_carousel(self, turn_context: TurnContext):
433
products = [
434
{
435
"title": "Espresso Blend",
436
"subtitle": "Bold and rich",
437
"image": "https://example.com/espresso.jpg",
438
"price": "$12.99"
439
},
440
{
441
"title": "Medium Roast",
442
"subtitle": "Smooth and balanced",
443
"image": "https://example.com/medium.jpg",
444
"price": "$10.99"
445
},
446
{
447
"title": "Dark Roast",
448
"subtitle": "Strong and intense",
449
"image": "https://example.com/dark.jpg",
450
"price": "$11.99"
451
}
452
]
453
454
# Create cards for each product
455
attachments = []
456
for product in products:
457
card = CardFactory.hero_card(
458
title=product["title"],
459
subtitle=product["subtitle"],
460
text=f"Price: {product['price']}",
461
images=[product["image"]],
462
buttons=[
463
{"type": "imBack", "title": "Buy", "value": f"buy {product['title']}"},
464
{"type": "imBack", "title": "Details", "value": f"details {product['title']}"}
465
]
466
)
467
attachments.append(card)
468
469
# Create carousel message
470
reply = MessageFactory.carousel(attachments, "Choose your favorite coffee:")
471
await turn_context.send_activity(reply)
472
```
473
474
### Receipt Card Example
475
476
```python
477
async def show_receipt(self, turn_context: TurnContext, order_details):
478
# Create receipt card
479
card = CardFactory.receipt_card(
480
title="Order Confirmation",
481
facts=[
482
{"key": "Order Number", "value": order_details["order_id"]},
483
{"key": "Payment Method", "value": "Credit Card"},
484
{"key": "Delivery", "value": "Standard (3-5 days)"}
485
],
486
items=[
487
{
488
"title": "Premium Coffee Blend",
489
"subtitle": "1 lb bag",
490
"text": "Quantity: 2",
491
"image": {"url": "https://example.com/coffee.jpg"},
492
"price": "$25.98",
493
"quantity": "2"
494
}
495
],
496
tax="$2.08",
497
total="$28.06",
498
buttons=[
499
{"type": "openUrl", "title": "Track Order", "value": f"https://example.com/track/{order_details['order_id']}"}
500
]
501
)
502
503
reply = MessageFactory.attachment(card)
504
await turn_context.send_activity(reply)
505
```
506
507
### File Attachment Example
508
509
```python
510
async def send_file_attachment(self, turn_context: TurnContext):
511
# Create file attachment
512
file_attachment = {
513
"name": "menu.pdf",
514
"contentType": "application/pdf",
515
"contentUrl": "https://example.com/files/menu.pdf"
516
}
517
518
reply = MessageFactory.attachment(
519
attachment=file_attachment,
520
text="Here's our current menu:"
521
)
522
523
await turn_context.send_activity(reply)
524
```
525
526
### OAuth Sign-in Card
527
528
```python
529
async def show_signin_card(self, turn_context: TurnContext):
530
# Create OAuth card
531
card = CardFactory.oauth_card(
532
connection_name="MyOAuthConnection",
533
title="Please sign in",
534
text="You need to sign in to access this feature."
535
)
536
537
reply = MessageFactory.attachment(card)
538
await turn_context.send_activity(reply)
539
```
540
541
### Media Cards
542
543
```python
544
async def show_video_card(self, turn_context: TurnContext):
545
# Create video card
546
card = CardFactory.video_card(
547
title="Coffee Brewing Tutorial",
548
subtitle="Learn the perfect brewing technique",
549
text="Watch this 5-minute tutorial to master coffee brewing.",
550
image={"url": "https://example.com/video-thumbnail.jpg"},
551
media=[{"url": "https://example.com/brewing-tutorial.mp4"}],
552
buttons=[
553
{"type": "openUrl", "title": "Full Tutorial", "value": "https://example.com/full-tutorial"}
554
],
555
autostart=False,
556
shareable=True
557
)
558
559
reply = MessageFactory.attachment(card)
560
await turn_context.send_activity(reply)
561
562
async def show_audio_card(self, turn_context: TurnContext):
563
# Create audio card
564
card = CardFactory.audio_card(
565
title="Coffee Shop Ambiance",
566
subtitle="Relaxing cafe sounds",
567
text="Enjoy the soothing sounds of a busy coffee shop.",
568
image={"url": "https://example.com/cafe.jpg"},
569
media=[{"url": "https://example.com/cafe-sounds.mp3"}],
570
autoloop=True,
571
shareable=True
572
)
573
574
reply = MessageFactory.attachment(card)
575
await turn_context.send_activity(reply)
576
```
577
578
## Types
579
580
```python { .api }
581
class Attachment:
582
"""File or card attachment."""
583
name: str
584
content_type: str
585
content: object
586
content_url: str
587
thumbnail_url: str
588
589
class CardAction:
590
"""Action button on a card."""
591
type: str # "imBack", "postBack", "openUrl", "signin", "playAudio", etc.
592
title: str
593
value: str
594
text: str
595
display_text: str
596
image: str
597
598
class CardImage:
599
"""Image on a card."""
600
url: str
601
alt: str
602
tap: CardAction
603
604
class SuggestedActions:
605
"""Suggested actions for user input."""
606
to: list
607
actions: list
608
609
class Fact:
610
"""Name-value pair for receipt cards."""
611
key: str
612
value: str
613
614
class ReceiptItem:
615
"""Item on a receipt card."""
616
title: str
617
subtitle: str
618
text: str
619
image: CardImage
620
price: str
621
quantity: str
622
tap: CardAction
623
624
class MediaUrl:
625
"""Media URL for media cards."""
626
url: str
627
profile: str
628
```