【问题标题】:How to continuously monitor a new mail in outlook and unread mails of a specific folder in python如何持续监控outlook中的新邮件和python中特定文件夹的未读邮件
【发布时间】:2019-08-17 00:37:12
【问题描述】:

我想检查特定的发件人电子邮件并在它到达的任何地方自动处理它

但是,在某些情况下,我的 Outlook 可能会重新启动,这意味着当我收到来自发件人的邮件并标记为未读时

为了持续监控特定主题的新邮件,我找到了以下代码

import win32com.client
import pythoncom
import re

class Handler_Class(object):
  def OnNewMailEx(self, receivedItemsIDs):
    # RecrivedItemIDs is a collection of mail IDs separated by a ",".
    # You know, sometimes more than 1 mail is received at the same moment.
    for ID in receivedItemsIDs.split(","):
        mail = outlook.Session.GetItemFromID(ID)
        subject = mail.Subject
    print subject   
        try: 
            command = re.search(r"%(.*?)%", subject).group(1)

            print command # Or whatever code you wish to execute.
        except:
            pass


outlook = win32com.client.DispatchWithEvents("Outlook.Application",Handler_Class)

#and then an infinit loop that waits from events.
pythoncom.PumpMessages() 

即使我想通过所有未读邮件来检查发件人的邮件是否已经到达并处理它(如果找到)

是否有任何功能可以检查未读邮件以添加到 handler_class 中

或者让我知道任何替代程序

【问题讨论】:

  • 你打算在你的outlook重启后重启你的python程序吗?如果是,您可以在执行pythoncom.PumpMessages() 之前检查未读电子邮件作为脚本的第一个操作
  • 我正在寻找一个案例,如果我的 Outlook 凭据已过期并尝试使用我的新凭据登录或我的系统已重新启动..意味着当我收到 3 封邮件时...你能建议我如何继续处理这 2 个案例。 .也可以为上面的评论放一些示例代码。
  • 如果你不重启你的python脚本,我不知道该怎么做。如果你这样做,那么看看我的回答
  • 非常感谢本!!!...
  • 我有一个问题,您是否在重新启动 Outlook 后尝试过您的代码?我的意思是,如果您在重新启动 Outlook 后不重新启动 Python 脚本,您是否仍会监控收到的消息(我不接受未读消息)?

标签: python win32com pythoncom


【解决方案1】:

因此,如果您每次重新启动 Outlook 时都重新启动 Python 脚本,那么将这些行添加到您的代码中以检查收件箱中的未读电子邮件:

ol = win32com.client.Dispatch( "Outlook.Application")
inbox = ol.GetNamespace("MAPI").GetDefaultFolder(6)
for message in inbox.Items:
    if message.UnRead == True:
        print message.Subject #or whatever command you want to do

将此代码放在代码中outlook 的定义之前

编辑

对我来说,您发布的代码在我关闭 Outlook 之前运行良好,然后即使我重新打开它,在收到新消息时我什么也得不到(请参阅我的一个 cmets)。我猜想用pythoncom.PumpMessages() 关闭Outlook“取消链接”的事实。无论如何,我会在 Handler_Class 类中检查未读电子邮件并重新启动监控,以防你重新启动 Outlook。

import win32com.client
import ctypes # for the VM_QUIT to stop PumpMessage()
import pythoncom
import re
import time
import psutil

class Handler_Class(object):

    def __init__(self):
        # First action to do when using the class in the DispatchWithEvents     
        inbox = self.Application.GetNamespace("MAPI").GetDefaultFolder(6)
        messages = inbox.Items
        # Check for unread emails when starting the event
        for message in messages:
            if message.UnRead:
                print message.Subject # Or whatever code you wish to execute.

    def OnQuit(self):
        # To stop PumpMessages() when Outlook Quit
        # Note: Not sure it works when disconnecting!!
        ctypes.windll.user32.PostQuitMessage(0)

    def OnNewMailEx(self, receivedItemsIDs):
    # RecrivedItemIDs is a collection of mail IDs separated by a ",".
    # You know, sometimes more than 1 mail is received at the same moment.
        for ID in receivedItemsIDs.split(","):
            mail = self.Session.GetItemFromID(ID)
            subject = mail.Subject
            print subject   
            try: 
                command = re.search(r"%(.*?)%", subject).group(1)
                print command # Or whatever code you wish to execute.
            except:
                pass

# Function to check if outlook is open
def check_outlook_open ():
    list_process = []
    for pid in psutil.pids():
        p = psutil.Process(pid)
        # Append to the list of process
        list_process.append(p.name())
    # If outlook open then return True
    if 'OUTLOOK.EXE' in list_process:
        return True
    else:
        return False

# Loop 
while True:
    try:
        outlook_open = check_outlook_open()
    except: 
        outlook_open = False
    # If outlook opened then it will start the DispatchWithEvents
    if outlook_open == True:
        outlook = win32com.client.DispatchWithEvents("Outlook.Application", Handler_Class)
        pythoncom.PumpMessages()
    # To not check all the time (should increase 10 depending on your needs)
    time.sleep(10)

不确定这是不是最好的方法,但它似乎可以按照您寻找的方式工作。

【讨论】:

  • 如果我的 Outlook 凭据过期并尝试使用我的新凭据登录 .. 意味着当我收到 3 封邮件时...如何处理检查这些邮件
  • 感谢 Ben,即使我昨天尝试时也注意到了同样的情况...将检查代码并通知您
  • 嗨 Ben,有没有办法定期启动/停止 pythoncom.PumpMessages() 让我们说每隔一小时
  • 嗨 Ben,如果 outlook_open == True:outlook=win32com.client.DispatchWithEvents("Outlook.Application", Handler_Class) while True:start_time= while time.clock,我在我的代码中尝试过类似的操作()
  • @Ben.T:很棒的代码,谢谢!当某些发件人的电子邮件到达时,我会向我的手机发送推送通知。超酷!我遇到的唯一问题是,如果 Outlook 关闭并再次打开,脚本会停止工作,甚至会挂起 Outlook。我最终删除了 while True 循环以与 Outlook 一起退出代码,然后在 Outlook 之后手动启动它。也在寻找 VBA 解决方案,所以我不会一直打开这个 python 窗口。
【解决方案2】:

不要从 python 监控 Outlook,而是尝试为该电子邮件设置 Outlook 规则,然后通过 vba 启动 python 脚本。

这是从 VBA 启动 python 脚本的代码。

注意:以下代码取自here

Sub UruchomBata(MyMail As MailItem)
  Dim Ret_Val
    Dim args As String

    args = "c:\new.py"
    Ret_Val = Shell("C:\python27\python.exe" & " " & args, vbNormalFocus) 
  End Sub

这行下面是 Python 脚本,供感兴趣的人使用。这是 当前设置为控制 com1 串行端口上的 DTR 引脚。这 以下将需要保存为 yourname.py 文件

import serial
from time import sleep


conn = serial.Serial('com1',
                     baudrate=9600,
                     bytesize=serial.EIGHTBITS,
                     parity=serial.PARITY_NONE,
                     stopbits=serial.STOPBITS_ONE,
                     timeout=1,
                     xonxoff=0,
                     rtscts=0
                     )
# Wake Modem

conn.setDTR(True)
sleep(3)
conn.setDTR(False)
sleep(1)


conn.close()


# Start talking

try:
    while True:
        conn.write('AT'+chr(13));
        print conn.readline() # readlines() will probably never return.
finally:
    conn.close()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-11
    • 1970-01-01
    • 1970-01-01
    • 2014-07-26
    • 2011-08-05
    相关资源
    最近更新 更多