ПолучениеИОтправкаЭлектронныхПисем (БСП)

Автор: 1С
ОбщийМодуль.УправлениеЭлектроннойПочтой
БСП

Получение отправка электронных писем. Выполняет процедуру отправки и получения электронных писем.

// Выполняет процедуру отправки и получения электронных писем.
Процедура ПолучениеИОтправкаЭлектронныхПисем() Экспорт
	
	ОбщегоНазначения.ПриНачалеВыполненияРегламентногоЗадания(Метаданные.РегламентныеЗадания.ПолучениеИОтправкаЭлектронныхПисем);
	
	Если НЕ ПолучитьФункциональнуюОпцию("ИспользоватьПочтовыйКлиент") Тогда
		Возврат;
	КонецЕсли;
		
	УстановитьПривилегированныйРежим(Истина);
	
	ЗаписьЖурналаРегистрации(СобытиеЖурналаРегистрации(), 
		УровеньЖурналаРегистрации.Информация, , ,
		НСтр("ru = 'Начато регламентное получение и отправка электронной почты'", ОбщегоНазначения.КодОсновногоЯзыка()));
		
	СтруктураМассивовПисем = СтруктураМассиваПисем();
	
	// Получение писем
	Запрос = Новый Запрос;
	Запрос.Текст =
	"ВЫБРАТЬ
	|	УчетныеЗаписиЭлектроннойПочты.Ссылка                                                        КАК Ссылка,
	|	УчетныеЗаписиЭлектроннойПочты.АдресЭлектроннойПочты                                         КАК АдресЭлектроннойПочты,
	|	УчетныеЗаписиЭлектроннойПочты.Наименование                                                  КАК Наименование,
	|	ЕСТЬNULL(НастройкиУчетныхЗаписейЭлектроннойПочты.ПомещатьПисьмоВПапкуПисьмаОснования, ЛОЖЬ) КАК ПомещатьПисьмоВПапкуПисьмаОснования,
	|	ВЫБОР
	|		КОГДА УчетныеЗаписиЭлектроннойПочты.ВладелецУчетнойЗаписи = ЗНАЧЕНИЕ(Справочник.Пользователи.ПустаяСсылка)
	|			ТОГДА ЕСТЬNULL(НастройкиУчетныхЗаписейЭлектроннойПочты.ОтветственныйЗаОбработкуПисем, ЗНАЧЕНИЕ(Справочник.Пользователи.ПустаяСсылка))
	|		ИНАЧЕ УчетныеЗаписиЭлектроннойПочты.ВладелецУчетнойЗаписи
	|	КОНЕЦ                                                                                       КАК ОтветственныйЗаОбработкуПисем,
	|	УчетныеЗаписиЭлектроннойПочты.ОставлятьКопииСообщенийНаСервере                              КАК ОставлятьКопии,
	|	УчетныеЗаписиЭлектроннойПочты.ПериодХраненияСообщенийНаСервере                              КАК ОставлятьДней,
	|	УчетныеЗаписиЭлектроннойПочты.ИмяПользователя                                               КАК ИмяПользователя,
	|	УчетныеЗаписиЭлектроннойПочты.ПротоколВходящейПочты                                         КАК ПротоколВходящейПочты,
	|	ЕСТЬNULL(ДатыПоследнейЗагрузкиПочтовыхСообщений.ДатаЗагрузкиПисем, ДАТАВРЕМЯ(1, 1, 1))      КАК ДатаЗагрузкиПисем,
	|	ВЫБОР
	|		КОГДА УчетныеЗаписиЭлектроннойПочты.ПротоколВходящейПочты = ""IMAP""
	|			ТОГДА ЕСТЬNULL(НастройкиУчетныхЗаписейЭлектроннойПочты.ОбработкаПисемВыполняетсяВДругомПочтовомКлиенте, ЛОЖЬ)
	|		ИНАЧЕ ЛОЖЬ
	|	КОНЕЦ                                                                                        КАК ОбработкаПисемВедетсяВДругомПочтовомКлиенте
	|ИЗ
	|	Справочник.УчетныеЗаписиЭлектроннойПочты КАК УчетныеЗаписиЭлектроннойПочты
	|		ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.НастройкиУчетныхЗаписейЭлектроннойПочты КАК НастройкиУчетныхЗаписейЭлектроннойПочты
	|		ПО (НастройкиУчетныхЗаписейЭлектроннойПочты.УчетнаяЗаписьЭлектроннойПочты = УчетныеЗаписиЭлектроннойПочты.Ссылка)
	|		ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ДатыПоследнейЗагрузкиПочтовыхСообщений КАК ДатыПоследнейЗагрузкиПочтовыхСообщений
	|		ПО (ДатыПоследнейЗагрузкиПочтовыхСообщений.УчетнаяЗапись = УчетныеЗаписиЭлектроннойПочты.Ссылка)
	|ГДЕ
	|	УчетныеЗаписиЭлектроннойПочты.ИспользоватьДляПолучения
	|	И НЕ ЕСТЬNULL(НастройкиУчетныхЗаписейЭлектроннойПочты.НеИспользоватьВоВстроенномПочтовомКлиенте, ЛОЖЬ)
	|	И УчетныеЗаписиЭлектроннойПочты.АдресЭлектроннойПочты <> """"
	|	И УчетныеЗаписиЭлектроннойПочты.СерверВходящейПочты <> """"";
	
	Выборка = Запрос.Выполнить().Выбрать();
	
	Пока Выборка.Следующий() Цикл
		
		Получено = 0;
		ПолучитьПисьма(Выборка, Ложь, Получено, СтруктураМассивовПисем);
		
	КонецЦикла;
	
	// Отправка писем
	Запрос = Новый Запрос;
	Запрос.Текст = "
	|ВЫБРАТЬ
	|	ЭлектронноеПисьмоИсходящее.Ссылка                                                  КАК Ссылка,
	|	ПРЕДСТАВЛЕНИЕ(ЭлектронноеПисьмоИсходящее.Ссылка)                                   КАК ПредставлениеПисьма,
	|	ЭлектронноеПисьмоИсходящее.УдалятьПослеОтправки                                    КАК УдалятьПослеОтправки,
	|	ЭлектронноеПисьмоИсходящее.УчетнаяЗапись                                           КАК УчетнаяЗапись,
	|	ЕСТЬNULL(ПапкиЭлектронныхПисем.ПредопределеннаяПапка, ИСТИНА)                      КАК ТребуетсяОпределениеПапки,
	|	ЕСТЬNULL(НепринятыеКОбработкеПочтовымСерверомИсходящиеПисьма.КоличествоПопыток, 0) КАК КоличествоПопыток
	|ИЗ
	|	Документ.ЭлектронноеПисьмоИсходящее КАК ЭлектронноеПисьмоИсходящее
	|		ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.УчетныеЗаписиЭлектроннойПочты КАК УчетныеЗаписиЭлектроннойПочты
	|		ПО ЭлектронноеПисьмоИсходящее.УчетнаяЗапись = УчетныеЗаписиЭлектроннойПочты.Ссылка
	|		ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ПредметыПапкиВзаимодействий КАК ПредметыПапкиВзаимодействий
	|			ЛЕВОЕ СОЕДИНЕНИЕ Справочник.ПапкиЭлектронныхПисем КАК ПапкиЭлектронныхПисем
	|			ПО ПредметыПапкиВзаимодействий.ПапкаЭлектронногоПисьма = ПапкиЭлектронныхПисем.Ссылка
	|		ПО (ПредметыПапкиВзаимодействий.Взаимодействие = ЭлектронноеПисьмоИсходящее.Ссылка)
	|		ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.НепринятыеКОбработкеПочтовымСерверомИсходящиеПисьма КАК НепринятыеКОбработкеПочтовымСерверомИсходящиеПисьма
	|		ПО (НепринятыеКОбработкеПочтовымСерверомИсходящиеПисьма.Письмо = ЭлектронноеПисьмоИсходящее.Ссылка)
	|ГДЕ
	|	НЕ ЭлектронноеПисьмоИсходящее.ПометкаУдаления
	|	И УчетныеЗаписиЭлектроннойПочты.АдресЭлектроннойПочты <> """"
	|	И УчетныеЗаписиЭлектроннойПочты.СерверИсходящейПочты <> """"
	|	И УчетныеЗаписиЭлектроннойПочты.ИспользоватьДляОтправки
	|	И ЭлектронноеПисьмоИсходящее.СтатусПисьма = ЗНАЧЕНИЕ(Перечисление.СтатусыИсходящегоЭлектронногоПисьма.Исходящее)
	|	И ВЫБОР
	|			КОГДА ЭлектронноеПисьмоИсходящее.ДатаКогдаОтправить = ДАТАВРЕМЯ(1, 1, 1)
	|				ТОГДА ИСТИНА
	|			ИНАЧЕ ЭлектронноеПисьмоИсходящее.ДатаКогдаОтправить < &ТекущаяДата
	|		КОНЕЦ
	|	И ВЫБОР
	|			КОГДА ЭлектронноеПисьмоИсходящее.ДатаАктуальностиОтправки = ДАТАВРЕМЯ(1, 1, 1)
	|				ТОГДА ИСТИНА
	|			ИНАЧЕ ЭлектронноеПисьмоИсходящее.ДатаАктуальностиОтправки > &ТекущаяДата
	|		КОНЕЦ
	|	И ЕСТЬNULL(НепринятыеКОбработкеПочтовымСерверомИсходящиеПисьма.КоличествоПопыток, 0) < 5
	|ИТОГИ ПО
	|	УчетнаяЗапись";
	
	Запрос.УстановитьПараметр("ТекущаяДата", ТекущаяДатаСеанса());
	
	ВыборкаУчетныеЗаписи = Запрос.Выполнить().Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
	Пока ВыборкаУчетныеЗаписи.Следующий() Цикл
		
		Профиль = РаботаСПочтовымиСообщениямиСлужебный.ИнтернетПочтовыйПрофиль(ВыборкаУчетныеЗаписи.УчетнаяЗапись);
		
		Попытка
			
			Соединение = Новый ИнтернетПочта;
			ПротоколПодключения = ?(ПустаяСтрока(Профиль.АдресСервераIMAP),ПротоколИнтернетПочты.POP3, ПротоколИнтернетПочты.IMAP);
			Соединение.Подключиться(Профиль, ПротоколПодключения);
			
			Если ПротоколПодключения = ПротоколИнтернетПочты.IMAP Тогда
				ПочтовыеЯщики = Соединение.ПолучитьПочтовыеЯщики();
				Для Каждого ПочтовыйЯщик Из ПочтовыеЯщики Цикл
					Если НРег(ПочтовыйЯщик) = "отправленные"
						Или НРег(ПочтовыйЯщик) = "sent" Тогда
						
						Соединение.ТекущийПочтовыйЯщик = ПочтовыйЯщик;
						Прервать;
						
					КонецЕсли;
				КонецЦикла;
			КонецЕсли;
			
		Исключение
			
			ТекстСообщенияОбОшибке = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
				НСтр("ru = 'Во время подключения к учетной записи %1 произошла ошибка
					|%2'", ОбщегоНазначения.КодОсновногоЯзыка()),
				ВыборкаУчетныеЗаписи.УчетнаяЗапись,
				ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
			
			ЗаписьЖурналаРегистрации(СобытиеЖурналаРегистрации(),
			                         УровеньЖурналаРегистрации.Ошибка, , ,
			                         ТекстСообщенияОбОшибке);
			
			Продолжить;
			
		КонецПопытки;
		
		ВыборкаПисьма = ВыборкаУчетныеЗаписи.Выбрать();
		Пока ВыборкаПисьма.Следующий() Цикл
			
			ПисьмоОбъект = ВыборкаПисьма.Ссылка.ПолучитьОбъект();
			Попытка
				
				ПараметрыПисьма = Неопределено;
				
				Если ПротоколПодключения = ПротоколИнтернетПочты.IMAP 
					И НЕ СерверИсходящейПочтыНеТребуетДополнительнойОтправкиПоIMAP(Профиль.АдресСервераSMTP)
					И Не ВыборкаПисьма.УдалятьПослеОтправки Тогда
					
					ПротоколПочты = "Все";
					
				Иначе
					
					ПротоколПочты = "";
					
				КонецЕсли;
				
				Взаимодействия.ВыполнитьОтправкуПисьма(ПисьмоОбъект, Соединение, ПараметрыПисьма, ПротоколПочты);
				
			Исключение
				
				ЭтоПроблемаОтвергнутыхСерверомПочтовыхАдресов = Ложь;
				ВсеАдресатыПисьмаОтвергнутыСервером           = Ложь;
				ПредставлениеОшибочныхАдресатов               = "";
				
				Если ПараметрыПисьма.Свойство("ОшибочныеПолучатели") Тогда
				
					ДанныеАнализаОшибочныхПолучателей = РезультатАнализаОшибочныхПолучателей(ПисьмоОбъект, ПараметрыПисьма.ОшибочныеПолучатели);
					
					ЭтоПроблемаОтвергнутыхСерверомПочтовыхАдресов = ДанныеАнализаОшибочныхПолучателей.ЭтоПроблемаОтвергнутыхСерверомПочтовыхАдресов;
					ВсеАдресатыПисьмаОтвергнутыСервером           = ДанныеАнализаОшибочныхПолучателей.ВсеАдресатыПисьмаОтвергнутыСервером;
					ПредставлениеОшибочныхАдресатов               = ДанныеАнализаОшибочныхПолучателей.ПредставлениеОшибочныхАдресатов;
				
				КонецЕсли;
				
				Если ЭтоПроблемаОтвергнутыхСерверомПочтовыхАдресов 
					И Не ВсеАдресатыПисьмаОтвергнутыСервером Тогда
				
					ТекстСообщенияОбОшибке = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
						НСтр("ru = 'Следующие адресаты электронного письма %1 не приняты почтовым сервером:
							|%2. Письмо отправлено остальным адресатам.'", ОбщегоНазначения.КодОсновногоЯзыка()),
						ВыборкаПисьма.ПредставлениеПисьма,
						ПредставлениеОшибочныхАдресатов);
						
				Иначе
					
					ТекстСообщенияОбОшибке = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
						НСтр("ru = 'Во время отправки электронного письма %1 произошла ошибка
							|%2'", ОбщегоНазначения.КодОсновногоЯзыка()),
						ВыборкаПисьма.ПредставлениеПисьма,
						ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
				
				КонецЕсли;
					
				ЗаписьЖурналаРегистрации(СобытиеЖурналаРегистрации(),
				                         УровеньЖурналаРегистрации.Ошибка, , ,
				                         ТекстСообщенияОбОшибке);
				
				Если НЕ ЭтоПроблемаОтвергнутыхСерверомПочтовыхАдресов
					Или ВсеАдресатыПисьмаОтвергнутыСервером Тогда
					
					МенеджерЗаписи = РегистрыСведений.НепринятыеКОбработкеПочтовымСерверомИсходящиеПисьма.СоздатьМенеджерЗаписи();
					МенеджерЗаписи.Письмо = ВыборкаПисьма.Ссылка;
					МенеджерЗаписи.КоличествоПопыток = ВыборкаПисьма.КоличествоПопыток + 1;
					МенеджерЗаписи.ИнформацияООшибке = ТекстСообщенияОбОшибке;
					МенеджерЗаписи.Записать();
					
					Продолжить;
				
				КонецЕсли;
				
			КонецПопытки;
			
			Если ВыборкаПисьма.УдалятьПослеОтправки Тогда
				
				ПисьмоОбъект.Удалить();
				
			Иначе
				
				ПисьмоОбъект.СтатусПисьма                       = Перечисления.СтатусыИсходящегоЭлектронногоПисьма.Отправлено;
				ПисьмоОбъект.Размер                             = Взаимодействия.ОценитьРазмерИсходящегоЭлектронногоПисьма(ПисьмоОбъект.Ссылка);
				ПисьмоОбъект.ДатаОтправления                    = ТекущаяДатаСеанса();
				ПисьмоОбъект.ДополнительныеСвойства.Вставить("НеЗаписыватьКонтакты", Истина);
				ПисьмоОбъект.Записать(РежимЗаписиДокумента.Запись);
				Если ВыборкаПисьма.ТребуетсяОпределениеПапки Тогда
					СтруктураМассивовПисем.ПисьмаДляОпределенияПапок.Добавить(ВыборкаПисьма.Ссылка);
				КонецЕсли;
				СтруктураМассивовПисем.ВсеПолученныеПисьма.Добавить(ВыборкаПисьма.Ссылка);
			КонецЕсли;
			
		КонецЦикла;
		
		Соединение.Отключиться();
		
	КонецЦикла;
	
	ОпределитьЗагруженныеРанееПодчиненныеПисьма(Выборка.Ссылка, СтруктураМассивовПисем.ВсеПолученныеПисьма);
	Взаимодействия.ЗаполнитьКонтактыМассиваВзаимодействий(СтруктураМассивовПисем.ВсеПолученныеПисьма);
	Взаимодействия.УстановитьПапкиДляМассиваПисем(СтруктураМассивовПисем.ПисьмаДляОпределенияПапок);
	Взаимодействия.РассчитатьРассмотреноПоПредметам(СтруктураМассивовПисем.ВсеПолученныеПисьма);
	Взаимодействия.РассчитатьРассмотреноПоКонтактам(СтруктураМассивовПисем.ВсеПолученныеПисьма);
	
	// Отправим уведомления о прочтении.
	Запрос = Новый Запрос;
	Запрос.Текст = "
	|ВЫБРАТЬ
	|	УведомленияОПрочтении.Письмо,
	|	ПРЕДСТАВЛЕНИЕ(УведомленияОПрочтении.Письмо) КАК ПредставлениеПисьма,
	|	УведомленияОПрочтении.ДатаПрочтения,
	|	ЭлектронноеПисьмоВходящее.АдресаУведомленияОПрочтении.(
	|		Адрес,
	|		Представление,
	|		Контакт
	|	),
	|	УчетныеЗаписиЭлектроннойПочты.Ссылка КАК УчетнаяЗапись,
	|	ЭлектронноеПисьмоВходящее.ОтправительПредставление,
	|	ЭлектронноеПисьмоВходящее.ОтправительАдрес,
	|	ЭлектронноеПисьмоВходящее.Дата,
	|	УчетныеЗаписиЭлектроннойПочты.ИмяПользователя,
	|	УчетныеЗаписиЭлектроннойПочты.АдресЭлектроннойПочты,
	|	ЭлектронноеПисьмоВходящее.Тема
	|ИЗ
	|	РегистрСведений.УведомленияОПрочтении КАК УведомленияОПрочтении
	|		ВНУТРЕННЕЕ СОЕДИНЕНИЕ Документ.ЭлектронноеПисьмоВходящее КАК ЭлектронноеПисьмоВходящее
	|			ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.УчетныеЗаписиЭлектроннойПочты КАК УчетныеЗаписиЭлектроннойПочты
	|			ПО ЭлектронноеПисьмоВходящее.УчетнаяЗапись = УчетныеЗаписиЭлектроннойПочты.Ссылка
	|		ПО УведомленияОПрочтении.Письмо = ЭлектронноеПисьмоВходящее.Ссылка
	|ГДЕ
	|	УведомленияОПрочтении.ТребуетсяОтправка
	|ИТОГИ ПО
	|	УчетнаяЗапись";
	
	ВыборкаУчетныеЗаписи = Запрос.Выполнить().Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
	Пока ВыборкаУчетныеЗаписи.Следующий() Цикл
		
		Профиль = РаботаСПочтовымиСообщениямиСлужебный.ИнтернетПочтовыйПрофиль(ВыборкаУчетныеЗаписи.УчетнаяЗапись);
		
		Попытка
			Соединение = Новый ИнтернетПочта;
			Соединение.Подключиться(Профиль);
		Исключение
			
			ТекстСообщенияОбОшибке = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
				НСтр("ru = 'Во время подключения к учетной записи %1 произошла ошибка
				|%2'", ОбщегоНазначения.КодОсновногоЯзыка()),
				ВыборкаУчетныеЗаписи.УчетнаяЗапись,
				ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
			
			ЗаписьЖурналаРегистрации(СобытиеЖурналаРегистрации(),
			                         УровеньЖурналаРегистрации.Ошибка, , ,
			                         ТекстСообщенияОбОшибке);
			
			Продолжить;
			
		КонецПопытки;
		
		ВыборкаПисьма = ВыборкаУчетныеЗаписи.Выбрать();
		Пока ВыборкаПисьма.Следующий() Цикл
			
			СоздатьОтправитьУведомлениеОПрочтении(ВыборкаПисьма, Истина, Соединение);
			
		КонецЦикла;
		
		Соединение.Отключиться();
		
	КонецЦикла;
	
	ЗаписьЖурналаРегистрации(СобытиеЖурналаРегистрации(), 
		УровеньЖурналаРегистрации.Информация, , ,
		НСтр("ru = 'Закончено регламентное получение и отправка электронной почты'", ОбщегоНазначения.КодОсновногоЯзыка()));
	
КонецПроцедуры

///////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2019, ООО 1С-Софт
// Все права защищены. Эта программа и сопроводительные материалы предоставляются 
// в соответствии с условиями лицензии Attribution 4.0 International (CC BY 4.0)
// Текст лицензии доступен по ссылке:
// https://creativecommons.org/licenses/by/4.0/legalcode
///////////////////////////////////////////////////////////////////////////////////////////////////////

Рекомендации

Похожие публикации

ПроверитьВозможностьОтправкиИПолученияЭлектроннойПочты (БСП)

ТипТекстовЭлектронныхПисем (БСП)

ВыполнитьУдалениеПапкиЭлектронныхПисем (БСП)

УстановитьРодителяУПапки (БСП)

Отправка электронной почты

СоздатьПредопределенныеПапкиЭлектронныхПисемДляУчетнойЗаписи (БСП)

ДоступнаОтправкаПисем (БСП)

TurboConf - расширение Конфигуратора 1С