Exchange is a library for sending, reading, and deleting emails. Exchange is interfacing with Exchange Web Services (EWS).

For more information about server settings, see this Microsoft support article.


Robot Framework

*** Settings ***
Library     RPA.Email.Exchange
...     vault_name=email_oauth_microsoft    vault_token_key=token
...  # your custom tenant here
Task Setup      Ensure Auth

*** Variables ***
${ACCOUNT}              ACCOUNT_NAME
${IMAGES}               myimage.png
${ATTACHMENTS}          C:${/}files${/}mydocument.pdf

*** Keywords ***
Ensure Auth
    ${secrets} =    Get Secret    email_oauth_microsoft
    RPA.Email.Exchange.Authorize    ${ACCOUNT}
    ...    is_oauth=${True}  # use the OAuth2 auth code flow (required)
    ...    client_id=${secrets}[client_id]  # app ID
    ...    client_secret=${secrets}[client_secret]  # app password
    ...    token=${secrets}[token]  # token dict (access, refresh, scope etc.)

*** Tasks ***
Task of sending email
    Send Message  recipients=${RECIPIENT_ADDRESS}
    ...           subject=Exchange Message from RPA Robot
    ...           body=<p>Exchange RPA Robot message body<br><img src='myimage.png'/></p>
    ...           save=${TRUE}
    ...           html=${TRUE}
    ...           images=${IMAGES}
    ...           cc=EMAIL_ADDRESS
    ...           bcc=EMAIL_ADDRESS
    ...           attachments=${ATTACHMENTS}

Task of listing messages
    # Attachments are saved specifically with a keyword Save Attachments
    ${messages}=    List Messages
    FOR    ${msg}    IN    @{messages}
        Log Many    ${msg}
        ${attachments}=    Run Keyword If    "${msg}[subject]"=="about my orders"
        ...    Save Attachments
        ...    ${msg}
        ...    save_dir=${CURDIR}${/}savedir
    # Using save_dir all attachments in listed messages are saved
    ${messages}=    List Messages
    ...    INBOX/Problems/sub1
    ...    criterion=subject:'about my orders'
    ...    save_dir=${CURDIR}${/}savedir2
    FOR    ${msg}    IN    @{messages}
        Log Many    ${msg}

Task of moving messages
    Move Messages    criterion=subject:'about my orders'
    ...    source=INBOX/Processed Purchase Invoices/sub2
    ...    target=INBOX/Problems/sub1


from RPA.Email.Exchange import Exchange
from RPA.Robocorp.Vault import Vault

vault_name = "email_oauth_microsoft"
secrets = Vault().get_secret(vault_name)
ex_account = "ACCOUNT_NAME"

mail = Exchange(
    subject="Message from RPA Python",
    body="RPA Python message body",


The OAuth2 flow is the only way of authorizing at the moment as Microsoft disabled entirely the usage of passwords, even App Passwords. And since you have to work with tokens now and because this library has the capability to automatically refresh an expired token, please don't forget to initialize the library with the following parameters: vault_name, vault_token_key and tenant.

Learn more on how to use the OAuth2 flow in this Portal robot example-oauth-email.

About criterion parameter

Following table shows possible criterion keys that can be used to filter emails. There apply to all keywords which have criterion parameter.

Key Effective search
subject subject to match
subject_contains subject to contain
body body to match
body_contains body to contain
sender sender (from) to match
sender_contains sender (from) to contain
before received time before this time
after received time after this time
between received time between start and end
category categories to match
category_contains categories to contain
importance importance to match

Keys before, after and between at the moment support two different timeformats either %d-%m-%Y %H:%M or %d-%m-%Y. These keys also support special string NOW which can be used especially together with keyword Wait for message  criterion=after:NOW.

When giving time which includes hours and minutes then the whole time string needs to be enclosed into single quotes.

between:'31-12-2021 23:50 and 01-01-2022 00:10'

Different criterion keys can be combined.

subject_contains:'new year' between:'31-12-2021 23:50 and 01-01-2022 00:10'

Please note that all values in the criterion that contain spaces need to be enclosed within single quotes.

In the following example the email subject is going to matched only against new not new year.

subject_contains:new year