Я пишу инструмент синхронизации, который будет отправлять все полученные и отправленные сообщения электронной почты в наше PHP-приложение, встроенное в CakePHP. Для этого я использую потоковые уведомления. а>.
Теперь для каждого smtp-адреса, который я хочу прослушать, я создаю новую службу, которая будет прослушивать «созданные» события в папках «Входящие» и «Отправленные». Я делаю это через учетную запись, которая имеет право выдавать себя за все эти учетные записи.
Папки и события, о которых я говорю (C#)
// The folders we want to listen to
FolderId[] folderIds = new FolderId[] {
WellKnownFolderName.Inbox,
WellKnownFolderName.SentItems
};
// The event types we want to listen to
EventType[] eventTypes = new EventType[] {
EventType.Created
};
Кроме того, мы используем Outlook365, к которому можно получить доступ через https://portal.outlook365.com, где я могу войти . Когда я создаю нового пользователя в «Outlook365», я могу войти в эту только что созданную учетную запись.
Но тут возникает моя проблема. Когда я запускаю инструмент и открываю свой SubscriptionStreamConnection для этого smtp-адреса, он немедленно запускает событие типа ItemEvent
. Итак, я предполагаю, что это допустимое событие, как и новое сообщение электронной почты в папке «Входящие» и «Sentitems». Но это первое событие не содержит всех данных, которые я запрашиваю, и происходит только один раз! Во второй раз, когда я прослушиваю учетную запись, событие не запускается, поэтому я предполагаю, что это какое-то событие «Создать входящие», но я не уверен, как я могу отличить это от обычного события.
Что я прошу (C#)
PropertySet propSet = new PropertySet(
BasePropertySet.IdOnly,
EmailMessageSchema.InternetMessageId,
// Basic data
EmailMessageSchema.Subject,
EmailMessageSchema.UniqueBody,
EmailMessageSchema.ConversationId,
EmailMessageSchema.DateTimeReceived,
EmailMessageSchema.DateTimeSent,
// Sender and recipient data
EmailMessageSchema.From,
EmailMessageSchema.ToRecipients,
EmailMessageSchema.CcRecipients,
EmailMessageSchema.BccRecipients
);
Что я получаю (XML)
<?xml version="1.0" encoding="utf-8"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<h:ServerVersionInfo MajorVersion="15" MinorVersion="0" MajorBuildNumber="939" MinorBuildNumber="16" Version="V2_11" xmlns:h="http://schemas.microsoft.com/exchange/services/2006/types" xmlns="http://schemas.microsoft.com/exchange/services/2006/types" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" />
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<m:GetItemResponse xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages" xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
<m:ResponseMessages>
<m:GetItemResponseMessage ResponseClass="Success">
<m:ResponseCode>NoError</m:ResponseCode>
<m:Items>
<t:Message>
<t:ItemId Id="AA/BB/CC/DD=" ChangeKey="AA/BB" />
<t:DateTimeReceived>2014-05-13T09:47:44Z</t:DateTimeReceived>
<t:DateTimeSent>2014-05-13T09:47:44Z</t:DateTimeSent>
<t:ConversationId Id="AA=" />
<t:InternetMessageId><[email protected]></t:InternetMessageId>
</t:Message>
</m:Items>
</m:GetItemResponseMessage>
</m:ResponseMessages>
</m:GetItemResponse>
</s:Body>
</s:Envelope>
Обратите внимание: я изменил идентификаторы для удобства чтения, я оставил /
на месте, на случай, если они что-то значат.
Как вы можете видеть, ответ XML не содержит всех свойств, которые я запрашиваю, однако обычное событие (когда я отправляю электронное письмо на эту новую учетную запись) я получаю полный ответ, например:
<?xml version="1.0" encoding="utf-8"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<h:ServerVersionInfo MajorVersion="15" MinorVersion="0" MajorBuildNumber="939" MinorBuildNumber="16" Version="V2_11" xmlns:h="http://schemas.microsoft.com/exchange/services/2006/types" xmlns="http://schemas.microsoft.com/exchange/services/2006/types" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" />
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<m:GetItemResponse xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages" xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
<m:ResponseMessages>
<m:GetItemResponseMessage ResponseClass="Success">
<m:ResponseCode>NoError</m:ResponseCode>
<m:Items>
<t:Message>
<t:ItemId Id="AA/BB/CC/DE=" ChangeKey="AA/BB" />
<t:Subject>My random test!</t:Subject>
<t:DateTimeReceived>2014-05-13T10:25:55Z</t:DateTimeReceived>
<t:DateTimeSent>2014-05-13T10:25:38Z</t:DateTimeSent>
<t:ConversationId Id="AA/LEGY=" />
<t:UniqueBody BodyType="Text" IsTruncated="false">Hello World</t:UniqueBody>
<t:ToRecipients>
<t:Mailbox>
<t:Name>a10 Test</t:Name>
<t:EmailAddress>[email protected]</t:EmailAddress>
<t:RoutingType>SMTP</t:RoutingType>
<t:MailboxType>Mailbox</t:MailboxType>
</t:Mailbox>
</t:ToRecipients>
<t:From>
<t:Mailbox>
<t:Name>My Name - Company</t:Name>
<t:EmailAddress>[email protected]</t:EmailAddress>
<t:RoutingType>SMTP</t:RoutingType>
<t:MailboxType>OneOff</t:MailboxType>
</t:Mailbox>
</t:From>
<t:InternetMessageId><[email protected]></t:InternetMessageId>
</t:Message>
</m:Items>
</m:GetItemResponseMessage>
</m:ResponseMessages>
</m:GetItemResponse>
</s:Body>
</s:Envelope>
Конечно, я могу добавить простую проверку, существует ли, например, Subject в этом событии, но мне это кажется неправильным.
Просто чтобы уточнить, некоторые "свойства" моего проекта таковы:
- Я подключаюсь к outlook365.com
- Я использую C# с платформой .NET4.5 и новейшим API EWS.
- У меня есть один пользователь, который может выдавать себя за всех других пользователей, так что программе не нужно знать все пароли
- Я добавляю все ImpersonatedUserId, которые я хочу прослушать, у каждого из этих олицетворенных пользователей есть собственная служба (я думаю, что эта информация устарела, но она может вам помочь)
- В моем «OnNotificationEvent» я пытаюсь получить элемент по его идентификатору (в новом потоке, чтобы основная программа могла продолжаться)
Это код метода, обрабатывающего событие:
protected void _OnExchangeNotificationEvent(object sender, NotificationEventArgs args)
{
StreamingSubscriptionConnection connection = (StreamingSubscriptionConnection)sender;
StreamingSubscription subscription = args.Subscription;
// Loop through all item-related events.
foreach (NotificationEvent notification in args.Events)
{
// if the notification is NOT an item event, skip the event
if (!(notification is ItemEvent))
{
continue;
}
// Start a new thread so the main program can continue
Thread exchangeToCrmThread = new Thread(() => this._handleExchangeEventToCrm((ItemEvent)notification, args));
exchangeToCrmThread.Start();
}
}
Обратите внимание на метод _handleExchangeEventToCrm
, этот метод фактически пытается получить EmailMessage (в соответствии с набором свойств выше).
Мой вопрос
Просто уточнить
Почему новый пользователь запускает ItemEvent
, когда я слушаю его через StreamingSubscribtion
В ПЕРВЫЙ раз? Другими словами, как я могу отличить «нормальное» событие отправки/получения электронной почты от любого другого события, которое, по-видимому, также является «ItemEvent»?
Я подозреваю, что это связано с "созданием почтового ящика", но я не уверен. Любая помощь приветствуется!
Если что-то непонятно, спросите, чтобы я мог уточнить свой вопрос