MS Exchang email notification via Linux command line

Posted on in category «Tech» by fnv with tags , , ,

Having account on MS Exchange with only MS Outlook Web Access is fine if your are instantly connected via web browser. However, imediatelly you close the web browser window you are out of emails. You could setup email forwarding which is fine until the policy prohibits external recipients. Mobile access is also option until the police force you to put your device under company mobile device management. I found the solution which fit to my case - just to get simple notification "There is new email in your inbox. Plase connect to check it out" via another email account outside of MS Exchange.

Installing required packages

Install required system packages. Here are packages for Debian, if you have any another distro you have to find on your own corresponding packages

apt install libxml2-dev libxslt1-dev python3-wheel python3-dev libssl-dev build-essential libffi-dev

Dedicated user and user environment preparation

MS Exchange account details are stored in dedicated config file in plaintext. I rather created dedicated user with locked login nevertheless it's not mandatory. You can skip it if you wish.

adduser emailnotify
passwd -l emailnotify
su - emailnotify

Install Python virtual environment and external library dependencies

mkdir office365-notifier
cd office365-notifier
python3 -m venv office365_venv
source office365_env/bin/activate
pip3 install sh exchangelib

Scripts - just copy&paste it to the office365-notifier dir

Notification notify.py script

#!/usr/bin/env python3

import config
import smtplib
from email.message import EmailMessage
from exchangelib import Account, Configuration, Credentials, DELEGATE


def connect(server, email, username, password):
    '''
    Create Exchange account connection

    Parameters:
        server - Exchange server address
        email - email address
        username - username for authentication - not always same as email
        password - password used for authentication
    Return:
        account - object representing the connection 
    '''

    creds = Credentials(username = username, password = password)
    config = Configuration(server = server, credentials = creds)

    return Account(primary_smtp_address = email, autodiscover = False, config = config, access_type = DELEGATE)


def main():
    '''
    Main body
    Parameters: none
    Return: none
    '''

    account = connect(config.server, config.email, config.username, config.password)

    if account.inbox.unread_count > 0:
        msg_email_word = "emails"
        if account.inbox.unread_count == 1:
            msg_email_word = "email"

        content = "You have new " + msg_email_word + " in your " + config.email + " mailbox\n\n"
        for item in account.inbox.filter(is_read = False).only('sender', 'subject'):
            content = content + "Sender: " + str(item.sender.email_address) + ", Subject: " + str(item.subject) + "\n"

        msg = EmailMessage()
        msg.set_content(content)
        msg["Subject"] = "Notification: " + str(account.inbox.unread_count) + " unread " + msg_email_word + " on " + config.email
        msg["From"] = config.sender
        msg["To"] = config.recipient

        server = smtplib.SMTP(config.smtp_server)
        server.send_message(msg)
        server.quit()


if __name__ == "__main__":
    main()

Config file config.py stores details about the MS Exchange account and the recipient who should receive the notification.

# MS Echange server address without HTTPS
server = "exchange.example.com"
# Your email address on the MS Exchange server
email = "joe@example.com"
# Username on the MS Exchange server
username = "example\joe"
# Password on the MS Exchange server
password = "passw0rd"
# SMTP server used for the sending notification
smtp_server = "localhost"
# SMTP server sender/recipient
sender = "joe@myserver.com"
recipient = "notify@myserver.com"

Scheduling

Right now, I'm fine to receive double notifications. Maybe in the future I will update script to suppress sending notification for same unread email. notify.sh

#!/usr/bin/env bash

DIR=/home/emailnotify/office365-notifier

cd $DIR
source ./office365_venv/bin/activate
./notify.py

And put the record into the crontab

1 8,12,16 * * * /home/emailnotify/office365-notifier/notify.sh

Resources

exchangelib library
notification script example