Search code examples
pythonemailo365-flow

How do I get the full list of recipients in a specific email with Python's O365 library?


I need to retrieve emails from an account I have access to. I have two conditions:

  1. Email must be unread.
  2. The "to", "cc", and "bcc" fields may not contain a specific address: "[email protected]".

The unread filter (1) works as expected, but for (2), I have learned that it is not possible to add a filter for the "to"/"cc"/"bcc" fields (see Unable to filter messages by recipient in Microsoft Graph Api. One or more invalid nodes). To work around this, I retrieve all of the unread emails and attempt to handle the extra filtering in my code afterwards.
However, there only seems to be an option to get the first address in the "to" field with get_first_recipient_with_address(). I need the full list to be able to check! I don't find another method in the docs

>>> from O365 import Account, FileSystemTokenBackend

# Authenticating the account works fine
>>> credentials = ("client ID", "client secret")
>>> token_backend = FileSystemTokenBackend(token_path='.', token_filename='o365_token.txt')
>>> account = Account(credentials, token_backend=token_backend)

# Making a new query for the inbox:
>>> mailbox = account.mailbox()
>>> inbox = mailbox.inbox_folder()
>>> query = mailbox.new_query()
# Filtering for unread works as expected:
>>> query.on_attribute('isRead').equals(False)
>>> unread_messages = inbox.get_messages(limit=1, query=query)

# Did not succeed in adding a "to" filter to `query`,
# so I want to filter on attributes of the returned emails:
>>> for mess in unread_messages:
...     recipient = mess.to.get_first_recipient_with_address()
...     print(recipient.address)
... 
>>> "[email protected]" 

I know for a fact that the address printed at the end is the first address in the "to" field of the email in question, but I need the full list which should be ["[email protected]", "[email protected]"]

Any ideas or workarounds?


Solution

  • I found a way by looking closer at the source code. There is a hidden variable _recipients that you could use to get the full list like so:

    >>> unread_messages = inbox.get_messages(limit=1, query=query)
    >>> for mess in unread_messages:
    ...     recipients = [rec.address for rec in mess.to._recipients]
    ...     print(recipients)
    ...
    >>> ["[email protected]", "[email protected]"]