Я хотел автоматизировать почтовый ящик outlook, чтобы переместить все недоставленные электронные письма и сохранить адрес электронной почты получателя недоставленного сообщения в списке, чтобы позже я мог проверить, присутствует ли запись в списке в Excel столбец, а затем удалите его из Excel. Надеюсь, это поможет !
Я нашел решение Python для этой проблемы. Библиотека Python, которая используется для подключения к outlook, называется 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
Затем создайте цикл, который перебирает весь внешний вид и попадает в указанную учетную запись:
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, которую вы хотите проверить по имени папки,
поэтому, если вы хотите перебрать Inbox, введите «Inbox» вместо «Folder_name»
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()
Я обнаружил, что самые популярные времена недоставленных адресов электронной почты представляют собой какую-то ошибку, и ниже этой ошибки находится оригинальная версия отправленного мною электронного письма. Большинство из них (за очень немногими исключениями) имеют строку, которая гласит:
To: "Some_email_address" ....
Вот почему я использовал это регулярное выражение, чтобы прочитать всю строку после моего шаблона (то есть «To:» »)
pattern = re.compile('To: ".*\n?',re.MULTILINE)
for counter, message in enumerate(messages):
Очень важно сохранить электронное письмо где-нибудь на вашем компьютере, потому что в противном случае, как только вы прочитаете его текст, электронное письмо будет зашифровано.
message.SaveAs("undeliverable_emails.msg")
f = r'specify_the_absolute_path_where_you_want_it_saved'
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('this email is not an undeliverable one')
except:
pass
Переместить все письма в списке в папку невозможности доставки:
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)