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