or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

activity-handling.mdbot-adapters.mdindex.mdmessage-factories.mdmiddleware.mdoauth-authentication.mdstate-management.mdstorage.mdtelemetry-logging.mdtesting-utilities.mdturn-context.md

message-factories.mddocs/

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

```