public void AddRelationshipEvents(MailMessageItem item) { CoreContext.TenantManager.SetCurrentTenant(TenantId); SecurityContext.AuthenticateMe(CoreContext.Authentication.GetAccountByID(_user_id)); var factory = new DaoFactory(CoreContext.TenantManager.GetCurrentTenant().TenantId, CRMConstants.DatabaseId); foreach (var contact_entity in item.LinkedCrmEntityIds) { switch (contact_entity.Type) { case ChainXCrmContactEntity.EntityTypes.Contact: var crm_contact = factory.GetContactDao().GetByID(contact_entity.Id); CRMSecurity.DemandAccessTo(crm_contact); break; case ChainXCrmContactEntity.EntityTypes.Case: var crm_case = factory.GetCasesDao().GetByID(contact_entity.Id); CRMSecurity.DemandAccessTo(crm_case); break; case ChainXCrmContactEntity.EntityTypes.Opportunity: var crm_opportunity = factory.GetDealDao().GetByID(contact_entity.Id); CRMSecurity.DemandAccessTo(crm_opportunity); break; } var file_ids = StoreAttachmentsToCrm(item, contact_entity); var content_string = GetHistoryContentJson(item); AddRelationshipEventWithCrmApi(item, contact_entity, content_string, file_ids); } }
public void SaveEmailInData(MailBox mailbox, MailMessageItem message, ILogger log) { if (string.IsNullOrEmpty(mailbox.EMailInFolder)) return; try { foreach (var attachment in message.Attachments) { using (var file = AttachmentManager.GetAttachmentStream(attachment)) { log.Debug("SaveEmailInData->ApiHelper.UploadToDocuments(fileName: '{0}', folderId: {1})", file.FileName, mailbox.EMailInFolder); UploadToDocuments(file, attachment.contentType, mailbox, log); } } } catch (Exception e) { _log.Error("SaveEmailInData(tenant={0}, userId='{1}', messageId={2}) Exception:\r\n{3}\r\n", mailbox.TenantId, mailbox.UserId, message.Id, e.ToString()); } }
public void ConvertMessageToInternalFormatTest() { var message = ParseMessage(FILE_PATH); var mailMessageItem = new MailMessageItem(message); Assert.IsNotNull(mailMessageItem); }
/// <summary> /// This method generated a FileResource to attach to the email. /// </summary> private FileResource GenerateAttachment(MailMessageItem message) { // NOTE [ILs] To know who you're generating for you can fetch the XConnect contact (or use the other data available) Contact contact = _contactService.GetContact(message.ContactIdentifier, "pass desired facet keys you need"); // TODO [ILs] Implement your attachment generation code here // NOTE [ILs] You can generate any desired attachment here and append the bytes return(new FileResource("Attachment name here", new byte[0])); }
public MailMessageItem ConvertMessageToInternalFormat() { var message = ParseMessage(); var mail_message_item = new MailMessageItem(message); Assert.IsNotNull(mail_message_item); return(mail_message_item); }
public void AddRelationshipEvents(MailMessageItem item) { CoreContext.TenantManager.SetCurrentTenant(TenantId); foreach (var contact_entity in item.LinkedCrmEntityIds) { var file_ids = StoreAttachmentsToCrm(item, contact_entity); var content_string = GetHistoryContentJson(item); AddRelationshipEventWithCrmApi(item, contact_entity, content_string, file_ids); } }
public void BodyReplaceEmbeddedImages() { var message = ParseMessage(FILE_PATH); var mailMessageItem = new MailMessageItem(message); var htmlBodyWithReplacedEmbedded = MailBoxManager.ReplaceEmbeddedImages(mailMessageItem); Assert.IsNotEmpty(htmlBodyWithReplacedEmbedded); }
public void Process(SendMessageArgs args) { // NOTE [ILs] This is the message Sitecore item wrapped for easy access to various details MailMessageItem message = args.EcmMessage as MailMessageItem; if (_attachToMessageIdList.Contains(message?.InnerItem.ID)) { // NOTE [ILs] The actual EDS core message that will be dispatched is hidden in custom data if (args.CustomData["EmailMessage"] is EmailMessage email) { FileResource attachment = GenerateAttachment(message); email.Attachments.Add(attachment); } } }
private List<int> StoreAttachmentsToCrm(MailMessageItem item, CrmContactEntity entity) { var file_ids = new List<int>(); foreach (var attachment in item.Attachments) { using (var file = Manager.GetAttachmentStream(attachment)) { var uploaded_file_id = UploadFileToCrm(file.FileStream, file.FileName, attachment.contentType, entity); if (uploaded_file_id > 0) { file_ids.Add(uploaded_file_id); } } } return file_ids; }
public MailMessageItem ToMailMessageItem(int tenant, string user) { Address fromVerified; if (Validator.ValidateSyntax(From)) { fromVerified = new Address(From, DisplayName); } else { throw new ArgumentException(MailApiResource.ErrorIncorrectEmailAddress .Replace("%1", MailApiResource.FieldNameFrom)); } var messageItem = new MailMessageItem { From = fromVerified.ToString(), FromEmail = fromVerified.Email, To = string.Join(", ", To.ToArray()), Cc = Cc != null?string.Join(", ", Cc.ToArray()) : "", Bcc = Bcc != null?string.Join(", ", Bcc.ToArray()) : "", Subject = Subject, Date = DateTime.Now, Important = Important, HtmlBody = HtmlBody, Introduction = MailMessageItem.GetIntroduction(HtmlBody), StreamId = StreamId, TagIds = Labels != null && Labels.Count != 0 ? new ASC.Mail.Aggregator.Common.Collection.ItemList <int>(Labels) : null, Size = HtmlBody.Length, MimeReplyToId = MimeReplyToId, MimeMessageId = string.IsNullOrEmpty(MimeMessageId) ? MailBoxManager.CreateMessageId() : MimeMessageId }; if (messageItem.Attachments == null) { messageItem.Attachments = new List <MailAttachment>(); } Attachments.ForEach(attachment => { attachment.tenant = tenant; attachment.user = user; }); messageItem.Attachments.AddRange(Attachments); return(messageItem); }
private List <int> StoreAttachmentsToCrm(MailMessageItem item, CrmContactEntity entity) { var file_ids = new List <int>(); foreach (var attachment in item.Attachments.FindAll(attach => !attach.isEmbedded)) { using (var file = AttachmentManager.GetAttachmentStream(attachment)) { var uploaded_file_id = UploadFileToCrm(file.FileStream, file.FileName, attachment.contentType, entity); if (uploaded_file_id > 0) { file_ids.Add(uploaded_file_id); } } } return(file_ids); }
public MailMessageItem GetMessageTemplate() { var send_template = new MailMessageItem { Attachments = new List <MailAttachment>(), Bcc = "", Cc = "", Subject = "", From = "", HtmlBody = "", Important = false, ReplyTo = "", To = "", StreamId = mailBoxManager.CreateNewStreamId() }; return(send_template); }
private static string GetHistoryContentJson(MailMessageItem item) { string contentString; var contentStruct = new CrmHistoryContent { message_id = item.Id }; var serializer = new DataContractJsonSerializer(typeof(CrmHistoryContent)); using (var stream = new MemoryStream()) { serializer.WriteObject(stream, contentStruct); contentString = Encoding.UTF8.GetString(stream.GetCorrectBuffer()); } return(contentString); }
public void AddRelationshipEvents(MailMessageItem item) { var factory = new DaoFactory(CoreContext.TenantManager.GetCurrentTenant().TenantId, CRMConstants.DatabaseId); foreach (var contactEntity in item.LinkedCrmEntityIds) { switch (contactEntity.Type) { case ChainXCrmContactEntity.EntityTypes.Contact: var crmContact = factory.GetContactDao().GetByID(contactEntity.Id); CRMSecurity.DemandAccessTo(crmContact); break; case ChainXCrmContactEntity.EntityTypes.Case: var crmCase = factory.GetCasesDao().GetByID(contactEntity.Id); CRMSecurity.DemandAccessTo(crmCase); break; case ChainXCrmContactEntity.EntityTypes.Opportunity: var crmOpportunity = factory.GetDealDao().GetByID(contactEntity.Id); CRMSecurity.DemandAccessTo(crmOpportunity); break; } var fileIds = new List <int>(); foreach (var attachment in item.Attachments.FindAll(attach => !attach.isEmbedded)) { using (var file = AttachmentManager.GetAttachmentStream(attachment)) { var uploadedFileId = ApiHelper.UploadToCrm(file.FileStream, file.FileName, attachment.contentType, contactEntity); if (uploadedFileId > 0) { fileIds.Add(uploadedFileId); } } } var contentString = GetHistoryContentJson(item); ApiHelper.AddToCrmHistory(item, contactEntity, contentString, fileIds); } }
private void AddRelationshipEventWithCrmApi(MailMessageItem item, CrmContactEntity entity, string content_string, List <int> files_id) { var body_builder = new StringBuilder(); body_builder .AppendFormat("content={0}", HttpUtility.UrlEncode(content_string)) .AppendFormat("&categoryId={0}", MailCrmHistoryCategory) .AppendFormat("&created={0}", HttpUtility.UrlEncode(new ApiDateTime(item.Date).ToString())); var crm_entity_type = entity.Type.StringName(); if (crm_entity_type == ChainXCrmContactEntity.CrmEntityTypeNames.contact) { body_builder.AppendFormat("&contactId={0}&entityId=0", entity.Id); } else { if (crm_entity_type != ChainXCrmContactEntity.CrmEntityTypeNames.Case && crm_entity_type != ChainXCrmContactEntity.CrmEntityTypeNames.opportunity) { throw new ArgumentException(String.Format("Invalid crm entity type: {0}", crm_entity_type)); } body_builder.AppendFormat("&contactId=0&entityId={0}&entityType={1}", entity.Id, crm_entity_type); } if (files_id != null) { foreach (var id in files_id) { body_builder.AppendFormat("&fileId[]={0}", id); } } var request_uri_builder = GetAddRelationshipEventCrmUrl(); var auth_cookie = ApiHelper.GetAuthCookie(UserId, request_uri_builder.Host); byte[] body_bytes = Encoding.UTF8.GetBytes(body_builder.ToString()); var request_stream = new MemoryStream(); request_stream.Write(body_bytes, 0, body_bytes.Length); request_stream.Position = 0; FormUpload.PostForm(request_uri_builder.ToString(), "", "application/x-www-form-urlencoded", request_stream, auth_cookie); }
public async Task <IHttpActionResult> PostAsync(int projectId, [FromBody] MailMessageItemDto model, CancellationToken cancellationToken) { if (model == null || !ModelState.IsValid) { return(BadRequest()); } var project = await _projectManager.FindByIdAsync(projectId, cancellationToken); await ApiSecurity.AuthorizeAsync(project, AccessPermission.CanEdit, cancellationToken); var mailMessage = new MailMessageItem { Subject = model.Subject, Body = model.Body }; var validationResult = await _projectManager.AddMailMessageAsync(project, mailMessage, cancellationToken); if (!validationResult.Succeeded) { return(this.ValidationContent(validationResult)); } return(CreatedAtRoute("Project.Mails.GetById", new RouteValueDictionary { { "id", mailMessage.Id } }, mailMessage)); }
public MailMessageItem ToMailMessageItem(int tennantid, string userid, bool loadAttachments) { Address From_verified; if (Validator.ValidateSyntax(From)) { From_verified = new Address(From, DisplayName); } else { throw new ArgumentException(MailServiceResource.ResourceManager.GetString("ErrorIncorrectEmailAddress").Replace("%1", MailServiceResource.ResourceManager.GetString("FieldNameFrom"))); } List <MailAttachment> internalAttachments = new List <MailAttachment>(); PreprocessHtml(tennantid, internalAttachments); MailMessageItem message_item = new MailMessageItem() { From = From_verified.ToString(), From_Email = From_verified.Email, To = string.Join(", ", To.ToArray()), Cc = Cc != null?string.Join(", ", Cc.ToArray()) : "", Bcc = Bcc != null?string.Join(", ", Bcc.ToArray()) : "", Subject = Subject, Date = DateTime.Now, Important = Important, HtmlBody = HtmlBody, StreamId = StreamId, TagIds = Labels != null && Labels.Count != 0 ? new ItemList <int>(Labels) : null }; message_item.loadAttachments(Attachments.Select(att => CreateAttachment(tennantid, att, loadAttachments)), false); message_item.loadAttachments(internalAttachments.ConvertAll(att => CreateAttachment(tennantid, att, true)), true); return(message_item); }
private void ExecuteHandledAssemblies(MailMessageItem message_item, Message mime_message, MailBox mbox) { foreach (var handler in message_handlers) { try { handler.HandleRetrievedMessage(mbox, mime_message, message_item, MailFolder.Ids.sent, string.Empty, string.Empty, message_item.IsNew, message_item.TagIds != null ? message_item.TagIds.ToArray() : new int[0]); } catch (Exception ex) { log.Error("ExecuteHandledAssemblies() in MailboxId={0} failed with exception:\r\n{1}", mbox.MailBoxId, ex.ToString()); } } }
private static string GetHistoryContentJson(MailMessageItem item) { string content_string; var content_struct = new CrmHistoryContent { message_id = item.Id }; var serializer = new DataContractJsonSerializer(typeof (CrmHistoryContent)); using (var stream = new MemoryStream()) { serializer.WriteObject(stream, content_struct); content_string = Encoding.UTF8.GetString(stream.GetCorrectBuffer()); } return content_string; }
public static string ReplaceEmbeddedImages(MailMessageItem m) { try { var doc = new HtmlDocument(); doc.LoadHtml(m.HtmlBody); if (m.Attachments != null && m.Attachments.Count > 0) { foreach (var attach in m.Attachments) { if (string.IsNullOrEmpty(attach.storedFileUrl)) continue; if (string.IsNullOrEmpty(attach.contentId) && string.IsNullOrEmpty(attach.contentLocation)) continue; HtmlNodeCollection old_nodes = null; if (!string.IsNullOrEmpty(attach.contentId)) { old_nodes = doc.DocumentNode.SelectNodes("//img[@src and (contains(@src,'cid:" + attach.contentId.Trim('<').Trim('>') + "'))]"); } if (!string.IsNullOrEmpty(attach.contentLocation) && old_nodes == null) { old_nodes = doc.DocumentNode.SelectNodes("//img[@src and (contains(@src,'" + attach.contentLocation + "'))]"); } if (old_nodes == null) { //This attachment is not embedded; attach.contentId = null; attach.contentLocation = null; continue; } foreach (var node in old_nodes) node.SetAttributeValue("src", attach.storedFileUrl); } } return doc.DocumentNode.OuterHtml; } catch (RecursionDepthException ex) { throw new Exception(ex.Message); } catch (Exception) { return m.HtmlBody; } }
public override void HandleRetrievedMessage(MailBox mailbox, Message message, MailMessageItem message_item, int folder_id, string uidl, string md5_hash, bool unread, int[] tags_ids) { if (string.IsNullOrEmpty(mailbox.EMailInFolder)) { return; } try { foreach (var attachment in message_item.Attachments) { using (var file = AttachmentManager.GetAttachmentStream(attachment)) { log.Debug("EmailInMessageHandler HandleRetrievedMessage file name: {0}, folder id: {1}", file.FileName, mailbox.EMailInFolder); var uploaded_file_id = FilesUploader.UploadToFiles(file.FileStream, file.FileName, attachment.contentType, mailbox.EMailInFolder, new Guid(mailbox.UserId), log); if (uploaded_file_id < 0) { log.Error("EmailInMessageHandler HandleRetrievedMessage uploaded_file_id < 0"); } } } } catch (WebException we) { var status_code = ((HttpWebResponse)we.Response).StatusCode; if (status_code == HttpStatusCode.NotFound || status_code == HttpStatusCode.Forbidden) { MailBoxManager.CreateUploadToDocumentsFailureAlert(mailbox.TenantId, mailbox.UserId, mailbox.MailBoxId, (status_code == HttpStatusCode.NotFound) ? MailBoxManager.UploadToDocumentsErrorType .FolderNotFound : MailBoxManager.UploadToDocumentsErrorType .AccessDenied); MailBoxManager.SetMailboxEmailInFolder(mailbox.TenantId, mailbox.UserId, mailbox.MailBoxId, null); mailbox.EMailInFolder = null; } throw; } }
private void AddRelationshipEventWithCrmApi(MailMessageItem item, CrmContactEntity entity, string content_string, List<int> files_id) { var body_builder = new StringBuilder(); body_builder .AppendFormat("content={0}", HttpUtility.UrlEncode(content_string)) .AppendFormat("&categoryId={0}", MailCrmHistoryCategory) .AppendFormat("&created={0}", HttpUtility.UrlEncode(new ApiDateTime(item.Date).ToString())); var crm_entity_type = entity.Type.StringName(); if (crm_entity_type == ChainXCrmContactEntity.CrmEntityTypeNames.contact) { body_builder.AppendFormat("&contactId={0}&entityId=0", entity.Id); } else { if (crm_entity_type != ChainXCrmContactEntity.CrmEntityTypeNames.Case && crm_entity_type != ChainXCrmContactEntity.CrmEntityTypeNames.opportunity) throw new ArgumentException(String.Format("Invalid crm entity type: {0}", crm_entity_type)); body_builder.AppendFormat("&contactId=0&entityId={0}&entityType={1}", entity.Id, crm_entity_type); } if (files_id != null) { foreach (var id in files_id) { body_builder.AppendFormat("&fileId[]={0}", id); } } var request_uri_builder = GetAddRelationshipEventCrmUrl(); var auth_cookie = GetAuthCookie(request_uri_builder); byte[] body_bytes = Encoding.UTF8.GetBytes(body_builder.ToString()); var request_stream = new MemoryStream(); request_stream.Write(body_bytes, 0, body_bytes.Length); request_stream.Position = 0; FormUpload.PostForm(request_uri_builder.ToString(), "", "application/x-www-form-urlencoded", request_stream, auth_cookie); }
public override void HandleRetrievedMessage(MailBox mailbox, Message message, MailMessageItem message_item, int folder_id, string uidl, string md5_hash, bool unread, int[] tags_ids) { MailContactsManager.SaveMailContacts(GetDb(), mailbox.TenantId, mailbox.UserId, message, log); }
public MailMessageItem GetMessageTemplate() { var sendTemplate = new MailMessageItem { Attachments = new List<MailAttachment>(), Bcc = "", Cc = "", Subject = "", From = "", HtmlBody = "", Important = false, ReplyTo = "", MimeMessageId = "", MimeReplyToId = "", To = "", StreamId = MailBoxManager.CreateNewStreamId() }; return sendTemplate; }
//Todo: Remove useless parameters from this method private void AddNotificationAlertToMailbox(int tenant_id, string username, MailSendItem item, MailMessageItem result_message, Exception ex, MailBox mbox, Message message) { try { var sb_message = new StringBuilder(1024); var message_delivery = new MailSendItem { Subject = MailApiResource.DeliveryFailureSubject }; message_delivery.To.Add(item.From); message_delivery.From = MailBoxManager.MAIL_DAEMON_EMAIL; message_delivery.Important = true; message_delivery.StreamId = _manager.CreateNewStreamId(); sb_message.Append(@"<style> .button.blue:hover { color: white; background: #57A7D3; background: linear-gradient(top, #78BFE8, #57A7D3 50%, #57A7D3 51%, #3F96C3); background: -o-linear-gradient(top, #78BFE8, #57A7D3 50%, #57A7D3 51%, #3F96C3); background: -moz-linear-gradient(top, #78BFE8, #57A7D3 50%, #57A7D3 51%, #3F96C3); background: -webkit-linear-gradient(top, #78BFE8, #57A7D3 50%, #57A7D3 51%, #3F96C3); border: 1px solid #5EAAD5; } .button.blue { color: white; background: #3D96C6; background: linear-gradient(top, #59B1E2, #3D96C6 50%, #3D96C6 51%, #1A76A6); background: -o-linear-gradient(top, #59B1E2, #3D96C6 50%, #3D96C6 51%, #1A76A6); background: -moz-linear-gradient(top, #59B1E2, #3D96C6 50%, #3D96C6 51%, #1A76A6); background: -webkit-linear-gradient(top, #59B1E2, #3D96C6 50%, #3D96C6 51%, #1A76A6); border-width: 1px; border-style: solid; border-color: #4DA9DC #4098C9 #2D7399 #4098C9; } .button, .button:visited, .button:hover, .button:active { display: inline-block; font-weight: normal; text-align: center; text-decoration: none; vertical-align: middle; cursor: pointer; border-radius: 3px; -moz-border-radius: 3px; -webkit-border-radius: 3px; touch-callout: none; -o-touch-callout: none; -moz-touch-callout: none; -webkit-touch-callout: none; user-select: none; -o-user-select: none; -moz-user-select: none; -webkit-user-select: none; font-size: 12px; line-height: 14px; padding: 2px 12px 3px; color: white; background: #3D96C6; background: linear-gradient(top, #59B1E2, #3D96C6 50%, #3D96C6 51%, #1A76A6); background: -o-linear-gradient(top, #59B1E2, #3D96C6 50%, #3D96C6 51%, #1A76A6); background: -moz-linear-gradient(top, #59B1E2, #3D96C6 50%, #3D96C6 51%, #1A76A6); background: -webkit-linear-gradient(top, #59B1E2, #3D96C6 50%, #3D96C6 51%, #1A76A6); border-width: 1px; border-style: solid; border-color: #4DA9DC #4098C9 #2D7399 #4098C9; } body { color: #333; font: normal 12px Arial, Tahoma,sans-serif; } </style>"); sb_message.AppendFormat("<div style=\"max-width:500px;\"><p style=\"color:gray;\">{0}</p>", MailApiResource.DeliveryFailureAutomaticMessage); sb_message.AppendFormat("<p>{0}</p>", MailApiResource.DeliveryFailureMessageIdentificator .Replace("{subject}", item.Subject) .Replace("{date}", DateTime.Now.ToString(CultureInfo.InvariantCulture))); sb_message.AppendFormat("<div><p>{0}:</p><ul style=\"color:#333;\">", MailApiResource.DeliveryFailureRecipients); item.To.ForEach(rcpt => sb_message.AppendFormat("<li>{0}</li>", HttpUtility.HtmlEncode(rcpt))); item.Cc.ForEach(rcpt => sb_message.AppendFormat("<li>{0}</li>", HttpUtility.HtmlEncode(rcpt))); item.Bcc.ForEach(rcpt => sb_message.AppendFormat("<li>{0}</li>", HttpUtility.HtmlEncode(rcpt))); sb_message.AppendFormat("</ul>"); sb_message.AppendFormat("<p>{0}</p>", MailApiResource.DeliveryFailureRecommendations .Replace("{account_name}", "<b>" + item.From + "</b>")); sb_message.AppendFormat( "<a id=\"delivery_failure_button\" mailid={0} class=\"button blue\" style=\"margin-right:8px;\">", result_message.Id); sb_message.Append(MailApiResource.DeliveryFailureBtn + "</a></div>"); sb_message.AppendFormat("<p>{0}</p>", MailApiResource.DeliveryFailureFAQInformation .Replace("{url_begin}", "<a id=\"delivery_failure_faq_link\" target=\"blank\" href=\"#gmail\">") .Replace("{url_end}", "</a>")); var last_dot_index = ex.Message.LastIndexOf('.'); var smtp_response = ex.Message; if (last_dot_index != -1 && last_dot_index != smtp_response.Length) { try { smtp_response = smtp_response.Remove(last_dot_index + 1, smtp_response.Length - last_dot_index - 1); } catch { } } sb_message.AppendFormat( "<p style=\"color:gray;\">" + MailApiResource.DeliveryFailureReason + ": \"{0}\"</p></div>", smtp_response); message_delivery.HtmlBody = sb_message.ToString(); // SaveToDraft To Inbox var notify_message_item = message_delivery.ToMailMessageItem(tenant_id, username); notify_message_item.MessageId = _manager.CreateMessageId(); notify_message_item.ChainId = notify_message_item.MessageId; notify_message_item.IsNew = true; notify_message_item.IsFromCRM = false; notify_message_item.IsFromTL = false; _manager.StoreMailBody(mbox.TenantId, mbox.UserId, notify_message_item); // ReSharper disable UnusedVariable var id_mail = _manager.MailSave(mbox, notify_message_item, 0, MailFolder.Ids.inbox, MailFolder.Ids.inbox, string.Empty, string.Empty, false); // ReSharper restore UnusedVariable //_manager.UpdateChain(notify_message_item.ChainId, folder, mbox.MailBoxId, mbox.TenantId, mbox.UserId); if (message != null) { _manager.CreateDeliveryFailureAlert(mbox.TenantId, mbox.UserId, item.Subject, item.From, (Int32)result_message.Id); } } catch { /* TODO: add log here */ } }
public MailMessageItem ToMailMessageItem(int tenant, string user) { Address from_verified; if (Validator.ValidateSyntax(From)) from_verified = new Address(From, DisplayName); else throw new ArgumentException(MailApiResource.ErrorIncorrectEmailAddress .Replace("%1", MailApiResource.FieldNameFrom)); var message_item = new MailMessageItem { From = from_verified.ToString(), FromEmail = from_verified.Email, To = string.Join(", ", To.ToArray()), Cc = Cc != null ? string.Join(", ", Cc.ToArray()) : "", Bcc = Bcc != null ? string.Join(", ", Bcc.ToArray()) : "", Subject = Subject, Date = DateTime.Now, Important = Important, HtmlBody = HtmlBody, Introduction = MailMessageItem.GetIntroduction(HtmlBody), StreamId = StreamId, TagIds = Labels != null && Labels.Count != 0 ? new ItemList<int>(Labels) : null, Size = HtmlBody.Length }; if (message_item.Attachments == null) message_item.Attachments = new List<MailAttachment>(); Attachments.ForEach(attachment => { attachment.tenant = tenant; attachment.user = user; }); message_item.Attachments.AddRange(Attachments); return message_item; }
/// <summary> /// Asynchronously enqueues a mail message. /// </summary> /// <param name="from">The sender of the mail message.</param> /// <param name="to">The recipients of the mail message.</param> /// <param name="mailMessage">The mail message to enqueue.</param> /// <param name="placeholders">A map of key/value pairs that can be used to interpolate the content of the mail message.</param> /// <param name="cancellationToken">Propagates notification that operations should be canceled.</param> /// <returns> /// The task object representing the asynchronous operation. /// </returns> protected virtual Task EqueueAllAsync(ProjectItem project, ContactItem from, ImmutableArray <ContactItem> to, MailMessageItem mailMessage, PropertyDictionary placeholders, CancellationToken cancellationToken) { Debug.Assert(project != null); Debug.Assert(from != null); Debug.Assert(to != null); Debug.Assert(mailMessage != null); return(Task.WhenAll( from partition in Partitioner.Create(to).GetPartitions(MaxDegreeOfParallelism) select Task.Run(async() => { using (partition) { while (partition.MoveNext()) { cancellationToken.ThrowIfCancellationRequested(); await EnqueueAsync(project, @from, partition.Current, mailMessage, placeholders, cancellationToken); } } }, cancellationToken))); }
/// <summary> /// Validates the specified <paramref name="mailHeader"/> and <paramref name="mailMessage"/> as an asynchronous operation. /// </summary> /// <param name="project">The project that contains the given contacts.</param> /// <param name="mailHeader">The mail header that defines contacts and filter criteria.</param> /// <param name="mailMessage">The mail message to send.</param> /// <param name="cancellationToken">Propagates notification that operations should be canceled.</param> /// <returns> /// The task object representing the number of the recipients. /// </returns> public virtual Task <ValidationResult> ValidateAsync(ProjectItem project, MailMessageHeader mailHeader, MailMessageItem mailMessage, CancellationToken cancellationToken) { if (project == null) { return(Task.FromResult(ValidationResult.Failed(string.Format(CultureInfo.CurrentCulture, MailResources.MailProjectRequired)))); } if (mailHeader == null) { return(Task.FromResult(ValidationResult.Failed(string.Format(CultureInfo.CurrentCulture, MailResources.MailHeaderRequired)))); } if (mailHeader.To.Count == 0 && mailHeader.IncludeWithTags.Count == 0 && mailHeader.ExcludeWithTags.Count == 0) { return(Task.FromResult(ValidationResult.Failed(string.Format(CultureInfo.CurrentCulture, MailResources.MailFilterPredicateRequired)))); } if (mailMessage == null) { return(Task.FromResult(ValidationResult.Failed(string.Format(CultureInfo.CurrentCulture, MailResources.MailMessageRequired)))); } if (string.IsNullOrWhiteSpace(mailMessage.Subject)) { return(Task.FromResult(ValidationResult.Failed(string.Format(CultureInfo.CurrentCulture, MailResources.MailMessageSubjectRequired)))); } return(Task.FromResult(ValidationResult.Success)); }
/// <summary> /// Enqueues a mail message. /// </summary> protected virtual async Task EnqueueAsync(ProjectItem project, ContactItem from, ContactItem to, MailMessageItem mailMessage, PropertyDictionary placeholders, CancellationToken cancellationToken) { Debug.Assert(project != null); Debug.Assert(from != null); Debug.Assert(to != null); Debug.Assert(mailMessage != null); Debug.Assert(placeholders != null); bool hasSubject = !string.IsNullOrEmpty(mailMessage.Subject); bool hasContent = !string.IsNullOrEmpty(mailMessage.Body); string subject = null; string content = null; if (hasSubject || hasContent) { placeholders = new PropertyDictionary(placeholders); placeholders.AddIfNotExists(StringTemplate.IdentityIdProperty, to.Id); placeholders.AddIfNotExists(MailResources.MailHeaderFrom, from); placeholders.AddIfNotExists(MailResources.MailHeaderTo, to); var immutablePlaceholders = placeholders.ToImmutableDictionary(); if (hasSubject) { subject = await StringTemplate.InterpolateAsync(mailMessage.Subject, immutablePlaceholders, cancellationToken); } if (hasContent) { content = await StringTemplate.InterpolateAsync(mailMessage.Body, immutablePlaceholders, cancellationToken); } } BackgroundJob.Enqueue <MailJobClient>(job => job.Send( new MailJobMessage { MessageId = mailMessage.Id, ProjectId = project.Id, From = new MailJobAddress(from.Id, from.Email.Address, from.Email.Name), To = new MailJobAddress(to.Id, to.Email.Address, to.Email.Name), Subject = subject, Body = content, Users = _userIds })); }
public string StoreMailBody(int tenant, string user, MailMessageItem messageItem) { if (string.IsNullOrEmpty(messageItem.HtmlBody)) { return string.Empty; } // Using id_user as domain in S3 Storage - allows not to add quota to tenant. var savePath = MailStoragePathCombiner.GetBodyKey(user, messageItem.StreamId); var storage = MailDataStore.GetDataStore(tenant); try { var safeBody = ReplaceEmbeddedImages(messageItem, _log); using (var reader = new MemoryStream(Encoding.UTF8.GetBytes(safeBody))) { var res = storage .UploadWithoutQuota(string.Empty, savePath, reader, "text/html", string.Empty) .ToString(); _log.Debug("StoreMailBody() tenant='{0}', user_id='{1}', save_body_path='{2}' Result: {3}", tenant, user, savePath, res); return res; } } catch (Exception ex) { _log.Debug( "StoreMailBody() Problems with message saving in messageId={0}. \r\n Exception: \r\n {0}\r\n", messageItem.MimeMessageId, ex.ToString()); storage.Delete(string.Empty, savePath); throw; } }
//Todo: Remove useless parameters from this method private void AddNotificationAlertToMailbox(int tenant_id, string username, MailSendItem item, MailMessageItem result_message, Exception ex, MailBox mbox) { try { var sb_message = new StringBuilder(1024); var message_delivery = new MailSendItem {Subject = MailApiResource.DeliveryFailureSubject}; message_delivery.To.Add(item.From); message_delivery.From = MailBoxManager.MAIL_DAEMON_EMAIL; message_delivery.Important = true; message_delivery.StreamId = manager.CreateNewStreamId(); sb_message.Append(@"<style> .button.blue:hover { color: white; background: #57A7D3; background: linear-gradient(top, #78BFE8, #57A7D3 50%, #57A7D3 51%, #3F96C3); background: -o-linear-gradient(top, #78BFE8, #57A7D3 50%, #57A7D3 51%, #3F96C3); background: -moz-linear-gradient(top, #78BFE8, #57A7D3 50%, #57A7D3 51%, #3F96C3); background: -webkit-linear-gradient(top, #78BFE8, #57A7D3 50%, #57A7D3 51%, #3F96C3); border: 1px solid #5EAAD5; } .button.blue { color: white; background: #3D96C6; background: linear-gradient(top, #59B1E2, #3D96C6 50%, #3D96C6 51%, #1A76A6); background: -o-linear-gradient(top, #59B1E2, #3D96C6 50%, #3D96C6 51%, #1A76A6); background: -moz-linear-gradient(top, #59B1E2, #3D96C6 50%, #3D96C6 51%, #1A76A6); background: -webkit-linear-gradient(top, #59B1E2, #3D96C6 50%, #3D96C6 51%, #1A76A6); border-width: 1px; border-style: solid; border-color: #4DA9DC #4098C9 #2D7399 #4098C9; } .button, .button:visited, .button:hover, .button:active { display: inline-block; font-weight: normal; text-align: center; text-decoration: none; vertical-align: middle; cursor: pointer; border-radius: 3px; -moz-border-radius: 3px; -webkit-border-radius: 3px; touch-callout: none; -o-touch-callout: none; -moz-touch-callout: none; -webkit-touch-callout: none; user-select: none; -o-user-select: none; -moz-user-select: none; -webkit-user-select: none; font-size: 12px; line-height: 14px; padding: 2px 12px 3px; color: white; background: #3D96C6; background: linear-gradient(top, #59B1E2, #3D96C6 50%, #3D96C6 51%, #1A76A6); background: -o-linear-gradient(top, #59B1E2, #3D96C6 50%, #3D96C6 51%, #1A76A6); background: -moz-linear-gradient(top, #59B1E2, #3D96C6 50%, #3D96C6 51%, #1A76A6); background: -webkit-linear-gradient(top, #59B1E2, #3D96C6 50%, #3D96C6 51%, #1A76A6); border-width: 1px; border-style: solid; border-color: #4DA9DC #4098C9 #2D7399 #4098C9; } body { color: #333; font: normal 12px Arial, Tahoma,sans-serif; } </style>"); sb_message.AppendFormat("<div style=\"max-width:500px;\"><p style=\"color:gray;\">{0}</p>", MailApiResource.DeliveryFailureAutomaticMessage); sb_message.AppendFormat("<p>{0}</p>", MailApiResource.DeliveryFailureMessageIdentificator .Replace("{subject}", item.Subject) .Replace("{date}", DateTime.Now.ToString(CultureInfo.InvariantCulture))); sb_message.AppendFormat("<div><p>{0}:</p><ul style=\"color:#333;\">", MailApiResource.DeliveryFailureRecipients); item.To.ForEach(rcpt =>sb_message.AppendFormat("<li>{0}</li>", HttpUtility.HtmlEncode(rcpt))); item.Cc.ForEach(rcpt =>sb_message.AppendFormat("<li>{0}</li>", HttpUtility.HtmlEncode(rcpt))); item.Bcc.ForEach(rcpt =>sb_message.AppendFormat("<li>{0}</li>", HttpUtility.HtmlEncode(rcpt))); sb_message.AppendFormat("</ul>"); sb_message.AppendFormat("<p>{0}</p>", MailApiResource.DeliveryFailureRecommendations .Replace("{account_name}", "<b>" + item.From + "</b>")); sb_message.AppendFormat( "<a id=\"delivery_failure_button\" mailid={0} class=\"button blue\" style=\"margin-right:8px;\">", result_message.Id); sb_message.Append(MailApiResource.DeliveryFailureBtn + "</a></div>"); sb_message.AppendFormat("<p>{0}</p>", MailApiResource.DeliveryFailureFAQInformation .Replace("{url_begin}", "<a id=\"delivery_failure_faq_link\" target=\"blank\" href=\"#gmail\">") .Replace("{url_end}", "</a>")); var last_dot_index = ex.Message.LastIndexOf('.'); var smtp_response = ex.Message; if (last_dot_index != -1 && last_dot_index != smtp_response.Length) { try { smtp_response = smtp_response.Remove(last_dot_index + 1, smtp_response.Length - last_dot_index - 1); } catch (Exception) { } } sb_message.AppendFormat( "<p style=\"color:gray;\">" + MailApiResource.DeliveryFailureReason + ": \"{0}\"</p></div>", smtp_response); message_delivery.HtmlBody = sb_message.ToString(); // SaveToDraft To Inbox var notify_message_item = message_delivery.ToMailMessageItem(tenant_id, username); notify_message_item.MessageId = manager.CreateMessageId(); notify_message_item.ChainId = notify_message_item.MessageId; notify_message_item.IsNew = true; notify_message_item.IsFromCRM = false; notify_message_item.IsFromTL = false; manager.StoreMailBody(mbox.TenantId, mbox.UserId, notify_message_item); // ReSharper disable UnusedVariable var id_mail = manager.MailSave(mbox, notify_message_item, 0, MailFolder.Ids.inbox, MailFolder.Ids.inbox, string.Empty, string.Empty, false); // ReSharper restore UnusedVariable manager.CreateDeliveryFailureAlert(mbox.TenantId, mbox.UserId, item.Subject, item.From, (Int32) result_message.Id); } catch { //TODO: add log here } }
public string StoreMailBody(int id_tenant, string id_user, MailMessageItem mail) { if (string.IsNullOrEmpty(mail.HtmlBody)) { return string.Empty; } try { var safe_body = ReplaceEmbeddedImages(mail); using (var reader = new MemoryStream(Encoding.UTF8.GetBytes(safe_body))) { // Using id_user as domain in S3 Storage - allows not to add quota to tenant. var save_body_path = MailStoragePathCombiner.GetBodyKey(id_user, mail.StreamId); var res = MailDataStore.GetDataStore(id_tenant) .UploadWithoutQuota(string.Empty, save_body_path, reader, "text/html", string.Empty) .ToString(); _log.Debug("StoreMailBody() tenant='{0}', user_id='{1}', save_body_path='{2}' Result: {3}", id_tenant, id_user, save_body_path, res); return res; } } catch (Exception) { MailDataStore.GetDataStore(id_tenant).Delete(string.Empty, MailStoragePathCombiner.GetBodyKey(id_user, mail.StreamId)); _log.Debug(String.Format("StoreMailBody() Problems with message saving in messageId={0}. Body was deleted.", mail.MessageId)); throw; } }
/// <summary> /// Enqueues emails asynchronously. /// </summary> /// <param name="project">The project that contains the given contacts.</param> /// <param name="mailHeader">The mail header that defines contacts and filter criteria.</param> /// <param name="mailMessage">The mail message to send.</param> /// <param name="cancellationToken">Propagates notification that operations should be canceled.</param> /// <returns> /// The task object representing the number of the recipients. /// </returns> public virtual async Task <ValidationResult> SendAsync(ProjectItem project, MailMessageHeader mailHeader, MailMessageItem mailMessage, CancellationToken cancellationToken) { var validationResult = await ValidateAsync(project, mailHeader, mailMessage, cancellationToken); if (!validationResult.Succeeded) { return(validationResult); } var from = await GetSenderAsync(project, mailHeader, cancellationToken); if (from == null) { throw new InvalidOperationException("The sender of the mail message is not specified."); } var to = await GetRecipientsAsync(project, mailHeader, cancellationToken); if (to.Any()) { Users = await GetUsersAsync(project, cancellationToken); _userIds = Users.Select(u => u.Id).ToImmutableArray(); await EqueueAllAsync(project, from, to, mailMessage, mailHeader.Placeholders, cancellationToken); } return(ValidationResult.Success); }
// Add tags from Teamlab CRM to mail if needed. private void SetCrmTags(MailMessageItem mail, int tenant_id, string user_id) { try { if (mail.ParticipantsCrmContactsId == null) mail.ParticipantsCrmContactsId = GetCrmContactsId(tenant_id, user_id, mail.FromEmail); var allowed_contact_ids = mail.ParticipantsCrmContactsId; using (var db = new DbManager("crm")) { #region Extract CRM tags if (allowed_contact_ids.Count == 0) return; //Todo: Rewrite this to Api call var tag_ids = db.ExecuteList(new SqlQuery("crm_entity_tag") .Distinct() .Select("tag_id") .Where("entity_type", (int)EntityType.Contact) .Where(Exp.In("entity_id", allowed_contact_ids))) .ConvertAll(r => -Convert.ToInt32(r[0])); mail.TagIds = new ItemList<int>(tag_ids); #endregion } } catch (Exception e) { _log.Error("SetCrmTags() Exception:\r\n{0}\r\n", e.ToString()); } }
public static string ReplaceEmbeddedImages(MailMessageItem m, ILogger log = null) { try { log = log ?? new NullLogger(); var doc = new HtmlDocument(); doc.LoadHtml(m.HtmlBody); if (m.Attachments != null && m.Attachments.Count > 0) { foreach (var attach in m.Attachments) { if (string.IsNullOrEmpty(attach.storedFileUrl)) continue; if (string.IsNullOrEmpty(attach.contentId) && string.IsNullOrEmpty(attach.contentLocation)) continue; HtmlNodeCollection oldNodes = null; if (!string.IsNullOrEmpty(attach.contentId)) { oldNodes = doc.DocumentNode.SelectNodes("//img[@src and (contains(@src,'cid:" + attach.contentId.Trim('<').Trim('>') + "'))]"); } if (!string.IsNullOrEmpty(attach.contentLocation) && oldNodes == null) { oldNodes = doc.DocumentNode.SelectNodes("//img[@src and (contains(@src,'" + attach.contentLocation + "'))]"); } if (oldNodes == null) { //This attachment is not embedded; attach.contentId = null; attach.contentLocation = null; continue; } foreach (var node in oldNodes) node.SetAttributeValue("src", attach.storedFileUrl); } } return doc.DocumentNode.OuterHtml; } catch (RecursionDepthException ex) { var data = Encoding.UTF8.GetBytes(m.HtmlBody); m.Attachments.Add(new MailAttachment { size = data.Length, fileName = "original_message.html", contentType = "text/html; charset=utf-8", data = data }); m.HtmlBody = "<div>The received email size is too big. The complete text was saved into a separate file and attached to this email.</div>"; log.Error("ReplaceEmbeddedImages() \r\n Exception: \r\n{0}\r\n", ex.ToString()); return m.HtmlBody; } catch (Exception) { return m.HtmlBody; } }