通过 Interop for Outlook 从无法送达的电子邮件中读取目标收件人

问题描述 投票:0回答:3

我创建了一个应用程序,用于循环遍历收件箱中的电子邮件,找到所有无法送达、邮箱已满或延迟的电子邮件并生成报告。

通常的例程是遍历收件箱中的所有电子邮件(直到指定日期)。

如果电子邮件无法送达,请使用正则表达式查找电子邮件。这在 95% 的情况下都有效,因为此信息包含在未送达消息 (ReportItem) 的正文中。

所以,我的问题是我有几封电子邮件将空白电子邮件返回给报告,这使得几乎不可能清理它们或轻易报告我们对某人的电子邮件有问题。

我发现 Internet 标头中的信息包含邮件的收件人,但找不到任何关于是否可以使用互操作或其他对象来获取此信息的信息。

如果其他人遇到过这个问题并且知道解决方法,我将不胜感激。

干杯

interop outlook
3个回答
3
投票

我正在寻找自动化 outlook 邮箱以移动所有未送达的电子邮件并将无法送达邮件的收件人的电子邮件地址存储在列表中,以便我稍后可以检查列表的条目是否存在于 excel 列中并且然后从excel中删除。我希望这有帮助 ! 我找到了解决此问题的 Python 解决方案。用于连接到 outlook 的 python 库是 win32com,所以首先我们导入我们需要的所有库:

import win32com.client
import re
import datetime as dt
from tqdm import tqdm
import time
import extract_msg

这是连接到特定 outlook 帐户的好方法,如果您有:

outlook = win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI")
accounts= win32com.client.Dispatch("Outlook.Application").Session.Accounts

然后创建一个循环遍历整个outlook并到达指定的邮件帐户:

for account in accounts:
    inbox = outlook.Folders(account.DeliveryStore.DisplayName)
    if account.DeliveryStore.DisplayName == 'place_your_account_name_here':
            for folder in inbox.Folders:

通过文件夹名称在outlook中找到您要查看的文件夹, 因此,如果您想遍历收件箱,请键入“收件箱”而不是“文件夹名称”

if folder.__str__() == "Folder_name":
    messages = folder.Items                                
    messages.Sort('[ReceivedTime]', True)
    if folder.Folders.Item('Undeliverable'):
        undeliverable = folder.Folders.Item('Undeliverable')

    list_of_undelivered_email_addresses = my_super_function(messages,undeliverable)

到达邮件项目并将无法投递的子文件夹声明为“无法投递”后,我们指定要执行以下功能的时间段:

def my_super_function(messages,undeliverable):

    list_of_undelivered_email_addresses = []

    last_n_days = dt.datetime.now() - dt.timedelta(days = 25)

    messages = messages.Restrict("[ReceivedTime] >= '" +last_n_days.strftime('%m/%d/%Y %H:%M %p')+"'")

    rl= list()

我发现邮件地址无法送达的msot流行时间出现某种错误,错误下方是我发送的电子邮件的原始版本。他们中的大多数(除了极少数例外,都有一行这样说: 至:“Some_email_address”.... 这就是为什么我使用这个正则表达式来读取我的模式后的整行(即“To:”)

    pattern = re.compile('To: ".*\n?',re.MULTILINE)

    for counter, message in enumerate(messages):

将电子邮件保存在 PC 上的某个位置非常重要,否则一旦您阅读它的正文,电子邮件就会被加密。

 message.SaveAs("undeliverable_emails.msg")
            f = r'specify_the_absolute_path_where_you_want_it_saved'  
            try:
                    msg = extract_msg.Message(f)
                    print(counter)

在保存的消息正文中搜索关键字Undeliverable:

                    if msg.body.find("undeliverable")!= -1 or msg.body.find("Undeliverable")!= -1 or msg.subject.find("Undeliverable")!= -1 or msg.subject.find("undeliverable")!= -1 or msg.body.find("wasn't found at")!= -1:

将实际电子邮件保存到列表中,以便稍后将其移动到未送达子文件夹

rl.append(message)


                            m = re.search(pattern, msg.body)
                            m = m[0]

                            mail_final = m.split('"')[1]   

                            list_of_undelivered_email_addresses.append(mail_final)
                            list_of_undelivered_email_addresses=list(filter(None, list_of_undelivered_email_addresses))


                    else:
                            print('this email is not an undeliverable one')
            except:
                    pass

将列表中的所有邮件移至undeliverables文件夹:

if len(rl) ==0:
            pass
    else:
            for m in tqdm(rl):
                    m.Move(undeliverable)

    return list_of_undelivered_email_addresses

这里是完整的代码:

import win32com.client
import re
import datetime as dt
from tqdm import tqdm #tqdm gives you the progress bar
import time
import extract_msg

outlook = win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI")
accounts= win32com.client.Dispatch("Outlook.Application").Session.Accounts

def my_super_function(messages,undeliverable):    
        list_of_undelivered_email_addresses = []
        last_n_days = dt.datetime.now() - dt.timedelta(days = 25)
        messages = messages.Restrict("[ReceivedTime] >= '" +last_n_days.strftime('%m/%d/%Y %H:%M %p')+"'")
        rl= list()
        pattern = re.compile('To: ".*\n?',re.MULTILINE)       
        for counter, message in enumerate(messages):
                message.SaveAs("undeliverable_emails.msg")
                f = r'some_absolute_path'  
                try:
                        msg = extract_msg.Message(f)
                        print(counter)
                        if msg.body.find("undeliverable")!= -1 or msg.body.find("Undeliverable")!= -1 or msg.subject.find("Undeliverable")!= -1 or msg.subject.find("undeliverable")!= -1 or msg.body.find("wasn't found at")!= -1:
                                rl.append(message)
                                m = re.search(pattern, msg.body)
                                m = m[0]
                                mail_final = m.split('"')[1]   
                                list_of_undelivered_email_addresses.append(mail_final)
                                list_of_undelivered_email_addresses=list(filter(None, list_of_undelivered_email_addresses))
                        else:
                                print('else')
                except:
                        pass
        if len(rl) ==0:
                pass
        else:
                for m in tqdm(rl):
                        m.Move(undeliverable)
        return list_of_undelivered_email_addresses

for account in accounts:
        inbox = outlook.Folders(account.DeliveryStore.DisplayName)
        if account.DeliveryStore.DisplayName == 'desired_email_address':
                for folder in inbox.Folders:
                        if folder.__str__() == "Inbox":
                                messages = folder.Items                               
                                messages.Sort('[ReceivedTime]', True)
                                if folder.Folders.Item('Undeliverable'):
                                        undeliverable = folder.Folders.Item('Undeliverable')                                      
                                list_of_undelivered_email_addresses = my_super_function(messages,undeliverable)

2
投票

看起来我想要的不是 ReportItem 属性的一部分。

可能的选项是 Extended IMAPI、CDO 或 Redemption

http://www.tech-archive.net/Archive/Outlook/microsoft.public.outlook.program_vba/2004-11/0084.html


0
投票

旧帖子,但仅供参考,您不必使用正则表达式来获取未送达的电子邮件,您可以通过检查中的值来获取所有未送达/退回的电话

message.Class

返回一个数字,46表示这是一封退回的邮件。 43 是正常收到的邮件。

与 message.Class 相关的数字的完整列表在此链接中https://learn.microsoft.com/en-us/dotnet/api/microsoft.office.interop.outlook.olobjectclass?view=outlook-pia

© www.soinside.com 2019 - 2024. All rights reserved.