diff --git a/MailComponent/Mail/IMailSender.cs b/MailComponent/Mail/IMailSender.cs new file mode 100755 index 0000000..cf9b9f4 --- /dev/null +++ b/MailComponent/Mail/IMailSender.cs @@ -0,0 +1,16 @@ +/*---------------------------------------------------------- +This Source Code Form is subject to the terms of the +Mozilla Public License, v.2.0. If a copy of the MPL +was not distributed with this file, You can obtain one +at http://mozilla.org/MPL/2.0/. +----------------------------------------------------------*/ + +namespace OneScript.InternetMail +{ + public interface IMailSender + { + void Logon(InternetMailProfile profile); + void Logoff(); + void Send(InternetMailMessage message, InternetMailTextProcessing processText); + } +} diff --git a/MailComponent/Mail/ImapReceiver.cs b/MailComponent/Mail/ImapReceiver.cs index cd0515c..beae142 100755 --- a/MailComponent/Mail/ImapReceiver.cs +++ b/MailComponent/Mail/ImapReceiver.cs @@ -15,7 +15,7 @@ This Source Code Form is subject to the terms of the namespace OneScript.InternetMail { - public class ImapReceiver : IMailReceiver, IDisposable + public class ImapReceiver : IMailReceiver, IMailSender, IDisposable { private readonly ImapClient client = new ImapClient(); private InternetMailProfile _profile; @@ -225,7 +225,7 @@ public ArrayImpl GetIdentifiers(ArrayImpl identifiers, StructureImpl filter) var headerWithUid = ivHeaderWithUid as InternetMailMessage; var Id = headerWithUid.Uid.Get(0); - if (identifiers == null || identifiers.Find(Id).DataType != DataType.Undefined) + if (identifiers == null || identifiers.Find(Id).DataType == DataType.Undefined) result.Add(Id); } @@ -311,5 +311,10 @@ public void Dispose() Logoff(); } + public void Send(InternetMailMessage message, InternetMailTextProcessing processText) + { + var messageToSend = message.CreateNativeMessage(processText); + _currentFolder.Append(messageToSend); + } } } diff --git a/MailComponent/Mail/InternetMail.cs b/MailComponent/Mail/InternetMail.cs index 95a29e7..cb53ab9 100755 --- a/MailComponent/Mail/InternetMail.cs +++ b/MailComponent/Mail/InternetMail.cs @@ -19,7 +19,7 @@ public class InternetMail : AutoContext, IDisposable { private InternetMailProfile _profile; - private SmtpClient smtpClient = new SmtpClient(); + private readonly SmtpSender smtpClient = new SmtpSender(); private IMailReceiver receiver; private string _currentMailbox = ""; private string _mailboxDelimiterCharacter = ""; @@ -60,19 +60,12 @@ public string CurrentMailbox private void LogonSmtp() { - SecureSocketOptions options = SecureSocketOptions.Auto; - smtpClient.Timeout = _profile.Timeout * 1000; - smtpClient.ServerCertificateValidationCallback = (s, c, h, e) => true; - smtpClient.Connect(_profile.SmtpServerAddress, _profile.GetSmtpPort(), options); - - if (_profile.SmtpUser != "") - smtpClient.Authenticate(_profile.SmtpUser, _profile.SmtpPassword); + smtpClient.Logon(_profile); } private void LogoffSmtp() { - if (smtpClient.IsConnected) - smtpClient.Disconnect(true); + smtpClient.Logoff(); } #endregion @@ -83,7 +76,9 @@ public void Logon(InternetMailProfile profile, InternetMailProtocol receiveMailP _profile = profile; if (!string.IsNullOrEmpty(_profile.SmtpServerAddress) && !_profile.Pop3BeforeSmtp) + { LogonSmtp(); + } switch (receiveMailProtocol) { @@ -130,12 +125,17 @@ public void Send(InternetMailMessage message, throw new RuntimeException("Недопустимо указывать POP3 в качестве протокола отправки почты!"); } - var messageToSend = message.CreateNativeMessage(processText); - + IMailSender sender = null; if (protocol == InternetMailProtocol.Smtp) + sender = smtpClient; + else if (protocol == InternetMailProtocol.Imap) { - smtpClient.Send(messageToSend); + sender = receiver as ImapReceiver; + if (sender == null) + throw new RuntimeException("Соединение IMAP не установлено!"); } + + sender?.Send(message, processText); } [ContextMethod("ПолучитьЗаголовки", "GetHeaders")] @@ -162,46 +162,55 @@ public void DeleteMessages(ArrayImpl dataToDelete) receiver?.DeleteMessages(dataToDelete); } + [ContextMethod("ПолучитьПочтовыеЯщики", "GetMailBoxes")] public ArrayImpl GetMailboxes() { return receiver?.GetMailboxes(); } + [ContextMethod("ПолучитьПочтовыеЯщикиПоПодписке", "GetMailBoxesBySubscription")] public ArrayImpl GetMailboxesBySubscription() { return receiver?.GetMailboxesBySubscription(); } + [ContextMethod("ПодписатьсяНаПочтовыйЯщик", "SubscribeToMailbox")] public void SubscribeToMailbox(string name) { receiver?.SubscribeToMailbox(name); } + [ContextMethod("ОтменитьПодпискуНаПочтовыйЯщик", "UnsubscribeFromMailbox")] public void UnsubscribeFromMailbox(string name) { receiver?.UnsubscribeFromMailbox(name); } + [ContextMethod("ОтменитьУдалениеСообщений", "UndeleteMessages")] public void UndeleteMessages(ArrayImpl deletedData) { receiver?.UndeleteMessages(deletedData); } + [ContextMethod("ОчиститьУдаленныеСообщения", "ClearDeletedMessages")] public void ClearDeletedMessages() { receiver?.ClearDeletedMessages(); } + [ContextMethod("ПереименоватьПочтовыйЯщик", "RenameMailbox")] public void RenameMailbox(string name, string newName) { receiver?.RenameMailbox(name, newName); } + [ContextMethod("СоздатьПочтовыйЯщик", "CreateMailbox")] public void CreateMailbox(string name) { receiver?.CreateMailbox(name); } + [ContextMethod("УдалитьПочтовыйЯщик", "DeleteMailbox")] public void DeleteMailbox(string name) { receiver?.DeleteMailbox(name); @@ -215,7 +224,8 @@ public ArrayImpl Get(bool? deleteMessages = null, ArrayImpl ids = null, bool? ma public void Dispose() { - ((IDisposable)smtpClient).Dispose(); + smtpClient.Dispose(); + (receiver as IDisposable)?.Dispose(); } [ScriptConstructor] diff --git a/MailComponent/Mail/Pop3Receiver.cs b/MailComponent/Mail/Pop3Receiver.cs index 44795a5..a841573 100755 --- a/MailComponent/Mail/Pop3Receiver.cs +++ b/MailComponent/Mail/Pop3Receiver.cs @@ -135,7 +135,7 @@ public ArrayImpl GetIdentifiers(ArrayImpl identifiers = null, StructureImpl filt { var Id = ValueFactory.Create(uid); - if (identifiers == null || identifiers.Find(Id).DataType != DataType.Undefined) + if (identifiers == null || identifiers.Find(Id).DataType == DataType.Undefined) result.Add(Id); } @@ -165,6 +165,7 @@ public ArrayImpl Get(bool deleteMessages, ArrayImpl ids, bool markAsRead) if (deleteMessages && processedMessages.Count > 0) { client.DeleteMessages(processedMessages); + Relogon(); } return result; diff --git a/MailComponent/Mail/SmtpSender.cs b/MailComponent/Mail/SmtpSender.cs new file mode 100755 index 0000000..dd3d97a --- /dev/null +++ b/MailComponent/Mail/SmtpSender.cs @@ -0,0 +1,47 @@ +/*---------------------------------------------------------- +This Source Code Form is subject to the terms of the +Mozilla Public License, v.2.0. If a copy of the MPL +was not distributed with this file, You can obtain one +at http://mozilla.org/MPL/2.0/. +----------------------------------------------------------*/ +using System; +using MailKit.Net.Smtp; +using MailKit.Security; + +namespace OneScript.InternetMail +{ + public class SmtpSender : IMailSender, IDisposable + { + + private readonly SmtpClient _client = new SmtpClient(); + + public void Logoff() + { + if (_client.IsConnected) + _client.Disconnect(true); + } + + public void Logon(InternetMailProfile profile) + { + SecureSocketOptions options = SecureSocketOptions.Auto; + _client.Timeout = profile.Timeout * 1000; + _client.ServerCertificateValidationCallback = (s, c, h, e) => true; + _client.Connect(profile.SmtpServerAddress, profile.GetSmtpPort(), options); + + if (profile.SmtpUser != "") + _client.Authenticate(profile.SmtpUser, profile.SmtpPassword); + } + + public void Send(InternetMailMessage message, InternetMailTextProcessing processText) + { + var messageToSend = message.CreateNativeMessage(processText); + _client.Send(messageToSend); + } + + public void Dispose() + { + Logoff(); + } + + } +} diff --git a/MailComponent/MailComponent.csproj b/MailComponent/MailComponent.csproj index b1d6d2a..bca205d 100755 --- a/MailComponent/MailComponent.csproj +++ b/MailComponent/MailComponent.csproj @@ -74,6 +74,8 @@ + + diff --git a/MailComponent/Properties/AssemblyInfo.cs b/MailComponent/Properties/AssemblyInfo.cs index 1180c9a..5ac6049 100755 --- a/MailComponent/Properties/AssemblyInfo.cs +++ b/MailComponent/Properties/AssemblyInfo.cs @@ -17,7 +17,7 @@ // The form "{Major}.{Minor}.*" will automatically update the build and revision, // and "{Major}.{Minor}.{Build}.*" will update just the revision. -[assembly: AssemblyVersion("1.0.1.*")] +[assembly: AssemblyVersion("1.0.2.*")] // The following attributes are used to specify the signing key for the assembly, // if desired. See the Mono documentation for more information about signing. diff --git a/TestApp/TestSendReceive.os b/TestApp/TestSendReceive.os index 18a52f2..9dce1ae 100755 --- a/TestApp/TestSendReceive.os +++ b/TestApp/TestSendReceive.os @@ -1,100 +1,205 @@ -Процедура ОтправитьПисьмо(Знач Получатель, Знач Заголовок, Знач ТекстПисьма) Экспорт - +Функция СоздатьПрофиль(Знач SMTP = Истина, Знач POP3 = Истина, Знач IMAP = Истина) + Профиль = Новый ИнтернетПочтовыйПрофиль; - Профиль.АдресСервераSMTP = Сервер; Профиль.Таймаут = Таймаут; - - Профиль.ПользовательSMTP = Пользователь; - Профиль.ПарольSMTP = Пароль; - Профиль.ПортSMTP = ПортSMTP; - Профиль.ИспользоватьSSLSMTP = ИспользоватьSSLSMTP; - Профиль.Пользователь = Пользователь; - Профиль.Пароль = Пароль; + Если SMTP Тогда + + Профиль.АдресСервераSMTP = Сервер; + Профиль.ПользовательSMTP = Пользователь; + Профиль.ПарольSMTP = Пароль; + Профиль.ПортSMTP = ПортSMTP; + Профиль.ИспользоватьSSLSMTP = ИспользоватьSSLSMTP; + + КонецЕсли; + + Если POP3 Тогда + + Профиль.АдресСервераPOP3 = СерверPop3; + Профиль.ИспользоватьSSLPOP3 = ИспользоватьSSLPOP3; + Профиль.Пользователь = Пользователь; + Профиль.Пароль = Пароль; + + КонецЕсли; + + Если IMAP Тогда + + Профиль.АдресСервераImap = СерверImap; + Профиль.ПользовательImap = Пользователь; + Профиль.ПарольImap = Пароль; + Профиль.ИспользоватьSSLIMAP = ИспользоватьSSLIMAP; + + КонецЕсли; + + Возврат Профиль; +КонецФункции + +Функция СоздатьСообщение(Знач Получатель, Знач Тема, Знач ТекстСообщения) + Сообщение = Новый ИнтернетПочтовоеСообщение; Сообщение.Получатели.Добавить(Получатель); - Сообщение.ОбратныйАдрес.Добавить(Отправитель).ОтображаемоеИмя = "Отправителище"; - Сообщение.Отправитель = Сообщение.ОбратныйАдрес.Получить(0); - Сообщение.Тема = Заголовок; - Сообщение.Тексты.Добавить(ТекстПисьма, ТипТекстаПочтовогоСообщения.ПростойТекст); - Сообщение.Тексты.Добавить(ТекстПисьма, ТипТекстаПочтовогоСообщения.ПростойТекст); - + Сообщение.ОбратныйАдрес.Добавить(Отправитель); + Сообщение.Отправитель = Отправитель; + Сообщение.Тема = Тема; + Сообщение.Тексты.Добавить(ТекстСообщения); + + Возврат Сообщение; + +КонецФункции + +Процедура Проверка_ОтправкаПрием_SMTP_POP3() + + Профиль = СоздатьПрофиль(Истина, Истина, Ложь); Почта = Новый ИнтернетПочта; - Почта.Подключиться(Профиль, ПротоколИнтернетПочты.IMAP); + Почта.Подключиться(Профиль, ПротоколИнтернетПочты.POP3); + + ТекстПисьма = "TestMessage"; + ТемаПисьма = "1-2-3"; + + СтарыеИдентификаторы = Почта.ПолучитьИдентификаторы(); + + Сообщение = СоздатьСообщение(Отправитель, ТемаПисьма, ТекстПисьма); + Почта.Послать(Сообщение, , ПротоколИнтернетПочты.SMTP); + + КоличествоПопыток = 5; + + Для НомерПопытки = 1 По КоличествоПопыток Цикл + + Почта.Отключиться(); + Приостановить(1000); // Подождём на всякий случай + Сообщить("Попытка " + НомерПопытки + "..."); + + Почта.Подключиться(Профиль, ПротоколИнтернетПочты.POP3); + + НовыеИдентификаторы = Почта.ПолучитьИдентификаторы(СтарыеИдентификаторы); + + // Ожидаем, что НовыеИдентификаторы().Количество() = 1 + + Если НовыеИдентификаторы.Количество() = 0 Тогда + + Сообщить("Письмо ещё не дошло..."); + Продолжить; + + ИначеЕсли Не (НовыеИдентификаторы.Количество() = 1) Тогда + + ВызватьИсключение "Всё плохо: новое письмо не обозначилось!"; + + КонецЕсли; + + Письма = Почта.Выбрать(Истина, НовыеИдентификаторы); + Если Не (Письма.Количество() = 1) Тогда + ВызватьИсключение "Всё плохо: новое письмо не найдено по идентификатору!"; + КонецЕсли; + + Письмо = Письма.Получить(0); + Если Не Письмо.Тема = ТемаПисьма Тогда + ВызватьИсключение "Получено не то письмо (Тема)!"; + КонецЕсли; - Почта.Послать(Сообщение, ОбработкаТекстаИнтернетПочтовогоСообщения.НеОбрабатывать, ПротоколИнтернетПочты.SMTP); + Если Не СокрЛП(Письмо.Тексты.Получить(0).Текст) = ТекстПисьма Тогда + + Для Каждого мТекст Из Письмо.Тексты Цикл + + Сообщить("-------"); + Сообщить(мТекст.Текст); + + КонецЦикла; + + Сообщить("-- Отправляли: "); + Сообщить(ТекстПисьма); + + ВызватьИсключение "Получено не то письмо (Текст)!"; + + КонецЕсли; + + Сообщить("Письмо успешно получено!"); + Прервать; + + КонецЦикла; Почта.Отключиться(); КонецПроцедуры -Процедура ПолучитьСписокПисем() +Процедура Проверка_ОтправкаПрием_IMAP_IMAP() - Профиль = Новый ИнтернетПочтовыйПрофиль; - - Профиль.АдресСервераImap = СерверImap; - Профиль.Таймаут = Таймаут; - - Профиль.ПользовательImap = Пользователь; - Профиль.ПарольImap = Пароль; - Профиль.ИспользоватьSSLIMAP = ИспользоватьSSLIMAP; - + Профиль = СоздатьПрофиль(Ложь, Ложь, Истина); Почта = Новый ИнтернетПочта; Почта.Подключиться(Профиль, ПротоколИнтернетПочты.IMAP); - Сообщить("Подключено"); - Сообщить("Сообщений в ящике: " + Почта.ПолучитьКоличествоСообщений()); - Заголовки = Почта.ПолучитьЗаголовки(Новый Структура("Flagged", Истина)); + ТекстПисьма = "TestMessage"; + ТемаПисьма = "1-2-3"; - Для Каждого мСообщение Из Заголовки Цикл - Сообщить("Заголовок: " + мСообщение.Заголовок); - КонецЦикла; + СтарыеИдентификаторы = Почта.ПолучитьИдентификаторы(); - Для Каждого мСообщение Из Заголовки Цикл - Сообщить(мСообщение.Тема); - Сообщить("" + мСообщение.ДатаОтправления + " +" + мСообщение.СмещениеДатыОтправления / 3600); - КонецЦикла; + Сообщение = СоздатьСообщение(Отправитель, ТемаПисьма, ТекстПисьма); + Почта.Послать(Сообщение, , ПротоколИнтернетПочты.IMAP); - Идентификаторы = Почта.ПолучитьИдентификаторы(); - Для Каждого мИД Из Идентификаторы Цикл - Сообщить(мИД); - КонецЦикла; + Приостановить(2000); // Подождём, чтобы увидеть письмо в почтовике - Письма = Почта.Выбрать(Ложь); - Для Каждого мПисьмо Из Письма Цикл + КоличествоПопыток = 5; - Сообщить("*********************"); - Сообщить(мПисьмо.Тема); - Сообщить("---------------------"); - Для Каждого мИД Из мПисьмо.Идентификатор Цикл - Сообщить(мИД); - КонецЦикла; + Для НомерПопытки = 1 По КоличествоПопыток Цикл - КонецЦикла; + Почта.Отключиться(); + Приостановить(1000); // Подождём на всякий случай + Сообщить("Попытка " + НомерПопытки + "..."); - Пока Письма.Количество() > 1 Цикл - Письма.Удалить(0); - КонецЦикла; + Почта.Подключиться(Профиль, ПротоколИнтернетПочты.IMAP); + + НовыеИдентификаторы = Почта.ПолучитьИдентификаторы(СтарыеИдентификаторы); + + // Ожидаем, что НовыеИдентификаторы().Количество() = 1 + + Если НовыеИдентификаторы.Количество() = 0 Тогда + + Сообщить("Письмо ещё не дошло..."); + Продолжить; + + ИначеЕсли Не (НовыеИдентификаторы.Количество() = 1) Тогда + + ВызватьИсключение "Всё плохо: новое письмо не обозначилось!"; + + КонецЕсли; + + Письма = Почта.Выбрать(Истина, НовыеИдентификаторы); + Если Не (Письма.Количество() = 1) Тогда + ВызватьИсключение "Всё плохо: новое письмо не найдено по идентификатору!"; + КонецЕсли; + + Письмо = Письма.Получить(0); + Если Не Письмо.Тема = ТемаПисьма Тогда + ВызватьИсключение "Получено не то письмо (Тема)!"; + КонецЕсли; + + Если Не СокрЛП(Письмо.Тексты.Получить(0).Текст) = ТекстПисьма Тогда + + Для Каждого мТекст Из Письмо.Тексты Цикл + + Сообщить("-------"); + Сообщить(мТекст.Текст); + + КонецЦикла; + + Сообщить("-- Отправляли: "); + Сообщить(ТекстПисьма); + + ВызватьИсключение "Получено не то письмо (Текст)!"; + + КонецЕсли; - Почта.УдалитьСообщения(Письма); - Сообщить("Письмо удалено"); + Сообщить("Письмо успешно получено!"); + Почта.ОчиститьУдаленныеСообщения(); - Письма = Почта.Выбрать(Ложь); - Для Каждого мПисьмо Из Письма Цикл + Прервать; - Сообщить("*********************"); - Сообщить(мПисьмо.Тема); - Сообщить("---------------------"); - Для Каждого мИД Из мПисьмо.Идентификатор Цикл - Сообщить(мИД); - КонецЦикла; КонецЦикла; Почта.Отключиться(); КонецПроцедуры -// ОтправитьПисьмо("sergey.batanov@lacoste.ru", "Theme", "OneScript rockz!"); -ПолучитьСписокПисем(); +Проверка_ОтправкаПрием_SMTP_POP3(); +Проверка_ОтправкаПрием_IMAP_IMAP(); diff --git a/lib/packagedef b/lib/packagedef index d480c4f..3ff361a 100755 --- a/lib/packagedef +++ b/lib/packagedef @@ -4,7 +4,7 @@ // Описание.Имя("InternetMail") - .Версия("1.0.1") + .Версия("1.0.2") .Автор("Батанов Сергей") .АдресАвтора("sergey.batanov@dmpas.ru") .Описание("Реализация стандартных объектов из раздела ИнтернетПочта")