Как добавить вложения в автоматически отправляемый email?
Добрый день.
У меня задача: при получении письма от пользователя автоматически пересылать его исполнителю по заявке. Дублировать письмо в БП получается, а вот вложенные документы - нет. Подскажите, пожалуйста.
Нравится
Тогда все лучше кодом,примерно так (подправьте получение списка вложений в методе 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; }
Огромное спасибо. Только мне предстоит брать вложения из другой активности, а не из шаблона. Буду переделывать.