Search code examples
pythonexchangelib

Syncronize mails with Exchangelib's "sync_item" doesn't work second time


I'm using ExchangeLib to access my Mailbox and create some kind of a mail listener:

# Register and create inbox object
account = Account(primary_smtp_address=mail,
                                   credentials=credentials,
                                   config=config)
inbox=account.inbox
subscriptionId = inbox.subscribe_to_streaming(event_types=[NewMailEvent.ELEMENT_NAME])

# define filters
only=["subject", "body", "datetime_sent", "attachments", "sender"]

while True:
    for notification in inbox.get_streaming_events(
            subscriptionId, connection_timeout=30):
        # Retrieve mails via item id and changekey
        mailList = [inbox.get(id=event.item_id.id,
                              changekey=event.item_id.changekey)
                    for event in notification.events]

When I run this it works perfectly the first time the sync_items is called. The second time however (when the get_streaming_events notifies about new elements) it's quite unreliable and a lot of times I'm unable to retrieve mail items via mailItems[sync[1] for sync in syncGenerator].

My initial approach was to add syncState in order to avoid ignoring mails by calling sync_items multiple time by accident and not returning anything. This however didn't solve the issue. I also experimented with max_changes_returned=1 to exclude the problem of a too large amount of mails.

I would appreciate suggestions on whether I'm making any mistakes using sync_items or if I should use another way of accessing the mails.

Thanks a lot!

Edit 1: I replaced the use of inbox.sync_items() with the inbox.get() functionality. However, this is stuck as well.

Edit 2: I checked in a more general sense. Accessing the inboxmails via inbox.filter(some_filter) is possible before get_streaming_events but somehow not afterwards. Maybe the issue could be connected to this.


Solution

  • Subscription sync (Folder.get_streaming_events()) and item sync (Folder.sync_items()) are two entirely different sync strategies and should not be combined. The former returns notification objects containing item IDs that you can use to look up the full object (inbox.get(id=some_id, changekey=some_changekey)).

    The exchangelib documentation has full examples of using either strategy: https://ecederstrand.github.io/exchangelib/#synchronization-subscriptions-and-notifications