Python通过EWS订阅新邮件

Python通过EWS订阅方式进行监听,获取新邮件内容

from exchangelib import NTLM, IMPERSONATION, Account, Credentials, Configuration,DELEGATE,HTMLBody
from exchangelib import Mailbox, Folder
# from exchangelib.items import Message


from datetime import datetime,timedelta
 ######### 取消SSL安全连接警告 #####################################
from exchangelib.protocol import BaseProtocol, NoVerifyHTTPAdapter

urllib3.disable_warnings()
# Tell exchangelib to use this adapter class instead of the default
# exchangelib provides a sample adapter which ignores TLS validation errors. 
# Use at own risk. NTML is NT LAN Manager.
BaseProtocol.HTTP_ADAPTER_CLS = NoVerifyHTTPAdapter
######### 取消SSL安全连接警告 #####################################

#定义要读取的邮箱
username_appimp = "test19\\test02"
password_appimp = "password"
mail_server = "10.10.2.13"
credentials = Credentials(username=username_appimp, password=password_appimp)
config = Configuration(server=mail_server, credentials=credentials, auth_type = NTLM, max_connections=3) #设置到服务器的连接数,默认为1。如果不增大连接数,则订阅本身已经占用了一个连接,就无法再获取邮件主题等


account = Account(
    primary_smtp_address="test02@test19.com",  #获取该用户邮箱的数据administrator@test19.com
    autodiscover=False,
    config=config,
    access_type=DELEGATE, #IMPERSONATION,
)

# print(account)
# print('-----------------------------------')

#导入Event事件
from exchangelib.properties import (
    NewMailEvent,
    StatusEvent,
    FreeBusyChangedEvent,
)


# 订阅新邮件通知
subscription_id = account.inbox.subscribe_to_streaming(
    event_types=['NewMailEvent']
)

for notification in account.inbox.get_streaming_events(subscription_id, connection_timeout=30):
    for event in notification.events:
        if isinstance(event, NewMailEvent):
            eid = event.item_id.id
            # print(eid)
            item = account.inbox.get(id=eid)
            print(f"新邮件主题: {item.subject}")
            print(f"发件人: {item.sender.email_address}")
            print(f"正文: {item.text_body}")
            # item.delete() #删除后不可恢复

 

增加订阅状态检查、失败重连机制:

from exchangelib import NTLM, IMPERSONATION, Account, Credentials, Configuration, DELEGATE, HTMLBody
from exchangelib import Mailbox, Folder
from exchangelib.errors import TransportError
from datetime import datetime,timedelta
 ######### 取消SSL安全连接警告 #####################################
from exchangelib.protocol import BaseProtocol, NoVerifyHTTPAdapter

urllib3.disable_warnings()
# Tell exchangelib to use this adapter class instead of the default
# exchangelib provides a sample adapter which ignores TLS validation errors. 
# Use at own risk. NTML is NT LAN Manager.
BaseProtocol.HTTP_ADAPTER_CLS = NoVerifyHTTPAdapter
######### 取消SSL安全连接警告 #####################################

usermail = "test02@test19.com"
username_appimp = "test19\\test02"
password_appimp = "password"
mail_server = "10.10.2.13"
credentials = Credentials(username=username_appimp, password=password_appimp)
config = Configuration(server=mail_server, credentials=credentials, auth_type = NTLM, max_connections=3)

try:
    account = Account(
        primary_smtp_address=usermail,  #获取该用户邮箱的数据administrator@test19.com
        autodiscover=False,
        config=config,
        access_type=DELEGATE, #IMPERSONATION,
    )
except Exception as e:
    print(e)
    exit(1)

# print(account)
# print('-----------------------------------')

def Get_NewMail(ItemID):
    item = account.inbox.get(id=ItemID)
    msg = f"新邮件主题: {item.subject} \n发件人: {item.sender.email_address}\n正文: {item.text_body}"
    # item.delete() #删除后不可恢复
    return msg


#导入Event事件
from exchangelib.properties import (
    NewMailEvent,
    StatusEvent,
    FreeBusyChangedEvent,
)

max_retries = 3   #定义最大重试次数         
retry_count = 0
subscription_id = None

while retry_count < max_retries:
    try:
        if not subscription_id:
            subscription_id = account.inbox.subscribe_to_streaming(event_types=['NewMailEvent'])
            print("订阅创建成功,ID:", subscription_id)

        notifications = account.inbox.get_streaming_events(subscription_id, connection_timeout=30)
        if not notifications:
            print("心跳检测:订阅活动正常,未收到新事件")

        #监听新邮件通知事件
        for notification in notifications:
            for event in notification.events:
                if isinstance(event, NewMailEvent):
                    ItemID = event.item_id.id
                    # print(ItemID)
                    mail = Get_NewMail(ItemID)
                    print(mail)

        retry_count = 0  # 重置重试计数器

    except TransportError as e:
        print(f"订阅异常: {str(e)},尝试重连...")
        retry_count += 1
        if subscription_id:
            try:
                account.inbox.unsubscribe(subscription_id)
            except Exception:
                pass
            subscription_id = None  # 重置订阅ID
        time.sleep(5)  # 重连间隔

    except Exception as e:
        print(f"未知错误: {str(e)},终止监听")
        break

if retry_count >= max_retries:
    print("达到最大重试次数,终止订阅")

 

posted on 2025-03-06 16:58  momingliu11  阅读(90)  评论(0)    收藏  举报