Вопрос

Как добавить вложения в автоматически отправляемый email?

Добрый день.

У меня задача: при получении письма от пользователя автоматически пересылать его исполнителю по заявке. Дублировать письмо в БП получается, а вот вложенные документы - нет. Подскажите, пожалуйста. 

Нравится

8 комментариев
Лучший ответ

Тогда все лучше кодом,примерно так (подправьте получение списка вложений в методе GetEmailAttachmentsFromTemplate)

			var tempalteId = GetEmailTemplateId(); //Id шаблона сообщения
			if (tempalteId == Guid.Empty) {
				return;
			}
			var esq = new EntitySchemaQuery(UserConnection.EntitySchemaManager, "EmailTemplate");
			esq.AddColumn("Subject");
			esq.AddColumn("Body");
			esq.AddColumn("IsHtmlBody");
			esq.AddColumn("Macros");
			var template = (Terrasoft.Configuration.EmailTemplate)esq.GetEntity(UserConnection, tempalteId);
			if (template == null) {
				return;
			}
			var smtpClient = new Terrasoft.Mail.SmtpClient(UserConnection);
			var credentials =  new MailCredentials();
			credentials.Host = (string)Terrasoft.Core.Configuration.SysSettings.GetValue(UserConnection, "SmtpHost");
			credentials.Port = int.Parse(Terrasoft.Core.Configuration.SysSettings.GetValue(UserConnection, "SmtpPort").ToString());
			credentials.UseSsl = (bool)Terrasoft.Core.Configuration.SysSettings.GetValue(UserConnection, "SmtpEnableSsl");
			credentials.UserName = (string)Terrasoft.Core.Configuration.SysSettings.GetValue(UserConnection, "SmtpUserName");
			credentials.UserPassword = (string)Terrasoft.Core.Configuration.SysSettings.GetValue(UserConnection, "SmtpUserPassword");
			if (string.IsNullOrEmpty(credentials.Host) || string.IsNullOrEmpty(credentials.UserName)) {
				return;
			}
			foreach(var recepient in recepients) {
				if (string.IsNullOrEmpty(recepient.Value)) {
					continue;
				}
				var body = ProcessEmailBody(template.Body, recepient.Key, template.GetBytesValue("Macros"));
				Dictionary<Guid, Tuple<byte[], string>> attachments = GetEmailAttachmentsFromTemplate(tempalteId);
				var message = smtpClient.CreateMessage(body, template.Subject,
					new string[] {recepient.Value}, credentials.UserName, template.IsHtmlBody, attachments);
				try {
					smtpClient.SendMessage(message, credentials);
				} catch (SmtpException e) {
					// TODO: log exception
				}
			}
 
//Получение вложений
public virtual Dictionary<Guid, Tuple<byte[], string>> GetEmailAttachmentsFromTemplate(Guid templateId) {
			var result = new Dictionary<Guid, Tuple<byte[], string>>();
			var entitySchema = UserConnection.EntitySchemaManager.GetInstanceByName("EmailTemplateFile");
			var srcESQ = new EntitySchemaQuery(entitySchema);
			srcESQ.IsDistinct = true;
			var idColumn =srcESQ.AddColumn(srcESQ.RootSchema.GetPrimaryColumnName());
			var nameColumn = srcESQ.AddColumn("Name");	   
			srcESQ.Filters.Add(srcESQ.CreateFilterWithParameters(FilterComparisonType.Equal, "EmailTemplate", templateId));
			var srcList = srcESQ.GetEntityCollection(UserConnection);
			var fileRepository = ClassFactory.Get<FileRepository>(
						new ConstructorArgument("userConnection", UserConnection));
			foreach (var src in srcList) {
				var idSchemaColumn = src.Schema.Columns.GetByName(idColumn.Name);
				var fileId = src.GetTypedColumnValue<Guid>(idSchemaColumn.ColumnValueName);
				var nameSchemaColumn = src.Schema.Columns.GetByName(nameColumn.Name);
				var fileName = src.GetTypedColumnValue<String>(nameSchemaColumn.ColumnValueName);
				using (var memoryStream = new MemoryStream()) {
					var bwriter = new BinaryWriter(memoryStream);
					var fileInfo = fileRepository.LoadFile(entitySchema.UId, fileId, bwriter);
					Tuple<byte[], string> attach = Tuple.Create<byte[], string>(memoryStream.ToArray(), fileName);
					result.Add(fileId, attach);
				}							
			}
 
			return result;
		}

 

Вам поможет это бесплатное расширение с маркетплэйса или воспользоватся этим рецептом

Благодарю за быстрый ответ. Правда, мне нужно пересылать не один файл, а все высланные пользователем, но попробую разобраться

Во втором рецепте (а именно: Как отправить email сообщение из бизнес-процесса с вложенными файлами) количество вложений не ограниченно, и вы можете посмотреть как реализовано в первом и по аналогии вложить еще несколько

Этот пост я уже читала, там предложен вариант, когда для пользователя открывается окно, и он вручную добавляет вложения. Мне нужен полностью автоматический вариант, срабатывающий по событию создания Активности с признаком входящего email, 
Думаю, следует оперировать вложениями из C#. Хотелось бы найти пример.

Наталья Стригина,

Можно создать активность (в том числе и по шаблону) установить ручную отправку и потом к созданной через элемент отправить письмо активности прикрепить файлы используя элемент Добавить данные!

Затем выполнить отправку письма как в совете выше

Письмо у меня создается сначала как Активность, потом я его отправляю. А Добавлять данные куда? Таблица "Файлы и ссылки раздела Активности" из БП не доступна. Я, конечно, могу добавить в нее вложения sql-запросом. При этом с# код 
отправит вложения? Есть Такой опыт?

Тогда все лучше кодом,примерно так (подправьте получение списка вложений в методе GetEmailAttachmentsFromTemplate)

			var tempalteId = GetEmailTemplateId(); //Id шаблона сообщения
			if (tempalteId == Guid.Empty) {
				return;
			}
			var esq = new EntitySchemaQuery(UserConnection.EntitySchemaManager, "EmailTemplate");
			esq.AddColumn("Subject");
			esq.AddColumn("Body");
			esq.AddColumn("IsHtmlBody");
			esq.AddColumn("Macros");
			var template = (Terrasoft.Configuration.EmailTemplate)esq.GetEntity(UserConnection, tempalteId);
			if (template == null) {
				return;
			}
			var smtpClient = new Terrasoft.Mail.SmtpClient(UserConnection);
			var credentials =  new MailCredentials();
			credentials.Host = (string)Terrasoft.Core.Configuration.SysSettings.GetValue(UserConnection, "SmtpHost");
			credentials.Port = int.Parse(Terrasoft.Core.Configuration.SysSettings.GetValue(UserConnection, "SmtpPort").ToString());
			credentials.UseSsl = (bool)Terrasoft.Core.Configuration.SysSettings.GetValue(UserConnection, "SmtpEnableSsl");
			credentials.UserName = (string)Terrasoft.Core.Configuration.SysSettings.GetValue(UserConnection, "SmtpUserName");
			credentials.UserPassword = (string)Terrasoft.Core.Configuration.SysSettings.GetValue(UserConnection, "SmtpUserPassword");
			if (string.IsNullOrEmpty(credentials.Host) || string.IsNullOrEmpty(credentials.UserName)) {
				return;
			}
			foreach(var recepient in recepients) {
				if (string.IsNullOrEmpty(recepient.Value)) {
					continue;
				}
				var body = ProcessEmailBody(template.Body, recepient.Key, template.GetBytesValue("Macros"));
				Dictionary<Guid, Tuple<byte[], string>> attachments = GetEmailAttachmentsFromTemplate(tempalteId);
				var message = smtpClient.CreateMessage(body, template.Subject,
					new string[] {recepient.Value}, credentials.UserName, template.IsHtmlBody, attachments);
				try {
					smtpClient.SendMessage(message, credentials);
				} catch (SmtpException e) {
					// TODO: log exception
				}
			}
 
//Получение вложений
public virtual Dictionary<Guid, Tuple<byte[], string>> GetEmailAttachmentsFromTemplate(Guid templateId) {
			var result = new Dictionary<Guid, Tuple<byte[], string>>();
			var entitySchema = UserConnection.EntitySchemaManager.GetInstanceByName("EmailTemplateFile");
			var srcESQ = new EntitySchemaQuery(entitySchema);
			srcESQ.IsDistinct = true;
			var idColumn =srcESQ.AddColumn(srcESQ.RootSchema.GetPrimaryColumnName());
			var nameColumn = srcESQ.AddColumn("Name");	   
			srcESQ.Filters.Add(srcESQ.CreateFilterWithParameters(FilterComparisonType.Equal, "EmailTemplate", templateId));
			var srcList = srcESQ.GetEntityCollection(UserConnection);
			var fileRepository = ClassFactory.Get<FileRepository>(
						new ConstructorArgument("userConnection", UserConnection));
			foreach (var src in srcList) {
				var idSchemaColumn = src.Schema.Columns.GetByName(idColumn.Name);
				var fileId = src.GetTypedColumnValue<Guid>(idSchemaColumn.ColumnValueName);
				var nameSchemaColumn = src.Schema.Columns.GetByName(nameColumn.Name);
				var fileName = src.GetTypedColumnValue<String>(nameSchemaColumn.ColumnValueName);
				using (var memoryStream = new MemoryStream()) {
					var bwriter = new BinaryWriter(memoryStream);
					var fileInfo = fileRepository.LoadFile(entitySchema.UId, fileId, bwriter);
					Tuple<byte[], string> attach = Tuple.Create<byte[], string>(memoryStream.ToArray(), fileName);
					result.Add(fileId, attach);
				}							
			}
 
			return result;
		}

 

Огромное спасибо. Только мне предстоит брать вложения из другой активности, а не из шаблона. Буду переделывать. 

Показать все комментарии