Beispiel #1
0
        protected virtual void RetrieveMessage(Message message, int folderId, string uidl, string md5Hash, bool hasParseError, bool unread = true, int[] tagsIds = null)
        {
            MailMessage messageItem;

            if (mailBoxManager.MailReceive(Account, message, folderId, uidl, md5Hash, hasParseError, unread, tagsIds, out messageItem) < 1)
            {
                throw new Exception("MailReceive() returned id < 1;");
            }

            if (messageItem == null)
            {
                return;
            }

            mailBoxManager.AddRelationshipEventForLinkedAccounts(Account, messageItem, log);

            mailBoxManager.SaveEmailInData(Account, messageItem, log);

            var now = DateTime.UtcNow;

            if ((now - _lastSignal).TotalSeconds > SIGNALR_WAIT_SECONDS)
            {
                log.Debug("InvokeOnRetrieve add to signalr cache UserId = {0} TenantId = {1}", Account.UserId, Account.TenantId);
                _signalrServiceClient.SendUnreadUser(Account.TenantId, Account.UserId);
                _needSignal = false;
                _lastSignal = now;
            }
            else
            {
                log.Debug("InvokeOnRetreive UserId = {0} TenantId = {1} already exists in signalr cache", Account.UserId, Account.TenantId);
                _needSignal = true;
            }
        }
        private void DoOptionalOperations(MailMessage message, MimeMessage mimeMessage, MailBox mailbox, List <int> tagIds,
                                          ILogger log)
        {
            var manager = new MailBoxManager(log);

            log.Debug("DoOptionalOperations->SetMessageTags()");

            SetMessageTags(manager, message, mailbox, tagIds, log);

            log.Debug("DoOptionalOperations->AddRelationshipEventForLinkedAccounts()");

            manager.AddRelationshipEventForLinkedAccounts(mailbox, message, _tasksConfig.DefaultApiSchema, log);

            log.Debug("DoOptionalOperations->SaveEmailInData()");

            manager.SaveEmailInData(mailbox, message, _tasksConfig.DefaultApiSchema, log);

            log.Debug("DoOptionalOperations->SendAutoreply()");

            manager.SendAutoreply(mailbox, message, _tasksConfig.DefaultApiSchema, log);

            log.Debug("DoOptionalOperations->UploadIcsToCalendar()");

            manager.UploadIcsToCalendar(mailbox, message.CalendarId, message.CalendarUid, message.CalendarEventIcs,
                                        message.CalendarEventCharset, message.CalendarEventMimeType, mailbox.EMail.Address,
                                        _tasksConfig.DefaultApiSchema, log);

            if (_tasksConfig.SaveOriginalMessage)
            {
                log.Debug("DoOptionalOperations->StoreMailEml()");
                StoreMailEml(mailbox.TenantId, mailbox.UserId, message.StreamId, mimeMessage, log);
            }

            if (!_tasksConfig.EnableSignalr)
            {
                log.Debug("DoOptionalOperations->END");
                return;
            }

            var now = DateTime.UtcNow;

            if (mailbox.LastSignalrNotify.HasValue &&
                !((now - mailbox.LastSignalrNotify.Value).TotalSeconds > SIGNALR_WAIT_SECONDS))
            {
                mailbox.LastSignalrNotifySkipped = true;
                return;
            }

            log.Debug("DoOptionalOperations->NotifySignalrIfNeed()");

            NotifySignalrIfNeed(mailbox, log);

            mailbox.LastSignalrNotify        = now;
            mailbox.LastSignalrNotifySkipped = false;

            log.Debug("DoOptionalOperations->END");
        }
        public int Send(int tenant_id, string username, MailSendItem original_message, int mail_id, int mailbox_id)
        {
            var mbox = manager.GetMailBox(mailbox_id);

            if (mbox == null)
            {
                throw new ArgumentException("no such mailbox");
            }

            if (mbox.Name != "")
            {
                original_message.DisplayName = mbox.Name;
            }

            if (string.IsNullOrEmpty(original_message.HtmlBody))
            {
                original_message.HtmlBody = EmptyHtmlBody;
            }

            var message_item = SaveToDraft(original_message, mail_id, mbox);

            if (message_item.Id > 0)
            {
                var user_culture    = Thread.CurrentThread.CurrentCulture;
                var user_ui_culture = Thread.CurrentThread.CurrentUICulture;
                ThreadPool.QueueUserWorkItem(delegate
                {
                    try
                    {
                        Thread.CurrentThread.CurrentCulture   = user_culture;
                        Thread.CurrentThread.CurrentUICulture = user_ui_culture;
                        original_message.ChangeEmbededAttachmentLinks(tenant_id, username);
                        original_message.ChangeSmileLinks();
                        var mime_message = original_message.ToMimeMessage(tenant_id, username, true);

                        if (mbox.RefreshToken != null)
                        {
                            ActiveUp.Net.Mail.SmtpClient.SendSsl(mime_message, mbox.SmtpServer, mbox.SmtpPort,
                                                                 mbox.SmtpAccount, GetAccessToken(mbox),
                                                                 SaslMechanism.OAuth2);
                        }
                        else if (mbox.OutcomingEncryptionType == EncryptionType.None)
                        {
                            if (mbox.AuthenticationTypeSmtp == SaslMechanism.None)
                            {
                                ActiveUp.Net.Mail.SmtpClient.Send(mime_message, mbox.SmtpServer, mbox.SmtpPort);
                            }
                            else
                            {
                                ActiveUp.Net.Mail.SmtpClient.Send(mime_message, mbox.SmtpServer, mbox.SmtpPort,
                                                                  mbox.SmtpAccount, mbox.SmtpPassword,
                                                                  mbox.AuthenticationTypeSmtp);
                            }
                        }
                        else
                        {
                            if (mbox.AuthenticationTypeSmtp == SaslMechanism.None)
                            {
                                ActiveUp.Net.Mail.SmtpClient.SendSsl(mime_message, mbox.SmtpServer, mbox.SmtpPort,
                                                                     mbox.OutcomingEncryptionType);
                            }
                            else
                            {
                                ActiveUp.Net.Mail.SmtpClient.SendSsl(mime_message, mbox.SmtpServer, mbox.SmtpPort,
                                                                     mbox.SmtpAccount, mbox.SmtpPassword,
                                                                     mbox.AuthenticationTypeSmtp,
                                                                     mbox.OutcomingEncryptionType);
                            }
                        }

                        // message was correctly send - lets update its chains id
                        var draft_chain_id = message_item.ChainId;
                        // before moving message from draft to sent folder - lets recalculate its correct chain id
                        message_item.ChainId = manager.DetectChainId(mbox, message_item);
                        // push new message correct chain id to db
                        manager.UpdateMessageChainId(mbox, message_item.Id, MailFolder.Ids.drafts, draft_chain_id,
                                                     message_item.ChainId);

                        manager.UpdateCrmLinkedChainId(mbox.MailBoxId, tenant_id, draft_chain_id,
                                                       message_item.ChainId);

                        //Move to_addresses sent
                        manager.SetConversationsFolder(tenant_id, username, MailFolder.Ids.sent,
                                                       new List <int> {
                            (Int32)message_item.Id
                        });
                        manager.SetMessageFolderRestore(tenant_id, username, MailFolder.Ids.sent,
                                                        (int)message_item.Id);

                        manager.AddRelationshipEventForLinkedAccounts(mbox, message_item, log);

                        ExecuteHandledAssemblies(message_item, mime_message, mbox);

                        StoreMessageToImapSentFolder(mbox, mime_message);

                        StoreEml(mbox, message_item.StreamId, mime_message);
                    }
                    catch (Exception ex)
                    {
                        AddNotificationAlertToMailbox(original_message, (Int32)message_item.Id, ex, mbox);
                    }
                });
            }
            else
            {
                throw new ArgumentException("Failed to_addresses save draft");
            }

            return(message_item.Id > 0 ? (Int32)message_item.Id : 1); // Callback in api will be raised if value > 0
        }
Beispiel #4
0
        public int Send(int tenant_id, string username, MailSendItem item, int mail_id)
        {
            var mbox = _manager.GetMailBox(tenant_id, username, new MailAddress(item.From));

            if (mbox == null)
            {
                throw new ArgumentException("no such mailbox");
            }

            if (mbox.Name != "")
            {
                item.DisplayName = mbox.Name;
            }

            string mime_message_id, in_reply_to;
            var    result_message = SaveToDraft(tenant_id, username, item, mail_id, out mime_message_id, out in_reply_to, mbox);

            if (result_message.Id > 0)
            {
                var user_culture    = Thread.CurrentThread.CurrentCulture;
                var user_ui_culture = Thread.CurrentThread.CurrentUICulture;
                ThreadPool.QueueUserWorkItem(delegate
                {
                    Message message = null;
                    try
                    {
                        Thread.CurrentThread.CurrentCulture   = user_culture;
                        Thread.CurrentThread.CurrentUICulture = user_ui_culture;
                        item.ChangeEmbededAttachmentLinks(tenant_id, username);
                        item.ChangeSmileLinks();
                        message           = item.ToMimeMessage(tenant_id, username, true);
                        message.MessageId = mime_message_id;

                        in_reply_to = in_reply_to.Trim();
                        if (!string.IsNullOrEmpty(in_reply_to))
                        {
                            message.InReplyTo = in_reply_to;
                        }

                        if (mbox.RefreshToken != null)
                        {
                            ActiveUp.Net.Mail.SmtpClient.SendSsl(message, mbox.SmtpServer, mbox.SmtpPort, mbox.SmtpAccount, GetAccessToken(mbox), SaslMechanism.OAuth2);
                        }
                        else if (mbox.OutcomingEncryptionType == EncryptionType.None)
                        {
                            if (mbox.AuthenticationTypeSmtp == SaslMechanism.None)
                            {
                                ActiveUp.Net.Mail.SmtpClient.Send(message, mbox.SmtpServer, mbox.SmtpPort);
                            }
                            else
                            {
                                ActiveUp.Net.Mail.SmtpClient.Send(message, mbox.SmtpServer, mbox.SmtpPort, mbox.SmtpAccount, mbox.SmtpPassword, mbox.AuthenticationTypeSmtp);
                            }
                        }
                        else
                        {
                            if (mbox.AuthenticationTypeSmtp == SaslMechanism.None)
                            {
                                ActiveUp.Net.Mail.SmtpClient.SendSsl(message, mbox.SmtpServer, mbox.SmtpPort, mbox.OutcomingEncryptionType);
                            }
                            else
                            {
                                ActiveUp.Net.Mail.SmtpClient.SendSsl(message, mbox.SmtpServer, mbox.SmtpPort, mbox.SmtpAccount, mbox.SmtpPassword, mbox.AuthenticationTypeSmtp, mbox.OutcomingEncryptionType);
                            }
                        }

                        //Move to_addresses sent
                        _manager.SetConversationsFolder(tenant_id, username, MailFolder.Ids.sent, new List <int> {
                            (Int32)result_message.Id
                        });
                        _manager.SetMessageFolderRestore(tenant_id, username, MailFolder.Ids.sent, (int)result_message.Id);

                        _manager.AddRelationshipEventForLinkedAccounts(mbox, result_message);
                    }
                    catch (Exception ex)
                    {
                        AddNotificationAlertToMailbox(tenant_id, username, item, result_message, ex, mbox, message);
                    }
                });
            }
            else
            {
                throw new ArgumentException("Failed to_addresses save draft");
            }

            return(result_message.Id > 0 ? (Int32)result_message.Id : 1); // Callback in api will be raised if value > 0
        }
Beispiel #5
0
        public long Send(MailDraft draft)
        {
            if (string.IsNullOrEmpty(draft.HtmlBody))
            {
                draft.HtmlBody = EMPTY_HTML_BODY;
            }

            var message = Save(draft);

            if (message.Id <= 0)
            {
                throw new ArgumentException(string.Format("DraftManager-Send: Invalid message.Id = {0}", message.Id));
            }

            ValidateAddresses(DraftFieldTypes.From, new[] { draft.From }, true);
            ValidateAddresses(DraftFieldTypes.To, draft.To, true);
            ValidateAddresses(DraftFieldTypes.Cc, draft.Cc, false);
            ValidateAddresses(DraftFieldTypes.Bcc, draft.Bcc, false);

            var scheme = HttpContext.Current == null
                ? Uri.UriSchemeHttp
                : HttpContext.Current.Request.GetUrlRewriter().Scheme;

            manager.SetDraftSending(draft);

            var taskFactory = new TaskFactory();

            taskFactory.StartNew(() =>
            {
                try
                {
                    CoreContext.TenantManager.SetCurrentTenant(draft.Mailbox.TenantId);

                    SecurityContext.AuthenticateMe(new Guid(draft.Mailbox.UserId));

                    draft.ChangeEmbeddedAttachmentLinks(log);

                    draft.ChangeSmileLinks(log);

                    draft.ChangeAttachedFileLinksAddresses(log);

                    draft.ChangeAttachedFileLinksImages(log);

                    if (!string.IsNullOrEmpty(draft.CalendarIcs))
                    {
                        draft.ChangeAllImagesLinksToEmbedded(log);
                    }

                    draft.ChangeUrlProxyLinks(log);

                    var mimeMessage = draft.ToMimeMessage(!string.IsNullOrEmpty(draft.CalendarIcs), _isAutoreply);

                    using (
                        var mc = new MailClient(draft.Mailbox, CancellationToken.None,
                                                certificatePermit: _sslCertificatePermit, log: log))
                    {
                        mc.Send(mimeMessage,
                                draft.Mailbox.Imap && !DisableImapSendSyncServers.Contains(draft.Mailbox.Server));
                    }

                    try
                    {
                        SaveIcsAttachment(draft, mimeMessage);

                        SendMailNotification(draft);

                        manager.ReleaseSendingDraftOnSuccess(draft, message);

                        manager.AddRelationshipEventForLinkedAccounts(draft.Mailbox, message, scheme, log);

                        manager.SaveEmailInData(draft.Mailbox, message, scheme, log);

                        SaveFrequentlyContactedAddress(draft.Mailbox.TenantId, draft.Mailbox.UserId, mimeMessage,
                                                       scheme);
                    }
                    catch (Exception ex)
                    {
                        log.Error("Unexpected Error in Send() Id = {0}\r\nException: {1}",
                                  message.Id, ex.ToString());
                    }
                }
                catch (Exception ex)
                {
                    log.Error("Mail->Send failed: Exception: {0}", ex.ToString());

                    AddNotificationAlertToMailbox(draft, ex);

                    manager.ReleaseSendingDraftOnFailure(draft);

                    SendMailErrorNotification(draft);
                }
                finally
                {
                    if (_isAutoreply)
                    {
                        manager.SaveAutoreplyHistory(draft.Mailbox, message);
                    }
                }
            }, CancellationToken.None);

            return(message.Id);
        }
        public int Send(int tenant_id, string username, MailSendItem item, int mail_id)
        {
            var mbox = manager.GetMailBox(tenant_id, username, new MailAddress(item.From));

            if (mbox == null)
            {
                throw new ArgumentException("no such mailbox");
            }

            if (mbox.Name != "")
            {
                item.DisplayName = mbox.Name;
            }

            if (string.IsNullOrEmpty(item.HtmlBody))
            {
                item.HtmlBody = EmptyHtmlBody;
            }

            string mime_message_id, in_reply_to;
            var    message_item = SaveToDraft(tenant_id, username, item, mail_id, out mime_message_id, out in_reply_to, mbox);

            if (message_item.Id > 0)
            {
                var user_culture    = Thread.CurrentThread.CurrentCulture;
                var user_ui_culture = Thread.CurrentThread.CurrentUICulture;
                ThreadPool.QueueUserWorkItem(delegate
                {
                    try
                    {
                        Thread.CurrentThread.CurrentCulture   = user_culture;
                        Thread.CurrentThread.CurrentUICulture = user_ui_culture;
                        item.ChangeEmbededAttachmentLinks(tenant_id, username);
                        item.ChangeSmileLinks();
                        var message       = item.ToMimeMessage(tenant_id, username, true);
                        message.MessageId = mime_message_id;

                        in_reply_to = in_reply_to.Trim();
                        if (!string.IsNullOrEmpty(in_reply_to))
                        {
                            message.InReplyTo = in_reply_to;
                        }

                        if (mbox.RefreshToken != null)
                        {
                            ActiveUp.Net.Mail.SmtpClient.SendSsl(message, mbox.SmtpServer, mbox.SmtpPort, mbox.SmtpAccount, GetAccessToken(mbox), SaslMechanism.OAuth2);
                        }
                        else if (mbox.OutcomingEncryptionType == EncryptionType.None)
                        {
                            if (mbox.AuthenticationTypeSmtp == SaslMechanism.None)
                            {
                                ActiveUp.Net.Mail.SmtpClient.Send(message, mbox.SmtpServer, mbox.SmtpPort);
                            }
                            else
                            {
                                ActiveUp.Net.Mail.SmtpClient.Send(message, mbox.SmtpServer, mbox.SmtpPort, mbox.SmtpAccount, mbox.SmtpPassword, mbox.AuthenticationTypeSmtp);
                            }
                        }
                        else
                        {
                            if (mbox.AuthenticationTypeSmtp == SaslMechanism.None)
                            {
                                ActiveUp.Net.Mail.SmtpClient.SendSsl(message, mbox.SmtpServer, mbox.SmtpPort, mbox.OutcomingEncryptionType);
                            }
                            else
                            {
                                ActiveUp.Net.Mail.SmtpClient.SendSsl(message, mbox.SmtpServer, mbox.SmtpPort, mbox.SmtpAccount, mbox.SmtpPassword, mbox.AuthenticationTypeSmtp, mbox.OutcomingEncryptionType);
                            }
                        }

                        // message was correctly send - lets update its chains id
                        var draft_chain_id = message_item.ChainId;
                        // before moving message from draft to sent folder - lets recalculate its correct chain id
                        message_item.ChainId = manager.DetectChainId(mbox, message_item);
                        // push new message correct chain id to db
                        manager.UpdateMessageChainId(mbox, message_item.Id, MailFolder.Ids.drafts, draft_chain_id, message_item.ChainId);

                        manager.UpdateCrmLinkedChainId(mbox.MailBoxId, tenant_id, draft_chain_id, message_item.ChainId);

                        //Move to_addresses sent
                        manager.SetConversationsFolder(tenant_id, username, MailFolder.Ids.sent, new List <int> {
                            (Int32)message_item.Id
                        });
                        manager.SetMessageFolderRestore(tenant_id, username, MailFolder.Ids.sent, (int)message_item.Id);

                        manager.AddRelationshipEventForLinkedAccounts(mbox, message_item);

                        foreach (var handler in message_handlers)
                        {
                            try
                            {
                                handler.HandleRetrievedMessage(mbox,
                                                               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(ex, "MailSendQueue::Send");
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        AddNotificationAlertToMailbox(tenant_id, username, item, message_item, ex, mbox);
                    }
                });
            }
            else
            {
                throw new ArgumentException("Failed to_addresses save draft");
            }

            return(message_item.Id > 0 ? (Int32)message_item.Id : 1); // Callback in api will be raised if value > 0
        }
Beispiel #7
0
        public int Send(int tenant, string username, MailSendItem originalMessage, int mailId, int mailboxId)
        {
            var mbox = manager.GetUnremovedMailBox(mailboxId);

            if (mbox == null)
            {
                throw new ArgumentException("no such mailbox");
            }

            originalMessage.MailboxId = mbox.MailBoxId;

            if (mbox.Name != "")
            {
                originalMessage.DisplayName = mbox.Name;
            }

            if (string.IsNullOrEmpty(originalMessage.HtmlBody))
            {
                originalMessage.HtmlBody = EMPTY_HTML_BODY;
            }

            var messageItem = SaveToDraft(originalMessage, mailId, mbox);

            if (messageItem.Id > 0)
            {
                var userCulture   = Thread.CurrentThread.CurrentCulture;
                var userUiCulture = Thread.CurrentThread.CurrentUICulture;
                var scheme        = HttpContext.Current.Request.GetUrlRewriter().Scheme;
                // move to_addresses temp
                manager.SetConversationsFolder(tenant, username, MailFolder.Ids.temp,
                                               new List <int> {
                    (Int32)messageItem.Id
                });
                manager.SetMessageFolderRestore(tenant, username, MailFolder.Ids.drafts,
                                                (int)messageItem.Id);
                ThreadPool.QueueUserWorkItem(delegate
                {
                    Message mimeMessage;
                    try
                    {
                        Thread.CurrentThread.CurrentCulture   = userCulture;
                        Thread.CurrentThread.CurrentUICulture = userUiCulture;

                        CoreContext.TenantManager.SetCurrentTenant(tenant);
                        SecurityContext.AuthenticateMe(new Guid(username));

                        ApiHelper.SetupScheme(scheme);

                        originalMessage.ChangeEmbededAttachmentLinks(tenant, username);
                        originalMessage.ChangeSmileLinks();

                        originalMessage.ChangeAttachedFileLinksAddresses(tenant);
                        originalMessage.ChangeAttachedFileLinksImages();

                        mimeMessage = originalMessage.ToMimeMessage(tenant, username, true);

                        var smptClient = MailClientBuilder.Smtp();

                        if (mbox.RefreshToken != null)
                        {
                            smptClient.SendSsl(mimeMessage, mbox.SmtpServer, mbox.SmtpPort,
                                               mbox.SmtpAccount, GetAccessToken(mbox),
                                               SaslMechanism.OAuth2);
                        }
                        else if (mbox.OutcomingEncryptionType == EncryptionType.None)
                        {
                            if (mbox.AuthenticationTypeSmtp == SaslMechanism.None)
                            {
                                smptClient.Send(mimeMessage, mbox.SmtpServer, mbox.SmtpPort);
                            }
                            else
                            {
                                smptClient.Send(mimeMessage, mbox.SmtpServer, mbox.SmtpPort,
                                                mbox.SmtpAccount, mbox.SmtpPassword,
                                                mbox.AuthenticationTypeSmtp);
                            }
                        }
                        else
                        {
                            if (mbox.AuthenticationTypeSmtp == SaslMechanism.None)
                            {
                                smptClient.SendSsl(mimeMessage, mbox.SmtpServer, mbox.SmtpPort,
                                                   mbox.OutcomingEncryptionType);
                            }
                            else
                            {
                                smptClient.SendSsl(mimeMessage, mbox.SmtpServer, mbox.SmtpPort,
                                                   mbox.SmtpAccount, mbox.SmtpPassword,
                                                   mbox.AuthenticationTypeSmtp,
                                                   mbox.OutcomingEncryptionType);
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        AddNotificationAlertToMailbox(originalMessage, (Int32)messageItem.Id, ex, mbox);

                        // move to_addresses drafts
                        manager.SetConversationsFolder(tenant, username, MailFolder.Ids.drafts,
                                                       new List <int> {
                            (Int32)messageItem.Id
                        });
                        manager.SetMessageFolderRestore(tenant, username, MailFolder.Ids.drafts,
                                                        (int)messageItem.Id);

                        // send unsuccess notification
                        SendMailNotification(tenant, username, 1);

                        return;
                    }

                    SendMailNotification(tenant, username, 0);

                    try
                    {
                        // message was correctly send - lets update its chains id
                        var draftChainId = messageItem.ChainId;
                        // before moving message from draft to sent folder - lets recalculate its correct chain id
                        messageItem.ChainId = manager.DetectChainId(mbox, messageItem);
                        // push new message correct chain id to db
                        manager.UpdateMessageChainId(mbox, messageItem.Id, MailFolder.Ids.temp, draftChainId,
                                                     messageItem.ChainId);

                        manager.UpdateCrmLinkedChainId(mbox.MailBoxId, tenant, draftChainId,
                                                       messageItem.ChainId);

                        // move to_addresses sent
                        manager.SetConversationsFolder(tenant, username, MailFolder.Ids.sent,
                                                       new List <int> {
                            (Int32)messageItem.Id
                        });
                        manager.SetMessageFolderRestore(tenant, username, MailFolder.Ids.sent,
                                                        (int)messageItem.Id);

                        manager.AddRelationshipEventForLinkedAccounts(mbox, messageItem, log);

                        manager.SaveEmailInData(mbox, messageItem, log);

                        manager.SaveMailContacts(mbox.TenantId, mbox.UserId, mimeMessage);

                        StoreMessageToImapSentFolder(mbox, mimeMessage);
                    }
                    catch (Exception ex)
                    {
                        log.Error("Unexpected Error in Send(), message_item.Id = {0}, {1}, {2}",
                                  messageItem.Id, ex.ToString(), ex.StackTrace);
                    }
                });
            }
            else
            {
                throw new ArgumentException("Failed to_addresses save draft");
            }

            return(messageItem.Id > 0 ? (Int32)messageItem.Id : 1); // Callback in api will be raised if value > 0
        }
        private void DoOptionalOperations(MailMessage message, MimeMessage mimeMessage, MailBox mailbox, int[] tagIds, ILogger log)
        {
            var manager = new MailBoxManager(log);

            CoreContext.TenantManager.SetCurrentTenant(mailbox.TenantId);

            SecurityContext.AuthenticateMe(new Guid(mailbox.UserId));

            try
            {
                if (mailbox.Imap)
                {
                    if (tagIds != null) // Add new tags to existing messages
                    {
                        foreach (var tagId in tagIds)
                        {
                            manager.SetMessagesTag(mailbox.TenantId, mailbox.UserId, tagId, new[] { (int)message.Id });
                        }
                    }
                }
            }
            catch (Exception e)
            {
                _log.Error("SetMessagesTag(tenant={0}, userId='{1}', messageId={2}, tagid = {3}) Exception:\r\n{4}\r\n",
                           mailbox.TenantId, mailbox.UserId, message.Id, e.ToString(), tagIds != null ? string.Join(",", tagIds) : "null");
            }

            manager.AddRelationshipEventForLinkedAccounts(mailbox, message, _tasksConfig.DefaultApiSchema, log);

            manager.SaveEmailInData(mailbox, message, _tasksConfig.DefaultApiSchema, log);

            manager.SendAutoreply(mailbox, message, _tasksConfig.DefaultApiSchema, log);

            manager.UploadIcsToCalendar(
                mailbox,
                message.CalendarId,
                message.CalendarUid,
                message.CalendarEventIcs,
                message.CalendarEventCharset,
                message.CalendarEventMimeType,
                mailbox.EMail.Address,
                _tasksConfig.DefaultApiSchema, log);

            if (_tasksConfig.SaveOriginalMessage)
            {
                StoreMailEml(mailbox.TenantId, mailbox.UserId, message.StreamId, mimeMessage, log);
            }

            if (!_tasksConfig.EnableSignalr)
            {
                return;
            }

            var now = DateTime.UtcNow;

            if (mailbox.LastSignalrNotify.HasValue &&
                !((now - mailbox.LastSignalrNotify.Value).TotalSeconds > SIGNALR_WAIT_SECONDS))
            {
                mailbox.LastSignalrNotifySkipped = true;
                return;
            }

            NotifySignalr(mailbox, log);

            mailbox.LastSignalrNotify        = now;
            mailbox.LastSignalrNotifySkipped = false;
        }
        public int Send(MailDraft draft)
        {
            if (string.IsNullOrEmpty(draft.HtmlBody))
            {
                draft.HtmlBody = EMPTY_HTML_BODY;
            }

            var message = Save(draft);

            if (message.Id > 0)
            {
                ValidateAddresses(DraftFieldTypes.From, new[] { draft.From }, true);
                ValidateAddresses(DraftFieldTypes.To, draft.To, true);
                ValidateAddresses(DraftFieldTypes.Cc, draft.Cc, false);
                ValidateAddresses(DraftFieldTypes.Bcc, draft.Bcc, false);

                var scheme = HttpContext.Current == null ? Uri.UriSchemeHttp : HttpContext.Current.Request.GetUrlRewriter().Scheme;

                manager.SetDraftSending(draft);

                ThreadPool.QueueUserWorkItem(_ =>
                {
                    try
                    {
                        CoreContext.TenantManager.SetCurrentTenant(draft.Mailbox.TenantId);

                        SecurityContext.AuthenticateMe(new Guid(draft.Mailbox.UserId));

                        ApiHelper.SetupScheme(scheme);

                        draft.ChangeEmbededAttachmentLinks(log);

                        draft.ChangeSmileLinks(log);

                        draft.ChangeAttachedFileLinksAddresses(log);

                        draft.ChangeAttachedFileLinksImages(log);

                        var mimeMessage = draft.ToMimeMessage(true);

                        var smtp = MailClientBuilder.Smtp();

                        smtp.Send(draft.Mailbox, mimeMessage, log);

                        try
                        {
                            SendMailNotification(draft.Mailbox.TenantId, draft.Mailbox.UserId, 0);

                            manager.ReleaseSendingDraftOnSuccess(draft, message);

                            manager.AddRelationshipEventForLinkedAccounts(draft.Mailbox, message, log);

                            manager.SaveEmailInData(draft.Mailbox, message, log);

                            manager.SaveMailContacts(draft.Mailbox.TenantId, draft.Mailbox.UserId, mimeMessage);

                            StoreMessageToImapSentFolder(draft.Mailbox, mimeMessage);
                        }
                        catch (Exception ex)
                        {
                            log.Error("Unexpected Error in Send() Id = {0}\r\nException: {1}",
                                      message.Id, ex.ToString());
                        }
                    }
                    catch (Exception ex)
                    {
                        AddNotificationAlertToMailbox(draft, ex);

                        manager.ReleaseSendingDraftOnFailure(draft);

                        SendMailNotification(draft.Mailbox.TenantId, draft.Mailbox.UserId, 1);
                    }
                });
            }
            else
            {
                throw new ArgumentException("Failed to_addresses save draft");
            }

            return(message.Id > 0 ? (Int32)message.Id : 1); // Callback in api will be raised if value > 0
        }