Как проверить электронную почту на наличие файла с помощью С#?

Каждую неделю я получаю электронное письмо с файлом Excel. Я знаю, что, вероятно, есть лучшие способы для достижения моей цели, но возможно ли иметь задачу сценария в SSIS, которая может открывать электронную почту, искать определенное имя файла в виде вложения, а затем копировать этот файл в другое место?

Вот сценарий. Для моей команды важно иметь этот файл Excel в базе данных SQL, и поставщик источника Excel готов отправлять нам этот файл Excel по электронной почте только один раз в неделю. Затем я проверяю свою электронную почту, копирую файл в место, где задача потока данных SSIS может затем подобрать его и вставить в таблицу SQL. Я хотел бы автоматизировать это. Итак, если мой первоначальный подход не выполним, как еще это можно автоматизировать? Помимо использования общего сетевого расположения. Предположим, что файл Excel может прийти ТОЛЬКО из электронной почты. Используя Outlook/Office 365, SSIS, SSMS, у меня есть доступ к DBO, и я могу использовать С#.

Я признаю, что я ничего не знаю об электронной почте. Если есть процедура, которую почтовый клиент может выполнить для достижения этой цели, то я буду прислушиваться!

РЕДАКТИРОВАТЬ: у меня также есть доступ к сетевому диску, так как я понимаю, что сохранение на моем локальном компьютере может быть невозможным.


person user3486773    schedule 21.09.2016    source источник
comment
Я не верю, что SSIS может открывать и загружать вложения из электронной почты (или вообще открывать электронные письма), но вы можете проверить Фабрику задач, так как она добавляет эту функциональность: pragmaticworks.com/Products/Task-Factory   -  person Ryan Intravia    schedule 21.09.2016
comment
Интересно, есть ли способ использовать правило для его достижения. В худшем случае создайте небольшую службу/приложение С#, которая общается с веб-службами обмена.   -  person Charleh    schedule 21.09.2016
comment
@Charleh, для этого нет собственного правила, но оно основано на этой ссылке, которая может быть устаревшей pixelchef.net/content/rule-autosave-attachment-outlook показывает, что код VBA для создания правила, которое это сделает, довольно прост. Единственная проблема с этим маршрутом будет заключаться в том, что это будет рабочий стол, а не правило на стороне сервера, поэтому его / ее электронная почта должна быть открыта в нужное время.   -  person Matt    schedule 21.09.2016


Ответы (1)


Простой ответ Да, это возможно.

Я написал консольную программу для обработки электронной почты в Office365, которую я также взаимодействовал с SQL, так что это определенно можно сделать. Это не обязательно самая легкая вещь в мире, но и не слишком сложная.

Вы можете использовать управляемый API веб-служб Exchange (EWS)

Статья об изложении возможно и документации API https://msdn.microsoft.com/en-us/library/office/dd877012(v=exchg.150).aspx

Местоположение Github, где вы можете найти API (обратите внимание, что эта ссылка находится непосредственно на сайте Microsoft) https://github.com/officedev/ews-managed-api

Ссылка на то, как ссылаться на сборку, содержащую вторую ссылку выше: https://msdn.microsoft.com/en-us/library/office/dn528373(v=exchg.150).aspx

Создать и подключиться к сервису

string emailAddress = '[email protected]';
ExchangeService exService = new ExchangeService(ExchangeVersion.Exchange2013_SP1);
exService.Credentials = new WebCredentials(emailAddress,"password");

вы можете автоматически обнаружить или, если вы знаете URL-адрес, просто установите его таким образом, чтобы 1 из этих строк

exService.AutodiscoverUrl(_emailAddress, delegate { return true; });
exService.Url = new Uri("https://outlook.office365.com/EWS/Exchange.asmx");

Найдите папку «Входящие» и папку, в которую нужно переместить файл после обработки:

FolderView folderView = new FolderView(1);
folderView.PropertySet = new PropertySet(BasePropertySet.IdOnly);
folderView.PropertySet.Add(FolderSchema.DisplayName);
folderView.Traversal = FolderTraversal.Deep;
SearchFilter searchFilter = new SearchFilter.IsEqualTo(FolderSchema.DisplayName, "ProcessedFolderName");
Folder Inbox = Folder.Bind(exService, WellKnownFolderName.Inbox);
FindFoldersResults folderResults = Inbox.FindFolders(searchFilter, folderView);
FolderId processedFolderId = folderResults.Folders[0].Id;

Найдите сообщения, соответствующие вашим критериям:

List<SearchFilter> searchFilterCollection = new List<SearchFilter();
searchFilterCollection.Add(new SearchFilter.ContainsSubstring(ItemSchema.Subject,"Words in Subject"));
searchFilterCollection.Add(new SearchFilter.IsEqualTo(ItemSchema.HasAttachments,true));
searchFilterCollection.Add(new SearchFilter.IsEqualTo(EmailMessageSchema.From,new EmailAddress("[email protected]")));
SearchFilter searchFilter = new SearchFilter.SearchFilterCollection(LogicalOperator.And,searchFilterCollection);

ItemView view = new ItemView(50, 0, OffsetBasePoint.Beginning);
view.OrderBy.Add(ItemSchema.DateTimeReceived, SortDirection.Descending);
view.PropertySet = new PropertySet(BasePropertySet.IdOnly, ItemSchema.DateTimeReceived, ItemSchema.Attachments);
view.Traversal = ItemTraversal.Shallow;
FindItemsResults<Item> findResults = exService.FindItems(WellKnownFolderName.Inbox,searchFilter,view);

Обработайте результаты и сохраните вложения, когда закончите, переместите сообщение в другую папку, чтобы не импортировать одно и то же.

foreach (Item i in findResults.Items)
{
    foreach(FileAttachment attachment in i.Attachments)
    {
        attachment.Load(@"\\FilePathDirectory\" + attachment.FileName);
    }

    i.Move(processedFolderId);
}

вы можете расширить решение, протестировав, если вы не получаете результатов, отправляя себе сообщение об ошибке или выдавая ошибку для SSIS, чтобы подобрать и завершить задание. Вполне вероятно, что вы будете перезаписывать файл несколько раз, если у вас есть несколько сообщений для обработки, поэтому вы можете рассмотреть возможность добавления чего-то уникального в имя файла вместо того, чтобы просто использовать одно и то же, но это также создаст другие проблемы в службах SSIS.

во всяком случае, его начало надеюсь, что это поможет.

person Matt    schedule 21.09.2016
comment
Это больше, чем просто начало! Большое спасибо за направление. - person user3486773; 22.09.2016
comment
Приветствую вас. Мне стало любопытно узнать о моем старом решении, поэтому я откопал его и прочитал. - person Matt; 22.09.2016
comment
Интересно, что я использую то же самое для сканирования почтового ящика на наличие предупреждений о резервном копировании (чтобы управлять предупреждениями о резервном копировании для множества клиентов). Работает отлично, даже когда мы перешли с локальной биржи на O365. - person Charleh; 22.09.2016
comment
@Charleh Я изначально разработал, чтобы исправить ошибку с циклом обратной связи по электронной почте, с которой я застрял примерно за 1 год до исправления поставщика услуг электронной почты. поэтому я построил его для обработки нескольких тысяч возвращенных сообщений за раз, чтобы определить, следует ли их игнорировать (вне офиса), изменить адрес электронной почты или перенаправить в нашу службу поддержки клиентов, чтобы решить проблему... Это отлично сработало. в Office 365 я никогда не работал с ним в режиме on prem, но он должен..... определенно довольно масштабируем, хотя, как я думаю, в целом мое маленькое приложение обработало около 300-500 тыс. сообщений в целом и ~ 1 тыс. / 1-2 мин. - person Matt; 22.09.2016
comment
Просто хотел добавить, что мне удалось успешно реализовать это, используя 98% вашего решения с настройкой 2%. Итак, у меня есть задание ssis, которое теперь запускает задачу сценария и может захватить файл Excel, сохранить его, а затем передать задачу потока данных в мою БД! Спасибо еще раз! - person user3486773; 29.09.2016
comment
@user3486773 user3486773 здорово, рад, что это сработало. дайте мне знать о 2%, которые необходимо настроить, если есть какая-то ошибка или обновленный код, который мне не хватает, чтобы я мог интегрировать. Ваше здоровье - person Matt; 29.09.2016
comment
Хорошо работает с моей машины, но не с сервера планирования... Есть идеи? - person user3486773; 30.09.2016
comment
установлен ли управляемый API веб-служб Exchange (EWS) на сервере, на котором фактически выполняется пакет? - person Matt; 30.09.2016
comment
Итак, установил 64-разрядную версию EWS на 64-разрядный сервер планирования, но все равно не повезло. - person user3486773; 30.09.2016
comment
@user3486773 user3486773 У вас есть ошибки, которыми вы можете поделиться? сервер был перезагружен после установки (не уверен, что это требуется или нет)? Существуют ли какие-либо брандмауэры, блокирующие трафик с сервера планирования в Интернет/офис 365? какая ОС является сервером планирования и установлены ли SSIS и SQL-сервер? вам, вероятно, следует опубликовать еще один вопрос о том, что этот код работает в среде разработки, но не в производстве, включает конфигурации и ошибки, тогда я буду смотреть на него больше, чем просто - person Matt; 30.09.2016