public void CreateUpdateFromReceivedEmail(ReceivedEmailMessage message)
        {
            if (message.EmailForCorrespondence != null)
            {
                return;
            }

            if (message.OriginalMessage?.EmailForCorrespondence != null)
            {
                message.EmailForCorrespondence = message.OriginalMessage.EmailForCorrespondence;
                message.Save();
                return;
            }

            Func <string, string> formatEntityName = (s) => s.Replace('<', '(').Replace('>', ')');

            // create a new Correspondence Stream
            var corrStream = Entity.Create <CorrespondenceStream>();

            corrStream.Name = $"Correspondence initiated from received email from {formatEntityName(message.EmFrom)}";

            var corr = Entity.Create <Correspondence>();

            corr.Name        = $"Email Correspondence to {formatEntityName(message.EmTo)} from {formatEntityName(message.EmFrom)}";
            corr.CorrFrom    = message.EmFrom;
            corr.CorrTo      = message.EmFrom;
            corr.CorrContent = ExtractUserResponseFromBody(message.EmBody);
            corr.CorrespondenceAttachments.AddRange(message.EmAttachments);
            corr.CorrespondenceSourceEmail = Entity.As <EmailMessage>(message);
            corrStream.CorrespondenceLog.Add(corr);

            corrStream.Save();
        }
        public bool BeforeSave(ReceivedEmailMessage message, out Action postSaveAction)
        {
            postSaveAction = null;

            string sequenceString;
            long   tenantId;
            long   sequenceId;

            try
            {
                UserTaskHelper.SequenceIdGenerator.SplitSequenceId(message.EmSubject, out sequenceString, out tenantId, out sequenceId);
            }
            catch (SequenceIdGenerator.InvalidSequenceId)
            {
                return(false); // no sequence, so ignore the message
            }

            var task = UserTaskHelper.GetTaskFromEmbededSequenceId(sequenceString);

            if (task == null)
            {
                SendNoTaskReply(message);
            }
            else if (task.UserTaskCompletedOn != null)
            {
                SendTaskCompletedReply(message);
            }
            else
            {
                // try to complete the message
                var completionOptions = task.WorkflowRunForTask.PendingActivity.ForwardTransitions;

                var completionState = ExtractCompletionOption(completionOptions, message.EmBody);

                if (completionState == null)
                {
                    SendInvalidStateReply(message);
                }
                else
                {
                    // update the task after the save
                    var taskId = task.Id;

                    postSaveAction = () =>
                    {
                        UserTaskHelper.ProcessApproval(task, completionState, (writableTask) =>
                        {
                            writableTask.RelatedMessages.Add(message.Cast <EmailMessage>());
                        });
                    };
                }
            }

            return(false);
        }
Beispiel #3
0
        void RunWorkflow(Workflow workflow, string argName, ReceivedEmailMessage message)
        {
            var args = new Dictionary <string, object>
            {
                { argName, new EntityRef(message) }
            };

            WorkflowRunner.Instance.RunWorkflow(new WorkflowStartEvent(workflow)
            {
                Arguments = args
            });
        }
        /// <summary>
        ///     Gets the type of the event creation.
        /// </summary>
        /// <param name="message">The message.</param>
        /// <returns>
        ///     An EntityRef describing the type to create.
        /// </returns>
        private static EntityRef GetEventCreationType(ReceivedEmailMessage message)
        {
            EntityRef type = null;

            if (message != null && message.FromInbox != null)
            {
                Inbox inbox = message.FromInbox;

                if (inbox.InboxCreatedEventType != null)
                {
                    type = inbox.InboxCreatedEventType;
                }
            }

            return(type ?? new EntityRef("core:eventEmail"));
        }
Beispiel #5
0
        /// <summary>
        /// Executed before the message is saved
        /// </summary>
        /// <param name="message"></param>
        /// <param name="postSaveAction">if not null an action run after the save. This happens even if the save is cancelled.</param>
        /// <returns>
        /// True if the save is to be cancelled
        /// </returns>
        public bool BeforeSave(ReceivedEmailMessage message, out Action postSaveAction)
        {
            postSaveAction = null;

            /////
            // Get the references from the received email.
            /////
            string referencesString = message.EmReferences;

            if (!string.IsNullOrEmpty(referencesString))
            {
                /////
                // Parse out each reference as there may be many.
                /////
                List <string> messageIds = EmailHelper.GetMessageIds(referencesString);

                foreach (string messageId in messageIds)
                {
                    /////
                    // Get the local part of the message Id.
                    /////
                    string messageIdLocalPart = EmailHelper.GetMessageIdLocalPart(messageId);

                    if (!string.IsNullOrEmpty(messageIdLocalPart))
                    {
                        /////
                        // Locate any Sent emails that have the same sequence number.
                        /////
                        var sentEmail = Entity.GetByField <SentEmailMessage>(messageIdLocalPart, true, SentEmailMessage.SemSequenceNumber_Field).FirstOrDefault( );

                        if (sentEmail != null)
                        {
                            /////
                            // Link the send email to this received message.
                            /////
                            message.OriginalMessage = sentEmail;

                            break;
                        }
                    }
                }
            }

            return(false);
        }
Beispiel #6
0
        /// <summary>
        /// Create a ReceivedEmailMessage entity from a mail message
        /// </summary>
        /// <param name="msg"></param>
        /// <param name="inboxReceivedMessageType"></param>
        /// <returns></returns>
        ReceivedEmailMessage CreateReceivedEmailMessage(MailMessage msg, Class inboxReceivedMessageType)
        {
            ReceivedEmailMessage returnMessage = null;

            if (inboxReceivedMessageType != null)
            {
                var entity = inboxReceivedMessageType.Activate <IEntity>();

                if (entity != null)
                {
                    returnMessage = entity.As <ReceivedEmailMessage>();
                }
            }

            if (returnMessage == null)
            {
                returnMessage = new ReceivedEmailMessage();
            }

            returnMessage.Name = msg.Subject;

            return(returnMessage);
        }
        public void Test()
        {
            string messageIdLocalPart;

            var sentMessage = new SentEmailMessage
            {
                EmTo      = "*****@*****.**",
                EmFrom    = "*****@*****.**",
                EmBody    = "body",
                EmIsHtml  = false,
                EmSubject = "subject"
            };

            sentMessage.Save( );

            messageIdLocalPart = sentMessage.SemSequenceNumber;

            var receivedMessage = new ReceivedEmailMessage
            {
                EmTo         = "*****@*****.**",
                EmFrom       = "*****@*****.**",
                EmSubject    = "Re: " + sentMessage.EmSubject,
                EmBody       = "body",
                EmIsHtml     = false,
                EmReferences = EmailHelper.GenerateMessageId(messageIdLocalPart, "localhost")
            };

            var matchAction = new MatchSentToReceivedEmailsAction( );

            Action postSaveAction;

            Assert.IsFalse(matchAction.BeforeSave(receivedMessage, out postSaveAction));
            Assert.IsNull(postSaveAction);
            Assert.IsNotNull(receivedMessage.OriginalMessage, "The original message has been found.");
            Assert.AreEqual(sentMessage.Id, receivedMessage.OriginalMessage.Id, "The original message has been set correctly.");
        }
        /// <summary>
        ///     Executed before the message is saved
        /// </summary>
        /// <param name="message"></param>
        /// <param name="postSaveAction">if not null an action run after the save. This happens even if the save is cancelled.</param>
        /// <returns>
        ///     True if the save is to be cancelled
        /// </returns>
        public bool BeforeSave(ReceivedEmailMessage message, out Action postSaveAction)
        {
            postSaveAction = null;

            /////
            // Check the message.
            /////
            if (message == null)
            {
                return(false);
            }

            var iCalMessage = message.As <ReceivedICalEmailMessage>( );

            /////
            // Ensure the message is a received iCal email message.
            /////
            if (iCalMessage == null)
            {
                return(false);
            }

            /////
            // The iCalUpdate field was set by the iCalMailMesssageFormatter that was called as part
            // of the ProcessInboxes action.
            /////
            if (string.IsNullOrEmpty(iCalMessage.ICalUpdate))
            {
                return(false);
            }

            /////
            // Read the iCal update.
            /////
            using (var sr = new StringReader(iCalMessage.ICalUpdate))
            {
                /////
                // Deserialize the string into the iCal object model.
                /////
                IICalendarCollection iCalendarCollection = iCalendar.LoadFromStream(sr);

                if (iCalendarCollection == null)
                {
                    return(false);
                }

                /////
                // Get the first calendar.
                /////
                IICalendar calendar = iCalendarCollection.FirstOrDefault( );

                if (calendar == null || calendar.Events == null)
                {
                    return(false);
                }

                /////
                // Get the first calendar event.
                /////
                IEvent calendarEvent = calendar.Events.FirstOrDefault( );

                if (calendarEvent == null)
                {
                    return(false);
                }

                /////
                // Make sure the calendar events UID is set.
                /////
                if (string.IsNullOrEmpty(calendarEvent.Uid))
                {
                    return(false);
                }

                EventEmail  eventEntity = null;
                Appointment appointment = null;

                /////
                // Find all sent iCal UID containers that correlate to the received calendar events UID.
                /////
                IEnumerable <ICalUidContainer> iCalUidContainers = Entity.GetByField <ICalUidContainer>(calendarEvent.Uid, ICalUidContainer.ICalUid_Field);

                if (iCalUidContainers != null)
                {
                    /////
                    // Get the first sent message.
                    /////
                    ICalUidContainer iCalUidContainer = iCalUidContainers.FirstOrDefault( );

                    if (iCalUidContainer != null && iCalUidContainer.CalendarEventEmail != null)
                    {
                        /////
                        // Get the original event email object that was used to create the sent iCal Email Message.
                        /////
                        eventEntity = iCalUidContainer.CalendarEventEmail.AsWritable <EventEmail>( );
                    }
                }

                bool modificationsMade = false;

                if (eventEntity == null)
                {
                    /////
                    // No existing event email so this is a new request.
                    /////
                    EntityRef type = GetEventCreationType(message);

                    eventEntity = type != null?Entity.Create(type).As <EventEmail>( ) : new EventEmail( );

                    appointment = Entity.Create <Appointment>();
                    eventEntity.EventEmailAppt = appointment;

                    modificationsMade = true;

                    eventEntity.Name = calendarEvent.Summary;

                    var calUidContainer = new ICalUidContainer
                    {
                        ICalUid = calendarEvent.Uid
                    };

                    eventEntity.CalendarId = calUidContainer;

                    string creatorEmailAddress = GetEmailAddress(message.EmFrom);

                    if (creatorEmailAddress != null)
                    {
                        EmailContact creatorEmailContact = FindEmailContact(creatorEmailAddress);

                        if (creatorEmailContact == null)
                        {
                            var mailAddress = new MailAddress(message.EmFrom);

                            creatorEmailContact = CreateEmailContact(creatorEmailAddress, mailAddress.DisplayName ?? creatorEmailAddress);
                        }

                        eventEntity.EventEmailCreator = creatorEmailContact;
                    }

                    foreach (IAttendee attendee in calendarEvent.Attendees)
                    {
                        string emailAddress = GetEmailAddress(attendee.Value.ToString( ));

                        if (emailAddress != null)
                        {
                            EmailContact emailContact = FindEmailContact(emailAddress);

                            if (emailContact == null)
                            {
                                CreateEmailContact(emailAddress, attendee.CommonName);
                            }

                            appointment.EventEmailAttendees.Add(emailContact.EmailContactOwner);
                        }
                    }

                    CreateAndSendAcceptance(calendar, iCalMessage, eventEntity);
                }
                else
                {
                    appointment = eventEntity.EventEmailAppt;

                    if (calendar.Method == Methods.Publish || calendar.Method == Methods.Request)
                    {
                        /////
                        // A REQUEST or PUBLISH means a new event arriving in the system.
                        /////
                        CreateAndSendAcceptance(calendar, iCalMessage, eventEntity);
                    }
                }


                eventEntity.ReceivedEmailMessages.Add(iCalMessage);


                /////
                // Start time.
                /////
                if (calendarEvent.Start != null)
                {
                    DateTime utcTime = calendarEvent.Start.Utc;

                    if (!Equals(utcTime, appointment.EventStart))
                    {
                        appointment.EventStart = utcTime;
                        modificationsMade      = true;
                    }
                }

                /////
                // End time.
                /////
                if (calendarEvent.End != null)
                {
                    DateTime utcTime = calendarEvent.End.Utc;

                    if (!Equals(utcTime, appointment.EventEnd))
                    {
                        appointment.EventEnd = utcTime;
                        modificationsMade    = true;
                    }
                }

                /////
                // All Day Event.
                /////
                if (appointment.EventIsAllDay == null || !Equals(calendarEvent.IsAllDay, appointment.EventIsAllDay.Value))
                {
                    appointment.EventIsAllDay = calendarEvent.IsAllDay;
                    modificationsMade         = true;
                }

                /////
                // Location.
                /////
                if (calendarEvent.Location != null)
                {
                    if (!Equals(calendarEvent.Location, appointment.EventLocation))
                    {
                        appointment.EventLocation = calendarEvent.Location;
                        modificationsMade         = true;
                    }
                }

                /////
                // Location.
                /////
                if (eventEntity.EventEmailAppt.EventEmailPriority == null || !Equals(calendarEvent.Priority, eventEntity.EventEmailAppt.EventEmailPriority))
                {
                    string priorityAlias;

                    if (calendarEvent.Priority <= 0)
                    {
                        /////
                        // Undefined.
                        /////
                        priorityAlias = null;
                    }
                    else if (calendarEvent.Priority <= 4)
                    {
                        /////
                        // High priority.
                        /////
                        priorityAlias = "core:highPriority";
                    }
                    else if (calendarEvent.Priority == 5)
                    {
                        /////
                        // Normal priority.
                        /////
                        priorityAlias = "core:normalPriority";
                    }
                    else if (calendarEvent.Priority <= 9)
                    {
                        /////
                        // Low priority.
                        /////
                        priorityAlias = "core:lowPriority";
                    }
                    else
                    {
                        /////
                        // Invalid priority.
                        /////
                        priorityAlias = null;
                    }

                    eventEntity.EventEmailAppt.EventEmailPriority = priorityAlias != null?Entity.Get <EventEmailPriorityEnum>(priorityAlias) : null;

                    modificationsMade = true;
                }

                /////
                // Status.
                /////
                string statusAlias = null;

                switch (calendarEvent.Status)
                {
                case EventStatus.Cancelled:
                    statusAlias = "core:eventStatusCancelled";
                    break;

                case EventStatus.Confirmed:
                    statusAlias = "core:eventStatusConfirmed";
                    break;

                case EventStatus.Tentative:
                    statusAlias = "core:eventStatusTentative";
                    break;
                }

                if (!string.IsNullOrEmpty(statusAlias))
                {
                    if (appointment.EventStatus == null || appointment.EventStatus.Alias != statusAlias)
                    {
                        appointment.EventStatus = Entity.Get <EventStatusEnum>(statusAlias);
                        modificationsMade       = true;
                    }
                }

                if (modificationsMade)
                {
                    CustomContext cc = null;

                    try
                    {
                        string timeZone = null;

                        if (eventEntity != null)
                        {
                            /////
                            // Find all sent iCal Email Messages that correlate to the received calendar events UID.
                            /////
                            IEnumerable <SentICalEmailMessage> sentICalEmailMessages = eventEntity.SentEmailMessages;

                            if (sentICalEmailMessages != null)
                            {
                                SentICalEmailMessage sentICalEmailMessage = sentICalEmailMessages.FirstOrDefault(sent => sent.ICalTimeZone != null);

                                if (sentICalEmailMessage != null)
                                {
                                    timeZone = sentICalEmailMessage.ICalTimeZone;
                                }
                            }
                        }

                        if (string.IsNullOrEmpty(timeZone))
                        {
                            if (calendar.TimeZones != null)
                            {
                                ITimeZone calendarTimeZone = calendar.TimeZones.FirstOrDefault( );

                                if (calendarTimeZone != null)
                                {
                                    timeZone = calendarTimeZone.TzId;
                                }
                            }
                        }

                        if (!string.IsNullOrEmpty(timeZone))
                        {
                            /////
                            // Set up a custom context just for the duration of this call.
                            /////
                            RequestContext currentRequestContext = RequestContext.GetContext( );

                            var data = new RequestContextData(currentRequestContext)
                            {
                                TimeZone = timeZone
                            };

                            cc = new CustomContext(data);
                        }

                        eventEntity.Save( );
                    }
                    finally
                    {
                        /////
                        // Ensure the custom context is disposed.
                        /////
                        if (cc != null)
                        {
                            cc.Dispose( );
                        }
                    }
                }
            }

            return(false);
        }
 private void SendInvalidStateReply(ReceivedEmailMessage message)
 {
     // TODO: Add send
 }
 private void SendNoTaskReply(ReceivedEmailMessage message)
 {
     // TODO: add send
 }
 private void SendTaskCompletedReply(ReceivedEmailMessage message)
 {
     // TODO: add send
 }
 public bool BeforeSave(ReceivedEmailMessage message, out Action postSaveAction)
 {
     postSaveAction = () => { CreateUpdateFromReceivedEmail(message); };
     return(true);
 }