coddingtonbear / django-mailbox

Import mail from POP3, IMAP, local email mailboxes or directly from Postfix or Exim4 into your Django application automatically.
MIT License
356 stars 164 forks source link

Office365 API mailbox support #251

Closed Pietro395 closed 1 year ago

Pietro395 commented 2 years ago

We have implemented Office365 API support to read mailboxes. On Office365 IMAP is disabled by default and it is necessary to use Oauth, we used the O365 library to implement this mailbox type.

I have updated the documentation with details on how to set up credentials for Office365. You need to register an application and get client_id, client_secret and tenant_id, the steps are documented here: https://github.com/O365/python-o365#authentication

It's our first pull request in a public project, let us know critical issues about our implementation. We hope that the pull request is appreciated and can be implemented in the main brach.

ckrybus commented 1 year ago

@skar395 thank for you this patch

I've been testing it locally and on staging and it works beautifully :-)

Even though it is not merged yet we'll deploy it to production this week because the dreaded deadline is rapidly approaching.

ptav commented 1 year ago

Have been using this fork on production for about 3 months. No issues reported

coddingtonbear commented 1 year ago

Thanks for confirming that this works, @ptav!

I've had a look at the code under this, and it also looks pretty excellent, really; very nicely done @skar395 & thanks for the patch!

ckrybus commented 1 year ago

I've been testing it locally and on staging and it works beautifully :-)

Even though it is not merged yet we'll deploy it to production this week because the dreaded deadline is rapidly approaching.

Just a quick follow up: after few weeks in production I do not see any issues :+1: Only the last few days there were a few HTTPError: 404 Client Error: Not Found for url: https://graph.microsoft.com/v1.0/users/example@example.com/messages/some-long-base64-encoded-string-here==/$value | Error Message: The specified object was not found in the store. errors.

which caused some downloaded attachments to be empty.

It turns out Microsoft's Office 365 Advanced Threat Protection (ATP) was the culprit. When ATP is ON you can see the emails immediately after they have been received, you can also see how many attachments each email has and even see the attachment file names. But as long as the ATP scan is in progress you cannot download the attachments. The web interface shows an "ATP Scan in progress" message, but the API client sees only that the attachments are empty.

As a quick fix I modified the code a bit:

import datetime as dt
# wait 10 minutes before fetching emails, due to "ATP Scan in progress" some attachments
# are empty when django-mailbox fetches them.
query = self.mailbox_folder.q('received_date_time').less(dt.datetime.now() - dt.timedelta(minutes=10))
for o365message in self.mailbox_folder.get_messages(query=query):

A better solution would be to somehow determine if the attachments are ready for download and only then proceed, but my timebox was up and ultimately I did not find out how to do it.

I don't know how widely used ATP is, etc. I'm posting this here just in case someone has the same issue.

Alejandroid17 commented 1 year ago

Hi @coddingtonbear, is there a release date for a new version with this PR?