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
```