or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

authentication.mddirectory-services.mdemail-calendar.mdindex.mdonedrive-files.mdsharepoint-sites.mdteams.md

email-calendar.mddocs/

0

# Email & Calendar Services

1

2

Outlook integration for email, calendar, contacts, and mailbox management through Microsoft Graph API with comprehensive messaging capabilities. Provides complete communication and scheduling functionality for Microsoft 365 environments.

3

4

## Capabilities

5

6

### Email Management

7

8

Comprehensive email operations including message composition, sending, receiving, organizing, and attachment management with support for rich content and advanced features.

9

10

```python { .api }

11

class Message:

12

"""Outlook email message with comprehensive content and management capabilities."""

13

14

# Core Properties

15

id: str

16

created_date_time: str

17

last_modified_date_time: str

18

change_key: str

19

categories: List[str]

20

received_date_time: str

21

sent_date_time: str

22

has_attachments: bool

23

internet_message_id: str

24

subject: str

25

body_preview: str

26

importance: str # "low", "normal", "high"

27

inference_classification: str

28

is_delivery_receipt_requested: bool

29

is_draft: bool

30

is_read: bool

31

is_read_receipt_requested: bool

32

web_link: str

33

34

def get(self) -> 'Message':

35

"""

36

Retrieve message information and content.

37

38

Returns:

39

Message: Updated message object

40

"""

41

42

def update(self) -> 'Message':

43

"""

44

Update message properties.

45

46

Returns:

47

Message: Updated message object

48

"""

49

50

def delete(self) -> None:

51

"""Delete message (move to Deleted Items)."""

52

53

def send(self) -> None:

54

"""Send draft message."""

55

56

def reply(self, comment: str = None) -> 'Message':

57

"""

58

Create reply to message.

59

60

Args:

61

comment (str, optional): Reply comment

62

63

Returns:

64

Message: Reply message draft

65

"""

66

67

def reply_all(self, comment: str = None) -> 'Message':

68

"""

69

Create reply-all to message.

70

71

Args:

72

comment (str, optional): Reply comment

73

74

Returns:

75

Message: Reply-all message draft

76

"""

77

78

def forward(self, comment: str = None, to_recipients: List[Dict[str, str]] = None) -> 'Message':

79

"""

80

Create forward of message.

81

82

Args:

83

comment (str, optional): Forward comment

84

to_recipients (List[Dict], optional): Forward recipients

85

86

Returns:

87

Message: Forward message draft

88

"""

89

90

def copy(self, destination_id: str) -> 'Message':

91

"""

92

Copy message to folder.

93

94

Args:

95

destination_id (str): Destination folder ID

96

97

Returns:

98

Message: Copied message

99

"""

100

101

def move(self, destination_id: str) -> 'Message':

102

"""

103

Move message to folder.

104

105

Args:

106

destination_id (str): Destination folder ID

107

108

Returns:

109

Message: Moved message

110

"""

111

112

# Navigation Properties

113

@property

114

def body(self) -> 'ItemBody':

115

"""Message body content."""

116

117

@property

118

def from_(self) -> 'Recipient':

119

"""Message sender."""

120

121

@property

122

def sender(self) -> 'Recipient':

123

"""Message sender (may differ from from_ for delegates)."""

124

125

@property

126

def to_recipients(self) -> List['Recipient']:

127

"""Primary recipients."""

128

129

@property

130

def cc_recipients(self) -> List['Recipient']:

131

"""CC recipients."""

132

133

@property

134

def bcc_recipients(self) -> List['Recipient']:

135

"""BCC recipients."""

136

137

@property

138

def reply_to(self) -> List['Recipient']:

139

"""Reply-to recipients."""

140

141

@property

142

def attachments(self) -> 'AttachmentCollection':

143

"""Message attachments."""

144

145

@property

146

def extensions(self) -> 'ExtensionCollection':

147

"""Message extensions."""

148

149

class MessageCollection:

150

"""Collection of email messages with query and management capabilities."""

151

152

def get(self) -> 'MessageCollection':

153

"""Retrieve collection of messages."""

154

155

def filter(self, expression: str) -> 'MessageCollection':

156

"""

157

Filter messages by OData expression.

158

159

Args:

160

expression (str): OData filter expression

161

162

Returns:

163

MessageCollection: Filtered collection

164

"""

165

166

def select(self, properties: List[str]) -> 'MessageCollection':

167

"""

168

Select specific properties to retrieve.

169

170

Args:

171

properties (List[str]): Property names to select

172

173

Returns:

174

MessageCollection: Collection with selected properties

175

"""

176

177

def top(self, count: int) -> 'MessageCollection':

178

"""

179

Limit results to top N messages.

180

181

Args:

182

count (int): Maximum number of messages

183

184

Returns:

185

MessageCollection: Limited collection

186

"""

187

188

def order_by(self, property_name: str, ascending: bool = True) -> 'MessageCollection':

189

"""

190

Sort messages by property.

191

192

Args:

193

property_name (str): Property to sort by

194

ascending (bool): Sort direction

195

196

Returns:

197

MessageCollection: Sorted collection

198

"""

199

200

def get_by_id(self, message_id: str) -> Message:

201

"""

202

Get message by ID.

203

204

Args:

205

message_id (str): Message unique identifier

206

207

Returns:

208

Message: Message object

209

"""

210

211

def add(self, message_info: Dict[str, Any]) -> Message:

212

"""

213

Create new message (draft).

214

215

Args:

216

message_info (Dict): Message properties

217

218

Returns:

219

Message: Created message draft

220

"""

221

222

def send_mail(self, message: Dict[str, Any], save_to_sent_items: bool = True) -> None:

223

"""

224

Send message directly without creating draft.

225

226

Args:

227

message (Dict): Message content and recipients

228

save_to_sent_items (bool): Save copy to Sent Items

229

"""

230

```

231

232

### Mail Folder Management

233

234

Email folder organization with support for custom folders, folder hierarchy, and message organization rules.

235

236

```python { .api }

237

class MailFolder:

238

"""Outlook mail folder with comprehensive message organization capabilities."""

239

240

# Core Properties

241

id: str

242

display_name: str

243

parent_folder_id: str

244

child_folder_count: int

245

unread_item_count: int

246

total_item_count: int

247

size_in_bytes: int

248

is_hidden: bool

249

250

def get(self) -> 'MailFolder':

251

"""

252

Retrieve folder information.

253

254

Returns:

255

MailFolder: Updated folder object

256

"""

257

258

def update(self) -> 'MailFolder':

259

"""

260

Update folder properties.

261

262

Returns:

263

MailFolder: Updated folder object

264

"""

265

266

def delete(self) -> None:

267

"""Delete folder and all contents."""

268

269

def copy(self, destination_id: str) -> 'MailFolder':

270

"""

271

Copy folder to destination.

272

273

Args:

274

destination_id (str): Destination folder ID

275

276

Returns:

277

MailFolder: Copied folder

278

"""

279

280

def move(self, destination_id: str) -> 'MailFolder':

281

"""

282

Move folder to destination.

283

284

Args:

285

destination_id (str): Destination folder ID

286

287

Returns:

288

MailFolder: Moved folder

289

"""

290

291

# Navigation Properties

292

@property

293

def messages(self) -> MessageCollection:

294

"""Messages in the folder."""

295

296

@property

297

def child_folders(self) -> 'MailFolderCollection':

298

"""Child folders."""

299

300

@property

301

def message_rules(self) -> 'MessageRuleCollection':

302

"""Message rules for the folder."""

303

304

class MailFolderCollection:

305

"""Collection of mail folders with management capabilities."""

306

307

def get(self) -> 'MailFolderCollection':

308

"""Retrieve collection of folders."""

309

310

def filter(self, expression: str) -> 'MailFolderCollection':

311

"""

312

Filter folders by expression.

313

314

Args:

315

expression (str): OData filter expression

316

317

Returns:

318

MailFolderCollection: Filtered collection

319

"""

320

321

def get_by_id(self, folder_id: str) -> MailFolder:

322

"""

323

Get folder by ID.

324

325

Args:

326

folder_id (str): Folder unique identifier

327

328

Returns:

329

MailFolder: Folder object

330

"""

331

332

def add(self, folder_info: Dict[str, Any]) -> MailFolder:

333

"""

334

Create new folder.

335

336

Args:

337

folder_info (Dict): Folder properties

338

339

Returns:

340

MailFolder: Created folder

341

"""

342

```

343

344

### Calendar Management

345

346

Comprehensive calendar functionality including event creation, scheduling, meeting management, and calendar sharing with support for recurring events and attendee management.

347

348

```python { .api }

349

class Calendar:

350

"""Outlook calendar with comprehensive scheduling and event management."""

351

352

# Core Properties

353

id: str

354

name: str

355

color: str

356

change_key: str

357

can_share: bool

358

can_view_private_items: bool

359

can_edit: bool

360

allowed_online_meeting_providers: List[str]

361

default_online_meeting_provider: str

362

is_tale_enabled: bool

363

is_removable: bool

364

365

def get(self) -> 'Calendar':

366

"""

367

Retrieve calendar information.

368

369

Returns:

370

Calendar: Updated calendar object

371

"""

372

373

def update(self) -> 'Calendar':

374

"""

375

Update calendar properties.

376

377

Returns:

378

Calendar: Updated calendar object

379

"""

380

381

def delete(self) -> None:

382

"""Delete calendar."""

383

384

def get_schedule(self, schedules: List[str], start_time: str, end_time: str, availability_view_interval: int = 60) -> List[Dict[str, Any]]:

385

"""

386

Get free/busy information for specified time range.

387

388

Args:

389

schedules (List[str]): Email addresses to check

390

start_time (str): Start time (ISO 8601)

391

end_time (str): End time (ISO 8601)

392

availability_view_interval (int): Interval in minutes

393

394

Returns:

395

List[Dict]: Free/busy information

396

"""

397

398

# Navigation Properties

399

@property

400

def events(self) -> 'EventCollection':

401

"""Events in the calendar."""

402

403

@property

404

def calendar_view(self) -> 'EventCollection':

405

"""Calendar view of events."""

406

407

class CalendarCollection:

408

"""Collection of calendars with management capabilities."""

409

410

def get(self) -> 'CalendarCollection':

411

"""Retrieve collection of calendars."""

412

413

def get_by_id(self, calendar_id: str) -> Calendar:

414

"""

415

Get calendar by ID.

416

417

Args:

418

calendar_id (str): Calendar unique identifier

419

420

Returns:

421

Calendar: Calendar object

422

"""

423

424

def add(self, calendar_info: Dict[str, Any]) -> Calendar:

425

"""

426

Create new calendar.

427

428

Args:

429

calendar_info (Dict): Calendar properties

430

431

Returns:

432

Calendar: Created calendar

433

"""

434

435

class Event:

436

"""Calendar event with comprehensive scheduling and attendee management."""

437

438

# Core Properties

439

id: str

440

created_date_time: str

441

last_modified_date_time: str

442

change_key: str

443

categories: List[str]

444

original_start_time_zone: str

445

original_end_time_zone: str

446

i_cal_u_id: str

447

reminder_minutes_before_start: int

448

is_reminder_on: bool

449

has_attachments: bool

450

subject: str

451

importance: str

452

sensitivity: str

453

is_all_day: bool

454

is_cancelled: bool

455

is_organizer: bool

456

response_requested: bool

457

series_master_id: str

458

show_as: str # "free", "tentative", "busy", "oof", "workingElsewhere"

459

type: str # "singleInstance", "occurrence", "exception", "seriesMaster"

460

web_link: str

461

462

def get(self) -> 'Event':

463

"""

464

Retrieve event information.

465

466

Returns:

467

Event: Updated event object

468

"""

469

470

def update(self) -> 'Event':

471

"""

472

Update event properties.

473

474

Returns:

475

Event: Updated event object

476

"""

477

478

def delete(self) -> None:

479

"""Delete event."""

480

481

def accept(self, comment: str = None, send_response: bool = True) -> None:

482

"""

483

Accept meeting invitation.

484

485

Args:

486

comment (str, optional): Response comment

487

send_response (bool): Send response to organizer

488

"""

489

490

def decline(self, comment: str = None, send_response: bool = True) -> None:

491

"""

492

Decline meeting invitation.

493

494

Args:

495

comment (str, optional): Response comment

496

send_response (bool): Send response to organizer

497

"""

498

499

def tentatively_accept(self, comment: str = None, send_response: bool = True) -> None:

500

"""

501

Tentatively accept meeting invitation.

502

503

Args:

504

comment (str, optional): Response comment

505

send_response (bool): Send response to organizer

506

"""

507

508

def cancel(self, comment: str = None) -> None:

509

"""

510

Cancel event (organizer only).

511

512

Args:

513

comment (str, optional): Cancellation comment

514

"""

515

516

def dismiss_reminder(self) -> None:

517

"""Dismiss event reminder."""

518

519

def snooze_reminder(self, new_reminder_time: str) -> None:

520

"""

521

Snooze event reminder.

522

523

Args:

524

new_reminder_time (str): New reminder time (ISO 8601)

525

"""

526

527

def forward(self, to_recipients: List[Dict[str, str]], comment: str = None) -> None:

528

"""

529

Forward meeting invitation.

530

531

Args:

532

to_recipients (List[Dict]): Recipients to forward to

533

comment (str, optional): Forward comment

534

"""

535

536

# Navigation Properties

537

@property

538

def body(self) -> 'ItemBody':

539

"""Event body content."""

540

541

@property

542

def start(self) -> 'DateTimeTimeZone':

543

"""Event start time."""

544

545

@property

546

def end(self) -> 'DateTimeTimeZone':

547

"""Event end time."""

548

549

@property

550

def location(self) -> 'Location':

551

"""Event location."""

552

553

@property

554

def locations(self) -> List['Location']:

555

"""Multiple event locations."""

556

557

@property

558

def attendees(self) -> List['Attendee']:

559

"""Event attendees."""

560

561

@property

562

def organizer(self) -> 'Recipient':

563

"""Event organizer."""

564

565

@property

566

def recurrence(self) -> 'PatternedRecurrence':

567

"""Event recurrence pattern."""

568

569

@property

570

def attachments(self) -> 'AttachmentCollection':

571

"""Event attachments."""

572

573

@property

574

def online_meeting(self) -> 'OnlineMeetingInfo':

575

"""Online meeting information."""

576

577

@property

578

def instances(self) -> 'EventCollection':

579

"""Event instances (for recurring events)."""

580

581

class EventCollection:

582

"""Collection of calendar events with query and management capabilities."""

583

584

def get(self) -> 'EventCollection':

585

"""Retrieve collection of events."""

586

587

def filter(self, expression: str) -> 'EventCollection':

588

"""

589

Filter events by expression.

590

591

Args:

592

expression (str): OData filter expression

593

594

Returns:

595

EventCollection: Filtered collection

596

"""

597

598

def select(self, properties: List[str]) -> 'EventCollection':

599

"""

600

Select specific properties.

601

602

Args:

603

properties (List[str]): Property names to select

604

605

Returns:

606

EventCollection: Collection with selected properties

607

"""

608

609

def top(self, count: int) -> 'EventCollection':

610

"""

611

Limit results to top N events.

612

613

Args:

614

count (int): Maximum number of events

615

616

Returns:

617

EventCollection: Limited collection

618

"""

619

620

def order_by(self, property_name: str, ascending: bool = True) -> 'EventCollection':

621

"""

622

Sort events by property.

623

624

Args:

625

property_name (str): Property to sort by

626

ascending (bool): Sort direction

627

628

Returns:

629

EventCollection: Sorted collection

630

"""

631

632

def get_by_id(self, event_id: str) -> Event:

633

"""

634

Get event by ID.

635

636

Args:

637

event_id (str): Event unique identifier

638

639

Returns:

640

Event: Event object

641

"""

642

643

def add(self, event_info: Dict[str, Any]) -> Event:

644

"""

645

Create new event.

646

647

Args:

648

event_info (Dict): Event properties

649

650

Returns:

651

Event: Created event

652

"""

653

```

654

655

### Attachment Management

656

657

File and item attachment support with comprehensive attachment handling for both email messages and calendar events.

658

659

```python { .api }

660

class Attachment:

661

"""Base attachment class with common properties and operations."""

662

663

# Core Properties

664

id: str

665

last_modified_date_time: str

666

name: str

667

content_type: str

668

size: int

669

is_inline: bool

670

671

def get(self) -> 'Attachment':

672

"""

673

Retrieve attachment information.

674

675

Returns:

676

Attachment: Updated attachment object

677

"""

678

679

def delete(self) -> None:

680

"""Delete attachment."""

681

682

class FileAttachment(Attachment):

683

"""File attachment with content access."""

684

685

# Additional Properties

686

content_id: str

687

content_location: str

688

content_bytes: bytes

689

690

def get_content(self) -> bytes:

691

"""

692

Get attachment content.

693

694

Returns:

695

bytes: Attachment content as bytes

696

"""

697

698

class ItemAttachment(Attachment):

699

"""Outlook item attachment (message, event, contact)."""

700

701

# Navigation Properties

702

@property

703

def item(self) -> 'OutlookItem':

704

"""Attached Outlook item."""

705

706

class ReferenceAttachment(Attachment):

707

"""Reference attachment pointing to cloud content."""

708

709

# Additional Properties

710

source_url: str

711

provider_type: str

712

thumbnail_url: str

713

preview_url: str

714

permission: str

715

is_folder: bool

716

717

class AttachmentCollection:

718

"""Collection of attachments with management capabilities."""

719

720

def get(self) -> 'AttachmentCollection':

721

"""Retrieve collection of attachments."""

722

723

def get_by_id(self, attachment_id: str) -> Attachment:

724

"""

725

Get attachment by ID.

726

727

Args:

728

attachment_id (str): Attachment unique identifier

729

730

Returns:

731

Attachment: Attachment object

732

"""

733

734

def add(self, attachment_info: Dict[str, Any]) -> Attachment:

735

"""

736

Add new attachment.

737

738

Args:

739

attachment_info (Dict): Attachment properties and content

740

741

Returns:

742

Attachment: Created attachment

743

"""

744

```

745

746

## Usage Examples

747

748

### Email Operations

749

750

```python

751

from office365.graph_client import GraphClient

752

753

client = GraphClient.with_client_secret(client_id, client_secret, tenant)

754

755

# Get user's messages

756

messages = client.me.messages.top(10).get().execute_query()

757

for message in messages:

758

print(f"From: {message.from_['emailAddress']['name']}, Subject: {message.subject}")

759

760

# Send email

761

message_info = {

762

"subject": "Project Update",

763

"body": {

764

"contentType": "html",

765

"content": "<h1>Project Status</h1><p>The project is on track for completion next week.</p>"

766

},

767

"toRecipients": [

768

{

769

"emailAddress": {

770

"address": "colleague@company.com",

771

"name": "Colleague Name"

772

}

773

}

774

]

775

}

776

777

client.me.send_mail(message_info, save_to_sent_items=True).execute_query()

778

print("Email sent successfully")

779

780

# Create draft with attachment

781

draft_info = {

782

"subject": "Report with Attachment",

783

"body": {

784

"contentType": "text",

785

"content": "Please find the attached report."

786

},

787

"toRecipients": [

788

{"emailAddress": {"address": "manager@company.com"}}

789

]

790

}

791

792

draft = client.me.messages.add(draft_info).execute_query()

793

794

# Add file attachment

795

with open("report.pdf", "rb") as file_content:

796

attachment_info = {

797

"@odata.type": "#microsoft.graph.fileAttachment",

798

"name": "monthly_report.pdf",

799

"contentType": "application/pdf",

800

"contentBytes": file_content.read()

801

}

802

draft.attachments.add(attachment_info).execute_query()

803

804

# Send draft

805

draft.send().execute_query()

806

```

807

808

### Calendar Operations

809

810

```python

811

# Get user's calendar events

812

events = client.me.events.filter("start/dateTime ge '2024-01-01T00:00:00Z'").top(5).get().execute_query()

813

for event in events:

814

print(f"Event: {event.subject}, Start: {event.start['dateTime']}")

815

816

# Create calendar event

817

event_info = {

818

"subject": "Team Meeting",

819

"body": {

820

"contentType": "html",

821

"content": "Weekly team sync meeting"

822

},

823

"start": {

824

"dateTime": "2024-02-15T10:00:00",

825

"timeZone": "UTC"

826

},

827

"end": {

828

"dateTime": "2024-02-15T11:00:00",

829

"timeZone": "UTC"

830

},

831

"location": {

832

"displayName": "Conference Room A"

833

},

834

"attendees": [

835

{

836

"emailAddress": {

837

"address": "team@company.com",

838

"name": "Team Members"

839

},

840

"type": "required"

841

}

842

],

843

"reminderMinutesBeforeStart": 15,

844

"recurrence": {

845

"pattern": {

846

"type": "weekly",

847

"interval": 1,

848

"daysOfWeek": ["thursday"]

849

},

850

"range": {

851

"type": "endDate",

852

"startDate": "2024-02-15",

853

"endDate": "2024-06-15"

854

}

855

}

856

}

857

858

new_event = client.me.events.add(event_info).execute_query()

859

print(f"Created recurring event: {new_event.subject}")

860

```

861

862

### Mail Folder Management

863

864

```python

865

# Get mail folders

866

folders = client.me.mail_folders.get().execute_query()

867

for folder in folders:

868

print(f"Folder: {folder.display_name}, Unread: {folder.unread_item_count}")

869

870

# Create custom folder

871

folder_info = {

872

"displayName": "Project Communications"

873

}

874

new_folder = client.me.mail_folders.add(folder_info).execute_query()

875

876

# Move messages to folder

877

inbox = client.me.mail_folders.filter("displayName eq 'Inbox'").get().execute_query()[0]

878

project_messages = inbox.messages.filter("contains(subject, 'Project Alpha')").get().execute_query()

879

880

for message in project_messages:

881

message.move(new_folder.id).execute_query()

882

print(f"Moved message: {message.subject}")

883

```

884

885

## Types

886

887

```python { .api }

888

from typing import Dict, List, Any, Optional

889

890

class ItemBody:

891

"""Content body for messages and events."""

892

893

content_type: str # "text" or "html"

894

content: str

895

896

class Recipient:

897

"""Email recipient information."""

898

899

email_address: Dict[str, str] # {"name": str, "address": str}

900

901

class DateTimeTimeZone:

902

"""Date and time with timezone information."""

903

904

date_time: str # ISO 8601 format

905

time_zone: str # Timezone identifier

906

907

class Location:

908

"""Event location information."""

909

910

display_name: str

911

location_email_address: str

912

address: Dict[str, str]

913

coordinates: Dict[str, float]

914

location_uri: str

915

location_type: str

916

unique_id: str

917

unique_id_type: str

918

919

class Attendee:

920

"""Event attendee with response information."""

921

922

type: str # "required", "optional", "resource"

923

status: Dict[str, str] # {"response": str, "time": str}

924

email_address: Dict[str, str]

925

926

class PatternedRecurrence:

927

"""Event recurrence pattern."""

928

929

pattern: Dict[str, Any] # Recurrence pattern details

930

range: Dict[str, Any] # Recurrence range details

931

932

class RecurrencePattern:

933

"""Recurrence pattern details."""

934

935

type: str # "daily", "weekly", "monthly", etc.

936

interval: int

937

month: int

938

day_of_month: int

939

days_of_week: List[str]

940

first_day_of_week: str

941

index: str

942

943

class RecurrenceRange:

944

"""Recurrence range details."""

945

946

type: str # "endDate", "noEnd", "numbered"

947

start_date: str

948

end_date: str

949

recurrence_time_zone: str

950

number_of_occurrences: int

951

952

class OnlineMeetingInfo:

953

"""Online meeting information for events."""

954

955

conference_id: str

956

join_url: str

957

phones: List[Dict[str, str]]

958

quick_dial: str

959

toll_free_numbers: List[str]

960

toll_number: str

961

962

class MessageRule:

963

"""Email rule for automatic message processing."""

964

965

id: str

966

display_name: str

967

sequence: int

968

is_enabled: bool

969

has_error: bool

970

conditions: Dict[str, Any]

971

actions: Dict[str, Any]

972

exceptions: Dict[str, Any]

973

974

class MailboxSettings:

975

"""User mailbox configuration settings."""

976

977

archive_folder: str

978

automatic_replies_setting: Dict[str, Any]

979

date_format: str

980

delegate_meeting_message_delivery_options: str

981

language: Dict[str, str]

982

time_format: str

983

time_zone: str

984

working_hours: Dict[str, Any]

985

```