Skip to content

shinyzhu/outlook-bot-tool

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

19 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Outlook Mailbot Tool

Motivation and Objective

According to the Microsoft support page. The basic auth will be no longer available. You will receive many failures recently like me.

September 16th, 2024

  • Basic Authentication no longer available to access any Outlook account

So this is the core motivation to do the migration.

The objective of this project is to fetch and send emails with a personal @outlook.com account in a Python CLI app.

This is introducing how to use the Modern Authentication rather than username/password. And using the msal for authentication, imaplib and smtplib for fetching and sending emails that you're familiar with.

You can find the IMAP and SMTP server on this page.

Don't check out other MS docs e.g. Microsoft Graph, they don't provide any useful messages for you.

LOL.

The Implementation

Here I use the device_code_flow to authenticate and get access_token, then used in the imaplib and smtplib api callings.

And it also provides token cache. So you don't need to login every time.

Example output:

(ohoutlook) outlook-bot-tool[main*] % python mailbot.py
INFO:root:🔐 Token acquired from cache
====================================================================================================
Subject: New app(s) connected to your Microsoft account
From: Microsoft account team
        <account-security-noreply@accountprotection.microsoft.com>
Date: Wed, 21 Aug 2024 21:21:03 -0700
====================================================================================================
Subject: New app(s) connected to your Microsoft account
From: Microsoft account team
        <account-security-noreply@accountprotection.microsoft.com>
Date: Wed, 21 Aug 2024 21:26:32 -0700

And:

(ohoutlook) outlook-bot-tool[main*] % python mailbot.py
INFO:root:No accounts found in cache
INFO:root:🔑 Device code flow initiated
To sign in, use a web browser to open the page https://microsoft.com/devicelogin and enter the code IQA3Y48WV to authenticate.

----------------------------------------------------
Open: https://microsoft.com/devicelogin
Code: IQA3Y48WV
----------------------------------------------------

INFO:root:🔐 Token acquired from remote
Email sent

Step by step guides

You can follow this guide to build your own bot.

Create a Microsoft Entra application

  1. Open the Microsoft Entra admin center and login using your personal account.
  2. Make sure you're under the Default Directory. You can switch it from the dropdown list at the top right corner.
  3. From the left-hand navigation, expand Identity, expand Applications, then select App registrations.
  4. Click + New registration. Enter a name for your application.
  5. Choose the Accounts in any organizational directory (Any Microsoft Entra ID tenant - Multitenant) and personal Microsoft accounts (e.g. Skype, Xbox) account type.
  6. Leave Redirect URI empty.
  7. Click Register button. On the application's Overview page, copy the value of the Application (client) ID and save it.
  8. Select Authentication under Manage. Locate the Advanced settings section and change the Allow public client flows toggle to Yes, then choose Save.

Update Entra app permissions

  1. On the application's page. Select API permissions under Manage.
  2. Click + Add a permission. Select Microsoft Graph from the API list.
  3. Select Delegated permissions. You'll see a list of permissions. Use search to filter the results. Check the following:
    1. IMAP.AccessAsUser.All
    2. SMTP.Send
    3. offline_access
  4. Then click Add permissions button to save.

Clone this project

or you can create your own.

Create a Python env by conda

conda create -n ohoutlook python-dotenv msal
conda activate ohoutlook

Then run python mailbot.py to see the demo.

The Workflow

Here I provide a file outlook_auth.py. You can use it in your own code like this:

from outlook_auth import auth_device_flow

Then you can simply to get the access_token even from the local file cache or from remote server:

access_token = auth_device_flow()

imap_conn = imaplib.IMAP4_SSL(imap_server, imap_port)
imap_conn.authenticate(
    "XOAUTH2", lambda x: f"user={user_email}\1auth=Bearer {access_token}\1\1"
)
...
smtp_conn = smtplib.SMTP(
    os.getenv("OUTLOOK_SMTP_SERVER"), os.getenv("OUTLOOK_SMTP_PORT")
)
smtp_conn.starttls()
smtp_conn.ehlo()
smtp_conn.auth(
    "XOAUTH2",
    lambda: f"user={me_mail}\1auth=Bearer {access_token}\1\1",
)

Note on the device code flow

When you see this message in your output:

----------------------------------------------------
Open: https://microsoft.com/devicelogin
Code: IQA3Y48WV
----------------------------------------------------

You need to open the page and follow the form to enter the code.

outlook_device_code_login_1

When done. You'll see the output keeps going. And the token is cached to local file token_cache.json alongside your script. It'll retrieve from the cache next time.

FAQ (Problems)

No Default Directory for your account

Register an application

The ability to create applications outside of a directory has been deprecated. You may get a new directory by joining the M365 Developer Program or signing up for Azure.

But you will get:

Thank you for joining. You don't current qualify for a Microsoft 365 Developer Program sandbox subscription.

Find out more here.

You can successfuly logged into the Azure Portal but you don't have any Directory. I can't pass the Identity verification by card step.

Or join the Visual Studio Dev Essentials? I don't know if can get a directory. LOL

Resources

About

No description, website, or topics provided.

Resources

License

Stars

3 stars

Watchers

1 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages