/// <summary>
        /// Save the information about a given peer. In a VoIP PBX system a peer is a physical
        /// device. A person may have multiple peers associated with him/her. For example I
        /// have a physical desk phone (first peer), a VoIP client on my iPhone (second peer).
        /// This method has been written on the assumption that I only care about my primary
        /// (desk phone) peer. We name our SIP peers after the extension, so my extension of
        /// 268 has a peer defined as "268".
        /// </summary>
        /// <param name="organizationId">The organization we are currently working in.</param>
        /// <param name="extensionRules">A collection of Lookups to use in matching this peer to a person.</param>
        /// <param name="objectName">The name of this peer object.</param>
        /// <param name="acl">Not a clue.</param>
        /// <param name="dynamic">If this is a dynamic (i.e. DHCP) peer.</param>
        /// <param name="natSupport">Does the peer support NAT?</param>
        /// <param name="ip">IP address of the peer.</param>
        /// <param name="type">The type of peer, e.g. SIP or IAX2.</param>
        private void SavePeer(int organizationId, LookupCollection extensionRules, string objectName, bool acl, bool dynamic, bool natSupport, string ip, string type)
        {
            string internalNumber = objectName;

            //
            // Match this peer to a extension and build internalNumber
            // to be the full phone number to reach this peer.
            //
            foreach (Lookup rule in extensionRules)
            {
                if (Regex.Match(objectName, rule.Qualifier).Success)
                {
                    if (rule.Qualifier3 != string.Empty)
                    {
                        internalNumber = rule.Qualifier3.Replace("##orig##", objectName);
                    }
                }
            }

            //
            // Find a person who has this exact phone number. If more than one person
            // is found, the first match is used.
            //
            PersonCollection peerPersons = new PersonCollection();

            peerPersons.LoadByPhone(internalNumber);
            if (peerPersons.Count > 0)
            {
                //
                // Save the new Phone Peer object, which associates a physical phone to a person.
                //
                Arena.Phone.Peer peer = new Arena.Phone.Peer(objectName);
                peer.PersonId       = peerPersons[0].PersonID;
                peer.Acl            = acl;
                peer.Dynamic        = dynamic;
                peer.NatSupport     = natSupport;
                peer.Ip             = ip;
                peer.ObjectName     = objectName;
                peer.Type           = type;
                peer.OrganizationId = organizationId;
                peer.InternalNumber = internalNumber;
                peer.LastAuditId    = _sessionGuid;
                peer.Save("voipManager");
            }
        }
Beispiel #2
0
        public Contracts.GenericListResult <Contracts.PersonReference> GetPersonMatch(string email, string firstname, string lastname, string gender, string maritalstatus, string campus, string street1, string street2, string city, string state, string postalcode, string phonehome, string phonecell, string birthdate, string matchpercentminimum, string sessionid)
        {
            Contracts.GenericListResult <Contracts.PersonReference> personReferenceList = new Contracts.GenericListResult <Contracts.PersonReference>();
            personReferenceList.Items = new List <Contracts.PersonReference>();

            // Load PersonReference object with the provided values
            Contracts.PersonReference personReferenceOriginal = new Contracts.PersonReference();
            personReferenceOriginal.BirthDate    = birthdate.Trim();
            personReferenceOriginal.Campus       = campus.Trim();
            personReferenceOriginal.City         = city.Trim();
            personReferenceOriginal.Emails       = new Contracts.GenericListResult <Contracts.EmailReference>();
            personReferenceOriginal.Emails.Items = new List <Contracts.EmailReference>();
            personReferenceOriginal.Emails.Items.Add(new Contracts.EmailReference(1, email.Trim(), "True", "1"));
            personReferenceOriginal.FirstName          = firstname.Trim();
            personReferenceOriginal.LastName           = lastname.Trim();
            personReferenceOriginal.Gender             = gender.Trim();
            personReferenceOriginal.MaritalStatus      = maritalstatus.Trim();
            personReferenceOriginal.NickName           = firstname.Trim();
            personReferenceOriginal.PhoneNumbers       = new Contracts.GenericListResult <Contracts.PhoneReference>();
            personReferenceOriginal.PhoneNumbers.Items = new List <Contracts.PhoneReference>();
            // Phone numbers are optional
            if (!String.IsNullOrEmpty(phonehome))
            {
                personReferenceOriginal.PhoneNumbers.Items.Add(new Contracts.PhoneReference(PersonPhone.FormatPhone(phonehome.Trim()), "", "main/home"));
            }
            if (!String.IsNullOrEmpty(phonecell))
            {
                personReferenceOriginal.PhoneNumbers.Items.Add(new Contracts.PhoneReference(PersonPhone.FormatPhone(phonecell.Trim()), "", "cell"));
            }
            personReferenceOriginal.PostalCode = postalcode.Trim();
            personReferenceOriginal.State      = state.Trim();
            personReferenceOriginal.Street1    = street1.Trim();
            personReferenceOriginal.Street2    = street2.Trim();

            // What is the minimum matching percent of a person that we will return from the function
            int matchPercentMinimum = String.IsNullOrEmpty(matchpercentminimum) ? 0 : Convert.ToInt32(matchpercentminimum);

            //  Let's determine the provided gender or stop
            int genderId = -1;

            switch (gender.ToLower())
            {
            case "male":
                genderId = 0;
                break;

            case "female":
                genderId = 1;
                break;
            }

            if (genderId == -1)
            {
                throw new Exception("Please specify a valid gender.");
            }

            // Let's use the first 2 characters in order to limit results and do more auto-matching
            string firstNameInitial = (firstname.Length > 1 ? firstname.Substring(0, 2) : firstname.Substring(0, 1));

            // Get persons by first initial, last name, gender and birthdate
            CorePersonService  cps     = new CorePersonService();
            List <core_person> persons = cps.GetList(firstNameInitial, lastname, false);

            PersonCollection pc;
            List <Person>    personList = new List <Person>();

            // Get persons with this e-mail address
            pc = new PersonCollection();
            pc.LoadByEmail(email);
            personList.AddRange((from pcbe in pc
                                 select pcbe).ToList());

            // Get persons with this phone number
            if (!String.IsNullOrEmpty(phonehome))
            {
                phonehome = PersonPhone.FormatPhone(phonehome);
                pc        = new PersonCollection();
                pc.LoadByPhone(phonehome);
                personList.AddRange((from pcbe in pc
                                     select pcbe).ToList());
            }
            if (!String.IsNullOrEmpty(phonecell))
            {
                phonecell = PersonPhone.FormatPhone(phonecell);
                pc        = new PersonCollection();
                pc.LoadByPhone(phonecell);
                personList.AddRange((from pcbe in pc
                                     select pcbe).ToList());
            }

            // Get persons with this address and first initial
            Address            address       = new Address(street1, street2, city, state, postalcode);
            CoreAddressService cas           = new CoreAddressService();
            List <int>         addressIdList = cas.GetList(address.StreetLine1, address.StreetLine2, address.PostalCode);
            Person             person        = new Person();

            // TODO: enhance Arena with LoadByAddressIDs function to improve performance
            foreach (int addressId in addressIdList)
            {
                PersonAddressCollection pac = new PersonAddressCollection();
                pac.LoadByAddressID(addressId);

                foreach (PersonAddress pa in pac)
                {
                    person = new Person(pa.PersonID);
                    if ((person.FirstName.ToLower().StartsWith(firstNameInitial.ToLower()) || person.NickName.ToLower().StartsWith(firstNameInitial.ToLower())))
                    {
                        personList.Add(person);
                    }
                }
            }

            // Remove duplicates
            personList = (from p in personList select p).Distinct().ToList();

            // Load persons over the Match Percent Minimum threshold
            List <int> personIdList = new List <int>();

            Contracts.PersonReference personReference = new Contracts.PersonReference();
            string mapMatch = String.Empty;
            int    counter  = 0;

            foreach (Person p in personList)
            {
                if ((from prl in personIdList where prl == p.PersonID select prl).Count() == 0)
                {
                    counter++;
                    personReference = ConvertPersonToPersonReference(p);
                    personReference.MatchPercent = CalculateMatchPercent(personReferenceOriginal, personReference, out mapMatch);
                    personReference.MatchMap     = mapMatch;
                    personReference.IsExact      = "false";
                    // If Person is greater than Match Percent Minimum then check for exact match and add to
                    if (Convert.ToInt32(personReference.MatchPercent) >= matchPercentMinimum)
                    {
                        string domain = String.Empty;
                        personReference.IsExact = IsPersonQualifiedForExact(p, (personReference.MaritalStatus == personReferenceOriginal.MaritalStatus ? true : false), birthdate, email, firstname, lastname, gender, street1, street2, city, state, postalcode, phonehome, phonecell, out domain).ToString();
                        personReference.IsExactPrimaryEmailDomain = domain;
                        personReferenceList.Items.Add(personReference);
                        personIdList.Add(personReference.PersonId);
                    }
                }
            }

            foreach (core_person cp in persons)
            {
                if ((from prl in personIdList where prl == cp.person_id select prl).Count() == 0)
                {
                    counter++;
                    person                       = new Person(cp.person_id);
                    personReference              = ConvertPersonToPersonReference(person);
                    personReference.IsExact      = "false";
                    personReference.MatchPercent = CalculateMatchPercent(personReferenceOriginal, personReference, out mapMatch);
                    personReference.MatchMap     = mapMatch;
                    // If Person is greater than Match Percent Minimum then check for exact match
                    if (Convert.ToInt32(personReference.MatchPercent) >= matchPercentMinimum)
                    {
                        string domain = String.Empty;
                        personReference.IsExact = IsPersonQualifiedForExact(person, (personReference.MaritalStatus == personReferenceOriginal.MaritalStatus ? true : false), birthdate, email, firstname, lastname, gender, street1, street2, city, state, postalcode, phonehome, phonecell, out domain).ToString();
                        personReference.IsExactPrimaryEmailDomain = domain;
                        personReferenceList.Items.Add(personReference);
                        personIdList.Add(personReference.PersonId);
                    }
                }
            }

            // Order filtered persons by Match Percent
            Contracts.GenericListResult <Contracts.PersonReference> personsSorted = new Contracts.GenericListResult <Contracts.PersonReference>();
            personsSorted.Items = new List <Contracts.PersonReference>();
            personsSorted.Items = (from prl in personReferenceList.Items orderby Convert.ToInt32(prl.MatchPercent) descending select prl).ToList();

            personsSorted.Max   = counter;
            personsSorted.Total = personReferenceList.Items.Count();

            return(personsSorted);
        }
        public Contracts.GenericListResult<Contracts.PersonReference> GetPersonMatch(string email, string firstname, string lastname, string gender, string maritalstatus, string campus, string street1, string street2, string city, string state, string postalcode, string phonehome, string phonecell, string birthdate, string matchpercentminimum, string sessionid)
        {
            Contracts.GenericListResult<Contracts.PersonReference> personReferenceList = new Contracts.GenericListResult<Contracts.PersonReference>();
            personReferenceList.Items = new List<Contracts.PersonReference>();

            // Load PersonReference object with the provided values
            Contracts.PersonReference personReferenceOriginal = new Contracts.PersonReference();
            personReferenceOriginal.BirthDate = birthdate.Trim();
            personReferenceOriginal.Campus = campus.Trim();
            personReferenceOriginal.City = city.Trim();
            personReferenceOriginal.Emails = new Contracts.GenericListResult<Contracts.EmailReference>();
            personReferenceOriginal.Emails.Items = new List<Contracts.EmailReference>();
            personReferenceOriginal.Emails.Items.Add(new Contracts.EmailReference(1, email.Trim(), "True", "1"));
            personReferenceOriginal.FirstName = firstname.Trim();
            personReferenceOriginal.LastName = lastname.Trim();
            personReferenceOriginal.Gender = gender.Trim();
            personReferenceOriginal.MaritalStatus = maritalstatus.Trim();
            personReferenceOriginal.NickName = firstname.Trim();
            personReferenceOriginal.PhoneNumbers = new Contracts.GenericListResult<Contracts.PhoneReference>();
            personReferenceOriginal.PhoneNumbers.Items = new List<Contracts.PhoneReference>();
            // Phone numbers are optional
            if (!String.IsNullOrEmpty(phonehome))
            {
                personReferenceOriginal.PhoneNumbers.Items.Add(new Contracts.PhoneReference(PersonPhone.FormatPhone(phonehome.Trim()), "", "main/home"));
            }
            if (!String.IsNullOrEmpty(phonecell))
            {
                personReferenceOriginal.PhoneNumbers.Items.Add(new Contracts.PhoneReference(PersonPhone.FormatPhone(phonecell.Trim()), "", "cell"));
            }
            personReferenceOriginal.PostalCode = postalcode.Trim();
            personReferenceOriginal.State = state.Trim();
            personReferenceOriginal.Street1 = street1.Trim();
            personReferenceOriginal.Street2 = street2.Trim();

            // What is the minimum matching percent of a person that we will return from the function
            int matchPercentMinimum = String.IsNullOrEmpty(matchpercentminimum) ? 0 : Convert.ToInt32(matchpercentminimum);

            //  Let's determine the provided gender or stop
            int genderId = -1;
            switch (gender.ToLower())
            {
                case "male":
                    genderId = 0;
                    break;
                case "female":
                    genderId = 1;
                    break;
            }

            if (genderId == -1)
            {
                throw new Exception("Please specify a valid gender.");
            }

            // Let's use the first 2 characters in order to limit results and do more auto-matching
            string firstNameInitial = (firstname.Length > 1 ? firstname.Substring(0, 2) : firstname.Substring(0, 1));

            // Get persons by first initial, last name, gender and birthdate
            CorePersonService cps = new CorePersonService();
            List<core_person> persons = cps.GetList(firstNameInitial, lastname, false);

            PersonCollection pc;
            List<Person> personList = new List<Person>();

            // Get persons with this e-mail address
            pc = new PersonCollection();
            pc.LoadByEmail(email);
            personList.AddRange((from pcbe in pc
                                 select pcbe).ToList());

            // Get persons with this phone number
            if (!String.IsNullOrEmpty(phonehome))
            {
                phonehome = PersonPhone.FormatPhone(phonehome);
                pc = new PersonCollection();
                pc.LoadByPhone(phonehome);
                personList.AddRange((from pcbe in pc
                                     select pcbe).ToList());
            }
            if (!String.IsNullOrEmpty(phonecell))
            {
                phonecell = PersonPhone.FormatPhone(phonecell);
                pc = new PersonCollection();
                pc.LoadByPhone(phonecell);
                personList.AddRange((from pcbe in pc
                                     select pcbe).ToList());
            }

            // Get persons with this address and first initial
            Address address = new Address(street1, street2, city, state, postalcode);
            CoreAddressService cas = new CoreAddressService();
            List<int> addressIdList = cas.GetList(address.StreetLine1, address.StreetLine2, address.PostalCode);
            Person person = new Person();

            // TODO: enhance Arena with LoadByAddressIDs function to improve performance
            foreach (int addressId in addressIdList)
            {
                PersonAddressCollection pac = new PersonAddressCollection();
                pac.LoadByAddressID(addressId);

                foreach (PersonAddress pa in pac)
                {
                    person = new Person(pa.PersonID);
                    if ((person.FirstName.ToLower().StartsWith(firstNameInitial.ToLower()) || person.NickName.ToLower().StartsWith(firstNameInitial.ToLower())))
                    {
                        personList.Add(person);
                    }
                }
            }

            // Remove duplicates
            personList = (from p in personList select p).Distinct().ToList();

            // Load persons over the Match Percent Minimum threshold
            List<int> personIdList = new List<int>();
            Contracts.PersonReference personReference = new Contracts.PersonReference();
            string mapMatch = String.Empty;
            int counter = 0;

            foreach (Person p in personList)
            {
                if ((from prl in personIdList where prl == p.PersonID select prl).Count() == 0)
                {
                    counter++;
                    personReference = ConvertPersonToPersonReference(p);
                    personReference.MatchPercent = CalculateMatchPercent(personReferenceOriginal, personReference, out mapMatch);
                    personReference.MatchMap = mapMatch;
                    personReference.IsExact = "false";
                    // If Person is greater than Match Percent Minimum then check for exact match and add to
                    if (Convert.ToInt32(personReference.MatchPercent) >= matchPercentMinimum)
                    {
                        string domain = String.Empty;
                        personReference.IsExact = IsPersonQualifiedForExact(p, (personReference.MaritalStatus == personReferenceOriginal.MaritalStatus ? true : false), birthdate, email, firstname, lastname, gender, street1, street2, city, state, postalcode, phonehome, phonecell, out domain).ToString();
                        personReference.IsExactPrimaryEmailDomain = domain;
                        personReferenceList.Items.Add(personReference);
                        personIdList.Add(personReference.PersonId);
                    }
                }
            }

            foreach (core_person cp in persons)
            {
                if ((from prl in personIdList where prl == cp.person_id select prl).Count() == 0)
                {
                    counter++;
                    person = new Person(cp.person_id);
                    personReference = ConvertPersonToPersonReference(person);
                    personReference.IsExact = "false";
                    personReference.MatchPercent = CalculateMatchPercent(personReferenceOriginal, personReference, out mapMatch);
                    personReference.MatchMap = mapMatch;
                    // If Person is greater than Match Percent Minimum then check for exact match
                    if (Convert.ToInt32(personReference.MatchPercent) >= matchPercentMinimum)
                    {
                        string domain = String.Empty;
                        personReference.IsExact = IsPersonQualifiedForExact(person, (personReference.MaritalStatus == personReferenceOriginal.MaritalStatus ? true : false), birthdate, email, firstname, lastname, gender, street1, street2, city, state, postalcode, phonehome, phonecell, out domain).ToString();
                        personReference.IsExactPrimaryEmailDomain = domain;
                        personReferenceList.Items.Add(personReference);
                        personIdList.Add(personReference.PersonId);
                    }
                }
            }

            // Order filtered persons by Match Percent
            Contracts.GenericListResult<Contracts.PersonReference> personsSorted = new Contracts.GenericListResult<Contracts.PersonReference>();
            personsSorted.Items = new List<Contracts.PersonReference>();
            personsSorted.Items = (from prl in personReferenceList.Items orderby Convert.ToInt32(prl.MatchPercent) descending select prl).ToList();

            personsSorted.Max = counter;
            personsSorted.Total = personReferenceList.Items.Count();

            return personsSorted;
        }
        protected void Page_Load(object sender, EventArgs e)
        {
            String smsSid = Request.Form["SmsSid"].ToString();
            String status = Request.Form["SmsStatus"].ToString().ToLower();
            SmsHistory history;

            //
            // Check if this is a received message.
            //
            if (status == "received")
            {
                OrganizationData orgData = new OrganizationData();
                LookupCollection validNumbers = new LookupCollection(new Guid("11B4ADEC-CB8C-4D01-B99E-7A0FFE2007B5"));
                LookupCollection twilioHandlers = new LookupCollection(new Guid("FC1BA7E8-C22A-48CF-8A30-5DF640049373"));
                String body = Request.Form["Body"].ToString();
                String from = Request.Form["From"].ToString();
                String to = Request.Form["To"].ToString();
                String baseUrl;
                StringBuilder sb = new StringBuilder();
                List<String> possiblyFrom = new List<String>();
                Boolean handled = false;
                PersonCollection col = new PersonCollection();
                Lookup lkTo = null;

                //
                // Look for the twilio phone number, if not found ignore the incoming message.
                //
                to = TwilioSMS.CleanPhone(to);
                foreach (Lookup lk in validNumbers)
                {
                    if (lk.Active && to == TwilioSMS.CleanPhone(lk.Qualifier))
                    {
                        lkTo = lk;
                        break;
                    }
                }
                if (lkTo == null)
                    return;

                //
                // Load all person records that match the phone number.
                //
                from = TwilioSMS.CleanPhone(from);
                if (from.StartsWith("1"))
                    col.LoadByPhone(from.Substring(1));
                else
                    col.LoadByPhone(from);

                //
                // Build a list of ID numbers for the person IDs that this could be from.
                //
                foreach (Person p in col)
                {
                    possiblyFrom.Add(p.PersonID.ToString());
                }

                //
                // See if we can find a stored procedure that wants to handle this message.
                //
                try
                {
                    foreach (Lookup handler in twilioHandlers)
                    {
                        ArrayList parms = new ArrayList();
                        SqlParameter outStatus = new SqlParameter("@OutStatus", SqlDbType.Int);
                        SqlParameter outMessage = new SqlParameter("@OutMessage", SqlDbType.VarChar, 2000);

                        if (handler.Active == false)
                            continue;

                        //
                        // Check if this handler is for us.
                        //
                        if (Convert.ToInt32(handler.Qualifier) != lkTo.LookupID && lkTo.LookupID != -1)
                            continue;

                        //
                        // Check if there is a match on the regular expression.
                        //
                        if (!Regex.IsMatch(body, handler.Qualifier2, RegexOptions.IgnoreCase))
                            continue;

                        outStatus.Direction = ParameterDirection.Output;
                        outMessage.Direction = ParameterDirection.Output;
                        parms.Add(new SqlParameter("@FromNumber", from));
                        parms.Add(new SqlParameter("@PossiblyFrom", String.Join(",", possiblyFrom.ToArray())));
                        parms.Add(new SqlParameter("@ToNumber", to));
                        parms.Add(new SqlParameter("@ToNumberID", lkTo.LookupID));
                        parms.Add(new SqlParameter("@Message", body));
                        parms.Add(outStatus);
                        parms.Add(outMessage);

                        orgData.ExecuteNonQuery(handler.Qualifier3, parms);

                        //
                        // See if a response should be sent.
                        //
                        if ((int)outStatus.Value == 1)
                        {
                            if (!String.IsNullOrEmpty((String)outMessage.Value))
                            {
                                int len = outMessage.Value.ToString().Length;

                                if (len > 160)
                                    len = 160;
                                Response.Clear();
                                Response.ContentType = "text/plain";
                                Response.Write(outMessage.Value.ToString().Substring(0, len));

                                //
                                // Set the base url.
                                //
                                baseUrl = ArenaContext.Current.AppSettings["ApplicationURLPath"];
                                if (!baseUrl.EndsWith("/"))
                                    baseUrl = baseUrl + "/";
                                baseUrl = String.Format("{0}default.aspx?page={1}", baseUrl, personDetailPageId);

                                //
                                // If there is a valid e-mail address to forward the text to then build up an e-mail
                                // message and send an e-mail.
                                //
                                if (!String.IsNullOrEmpty(handler.Qualifier4))
                                {
                                    try
                                    {
                                        sb.AppendFormat("<p>Received a text message from {0} to {1} ({2})</p>", from, to, lkTo.Value);
                                        sb.AppendFormat("<p>Message: {0}</p>", body);

                                        if (col.Count > 0)
                                        {
                                            sb.Append("<p>Possibly received from:<br /><ul>");
                                            foreach (Person p in col)
                                            {
                                                sb.AppendFormat("<li><a href=\"{0}&guid={1}\">{2}</a></li>", baseUrl, p.PersonGUID.ToString(), Server.HtmlEncode(p.FullName));
                                            }
                                            sb.Append("</ul></p>");
                                        }

                                        ArenaSendMail.SendMail(String.Empty, String.Empty, handler.Qualifier4, "Received SMS message", sb.ToString());
                                    }
                                    catch (System.Exception ex)
                                    {
                                        try
                                        {
                                            new Arena.DataLayer.Core.ExceptionHistoryData().AddUpdate_Exception(ex,
                                                ArenaContext.Current.Organization.OrganizationID,
                                                "HDC.Twilio", ArenaContext.Current.ServerUrl);
                                        }
                                        catch { }
                                    }
                                }

                                Response.End();
                            }

                            handled = true;
                            break;
                        }
                    }
                }
                catch (System.Exception ex)
                {
                    if (ex.Message != "Thread was being aborted.")
                    {
                        new Arena.DataLayer.Core.ExceptionHistoryData().AddUpdate_Exception(ex,
                            ArenaContext.Current.Organization.OrganizationID,
                            "HDC.Twilio", ArenaContext.Current.ServerUrl);
                    }
                }

                //
                // If the message has already been handled, we don't need to send any replies or
                // e-mail anybody.
                //
                if (!handled)
                {
                    //
                    // Set the base url.
                    //
                    baseUrl = ArenaContext.Current.AppSettings["ApplicationURLPath"];
                    if (!baseUrl.EndsWith("/"))
                        baseUrl = baseUrl + "/";
                    baseUrl = String.Format("{0}default.aspx?page={1}", baseUrl, personDetailPageId);

                    //
                    // If there is a valid e-mail address to forward the text to then build up an e-mail
                    // message and send an e-mail.
                    //
                    if (!String.IsNullOrEmpty(lkTo.Qualifier2))
                    {
                        try
                        {
                            sb.AppendFormat("<p>Received a text message from {0} to {1} ({2})</p>", from, to, lkTo.Value);
                            sb.AppendFormat("<p>Message: {0}</p>", body);

                            if (col.Count > 0)
                            {
                                sb.Append("<p>Possibly received from:<br /><ul>");
                                foreach (Person p in col)
                                {
                                    sb.AppendFormat("<li><a href=\"{0}&guid={1}\">{2}</a></li>", baseUrl, p.PersonGUID.ToString(), Server.HtmlEncode(p.FullName));
                                }
                                sb.Append("</ul></p>");
                            }

                            ArenaSendMail.SendMail(String.Empty, String.Empty, lkTo.Qualifier2, "Received SMS message", sb.ToString());
                        }
                        catch (System.Exception ex)
                        {
                            try
                            {
                                new Arena.DataLayer.Core.ExceptionHistoryData().AddUpdate_Exception(ex,
                                    ArenaContext.Current.Organization.OrganizationID,
                                    "HDC.Twilio", ArenaContext.Current.ServerUrl);
                            }
                            catch { }
                        }
                    }

                    //
                    // If there is an auto-reply message in the lookup then send back that message.
                    //
                    if (!String.IsNullOrEmpty(lkTo.Qualifier8))
                    {
                        try
                        {
                            int len = lkTo.Qualifier8.Length;

                            if (len > 160)
                                len = 160;
                            Response.Clear();
                            Response.ContentType = "text/plain";
                            Response.Write(lkTo.Qualifier8.Substring(0, len));
                            Response.End();
                        }
                        catch (System.Exception ex)
                        {
                            try
                            {
                                if (ex.Message != "Thread was being aborted.")
                                {
                                    new Arena.DataLayer.Core.ExceptionHistoryData().AddUpdate_Exception(ex,
                                        ArenaContext.Current.Organization.OrganizationID,
                                        "HDC.Twilio", ArenaContext.Current.ServerUrl);
                                }
                            }
                            catch { }
                        }
                    }
                }
            }
            else
            {
                //
                // This (should be) a status response to an outgoing message.
                //
                history = new SmsHistory(smsSid);
                if (history.SmsHistoryId != -1)
                {
                    try
                    {
                        if (status == "sent")
                        {
                            new PersonCommunicationData().SavePersonCommunication(history.CommunicationId, history.PersonId, DateTime.Now, "Success");
                        }
                        else
                        {
                            new PersonCommunicationData().SavePersonCommunication(history.CommunicationId, history.PersonId, DateTime.Now, "Failed");
                        }
                    }
                    catch (System.Exception)
                    {
                    }

                    history.Delete();
                }
            }
        }