Skip to content

Commit ef97c4f

Browse files
authored
Merge pull request #667 from padamscrestonecapital/master
Add ability to pass b64 formatted string when adding attachments
2 parents 11a408c + cb03ad1 commit ef97c4f

File tree

4 files changed

+62
-6
lines changed

4 files changed

+62
-6
lines changed
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import base64
2+
3+
from examples import acquire_token_by_username_password
4+
from office365.graph_client import GraphClient
5+
6+
7+
# Multple "add_file_attachment" calls can be chained before "execute_query" to add multiple attachments
8+
9+
with open(r"path\to\file\test.pdf", "rb") as f:
10+
content = base64.b64encode(f.read()).decode()
11+
client = GraphClient(acquire_token_by_username_password)
12+
client.me.messages.add(
13+
subject="Meet for lunch?",
14+
body="The new cafeteria is open.",
15+
to_recipients=["fannyd@contoso.onmicrosoft.com"]
16+
).add_file_attachment("attachment.txt", content_type="application/pdf", base64_content=content).execute_query()

office365/outlook/mail/attachments/collection.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,19 +12,27 @@ class AttachmentCollection(EntityCollection):
1212
def __init__(self, context, resource_path=None):
1313
super(AttachmentCollection, self).__init__(context, Attachment, resource_path)
1414

15-
def add_file(self, name, content, content_type=None):
15+
def add_file(self, name, content=None, content_type=None, base64_content=None):
1616
"""
1717
Attach a file to message
1818
1919
:param str name: The name representing the text that is displayed below the icon representing the
2020
embedded attachment
21-
:param str content: The contents of the file
21+
:param str or None content: The contents of the file
2222
:param str or None content_type: The content type of the attachment.
23+
:param str or None base64_content: The contents of the file in the form of a base64 string.
2324
"""
25+
if not content and not base64_content:
26+
raise TypeError("Either content or base64_content is required")
2427
from office365.outlook.mail.attachments.file import FileAttachment
28+
2529
return_type = FileAttachment(self.context)
2630
return_type.name = name
27-
return_type.content_bytes = base64.b64encode(content.encode("utf-8")).decode("utf-8")
31+
if base64_content:
32+
content = base64_content
33+
else:
34+
content = base64.b64encode(content.encode("utf-8")).decode("utf-8")
35+
return_type.content_bytes = content
2836
return_type.content_type = content_type
2937
self.add_child(return_type)
3038
return self

office365/outlook/mail/messages/message.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,16 +60,21 @@ def get_content(self):
6060
self.context.add_query(qry)
6161
return return_type
6262

63-
def add_file_attachment(self, name, content, content_type=None):
63+
def add_file_attachment(
64+
self, name, content=None, content_type=None, base64_content=None
65+
):
6466
"""
6567
Attach a file to message
6668
6769
:param str name: The name representing the text that is displayed below the icon representing the
6870
embedded attachment
69-
:param str content: The contents of the file
71+
:param str or None content: The contents of the file
7072
:param str or None content_type: The content type of the attachment.
73+
:param str or None base64_content: The contents of the file in the form of a base64 string.
7174
"""
72-
self.attachments.add_file(name, content, content_type)
75+
if not content and not base64_content:
76+
raise TypeError("Either content or base64_content is required")
77+
self.attachments.add_file(name, content, content_type, base64_content)
7378
return self
7479

7580
def upload_attachment(self, file_path, chunk_uploaded=None):

tests/outlook/test_messages.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
import base64
2+
import io
3+
14
from office365.outlook.mail.messages.message import Message
25
from office365.outlook.mail.recipient import Recipient
36
from tests import test_user_principal_name, test_user_principal_name_alt
@@ -44,3 +47,27 @@ def test_7_delete_message(self):
4447
messages = self.client.me.messages.top(1).get().execute_query()
4548
message_to_delete = messages[0]
4649
message_to_delete.delete_object().execute_query()
50+
51+
def test_8_create_draft_message_with_attachments(self):
52+
content = base64.b64encode(
53+
io.BytesIO(b"This is some file content").read()
54+
).decode()
55+
draft = (
56+
self.client.me
57+
.messages.add(
58+
subject="Check out this attachment", body="The new cafeteria is open."
59+
)
60+
.add_file_attachment("test.txt", "Hello World!")
61+
.add_file_attachment("test2.txt", base64_content=content)
62+
.execute_query()
63+
)
64+
assert (
65+
len(
66+
self.client.me
67+
.messages[draft.id]
68+
.attachments.get()
69+
.execute_query()
70+
)
71+
== 2
72+
)
73+
draft.delete_object().execute_query()

0 commit comments

Comments
 (0)