2

I want to send an Email from my outlook account using Python. I used the below code running in an AWS EC2 instance to generate an email.

import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart

server = smtplib.SMTP('smtp.office365.com', 587)
server.starttls()
server.login("<outlook_mail_id>","<outlook_password>")

server.sendmail("<outlook_mail_id>", "<recipient_email_id> ", "Test Message")
server.quit()

But while running this I get the below error

Traceback (most recent call last):
  File "smtp_office_365.py", line 12, in <module>
    server.login("<outlook_email_id>","<outlook_pass>")
  File "/usr/local/lib/python3.8/smtplib.py", line 734, in login
    raise last_exception
  File "/usr/local/lib/python3.8/smtplib.py", line 723, in login
    (code, resp) = self.auth(
  File "/usr/local/lib/python3.8/smtplib.py", line 646, in auth
    raise SMTPAuthenticationError(code, resp)
smtplib.SMTPAuthenticationError: (535, b'5.7.3 Authentication unsuccessful [MN2PR15CA0001.namprd15.prod.outlook.com]')

I am able to login into web outlook account using these credentials. Hence to check further I connected with my Admin team and they said that Basic Authentication is disabled for this account and can't be enabled in any case. They suggested me to use modern Authentication method by using Microsoft Online Exchange.

On further exploration I found the below script to send the mail

from exchangelib import DELEGATE, IMPERSONATION, Account, Credentials, Configuration

credentials = Credentials('<outlook_mail_id>', '<outlook_password>')
account = Account('<outlook_mail_id>', credentials=credentials, autodiscover=True)
 
for item in account.inbox.all().order_by('-datetime_received')[:100]:
    print(item.subject, item.sender, item.datetime_received)

But I get the below error while running the script

Traceback (most recent call last):
  File "test_exchange.py", line 5, in <module>
    account = Account('<outlook_email_id>', credentials=credentials, autodiscover=True)
  File "/home/ec2-user/.local/lib/python3.8/site-packages/exchangelib/account.py", line 116, in __init__
    self.ad_response, self.protocol = discover(
  File "/home/ec2-user/.local/lib/python3.8/site-packages/exchangelib/autodiscover/discovery.py", line 24, in discover
    return Autodiscovery(
  File "/home/ec2-user/.local/lib/python3.8/site-packages/exchangelib/autodiscover/discovery.py", line 123, in discover
    ad_response = self._step_1(hostname=domain)
  File "/home/ec2-user/.local/lib/python3.8/site-packages/exchangelib/autodiscover/discovery.py", line 433, in _step_1
    return self._step_2(hostname=hostname)
  File "/home/ec2-user/.local/lib/python3.8/site-packages/exchangelib/autodiscover/discovery.py", line 451, in _step_2
    return self._step_3(hostname=hostname)
  File "/home/ec2-user/.local/lib/python3.8/site-packages/exchangelib/autodiscover/discovery.py", line 483, in _step_3
    return self._step_4(hostname=hostname)
  File "/home/ec2-user/.local/lib/python3.8/site-packages/exchangelib/autodiscover/discovery.py", line 514, in _step_4
    return self._step_6()
  File "/home/ec2-user/.local/lib/python3.8/site-packages/exchangelib/autodiscover/discovery.py", line 572, in _step_6
    raise AutoDiscoverFailed(
exchangelib.errors.AutoDiscoverFailed: All steps in the autodiscover protocol failed for email '<outlook_email_id>'. If you think this is an error, consider doing an official test at https://testconnectivity.microsoft.com

Please let me know if more details are required. Any help would be appreciated.

Thanks

Vipendra Singh
  • 689
  • 2
  • 12
  • 26
  • what were the results of following the error message's directive to "consider doing an official test at https://testconnectivity.microsoft.com?" – itprorh66 Jan 12 '21 at 22:22
  • Since your Outlook account is located on Office365, you can disable autodiscover and connect directly to `outlook.office365.com`. Autodiscover will point you there anyway, assuming autodiscover is set up correctly for your domain, which does not seem to be the case. – Erik Cederstrand Jan 13 '21 at 08:24
  • Hi @Erik, I removed autodiscover from account then it raised this error AttributeError: non-autodiscover requires a config To solve this I add a config with below details config = Configuration(server='outlook.office365.com', credentials=credentials) account = Account('', credentials=credentials, config = config) But it is giving me below error exchangelib.errors.UnauthorizedError: Invalid credentials for https://outlook.office365.com/EWS/Exchange.asmx – Vipendra Singh Jan 13 '21 at 13:53
  • Ok, so you are probably passing invalid credentials :-) – Erik Cederstrand Jan 13 '21 at 17:57
  • @VipendraSinghDid you try the solution given [here](https://stackoverflow.com/questions/46525041/exchangelib-all-steps-in-the-autodiscover-protocol-failed)? – Jacob Celestine Jan 13 '21 at 18:17
  • Hi @JacobCelestine, yes I tried but I am not able to get the exact server url used in config. I have put a comment in solution but got no reply. – Vipendra Singh Jan 14 '21 at 16:11
  • Hi @ErikCederstrand, As I already mentioned the credentials are correct because i am able to login through same credentials in web outlook – Vipendra Singh Jan 14 '21 at 16:12
  • Sorry, didn't notice that part. If you can't use NTLM or Basic auth, then you probably need to use OAuth (https://learn.microsoft.com/en-us/exchange/client-developer/exchange-web-services/authentication-and-ews-in-exchange). – Erik Cederstrand Jan 14 '21 at 16:57
  • Hi @ErikCederstrand, so which is the library for oauth for outlook 365 in python, is it O365 or anyother? – Vipendra Singh Jan 15 '21 at 06:40
  • You can still use exchangelib, just have a look at the OAuth docs: https://ecederstrand.github.io/exchangelib/#oauth-authentication – Erik Cederstrand Jan 15 '21 at 08:45
  • Sure @ErikCederstrand, I will give it a try. Also for getting client id and secret I need to talk with admin right, I can’t get it from my web outlook login ? – Vipendra Singh Jan 16 '21 at 15:43

0 Answers0