Exemplo n.º 1
0
        public void SendMessage(int personID, int communicationID, string toNumber, string fromNumber, string fromName, string message, string userID)
        {
            PersonCommunication pc;
            TwilioRestClient twilio = new TwilioRestClient(_username, _password);
            LookupCollection validNumbers = new LookupCollection(new Guid("11B4ADEC-CB8C-4D01-B99E-7A0FFE2007B5"));
            Message msg;
            SmsHistory history;
            String twilioNumber = null;
            String callback;

            //
            // Check if this message has already been sent. The agent seems to be broken and
            // will send each SMS message twice in rapid succession. If the communication is
            // no longer pending or queued, assume it has already been sent and silently ignore.
            //
            if (personID != -1 && communicationID != -1)
            {
                pc = new PersonCommunication(personID, communicationID);
                if (pc.CommunicationID != -1)
                {
                    if (pc.Status != "Pending" && pc.Status != "Queued")
                        return;
                }
            }

            //
            // Get the first enabled twilio number, use that as the default.
            //
            foreach (Lookup lk in validNumbers)
            {
                if (lk.Active)
                {
                    twilioNumber = CleanPhone(lk.Qualifier);
                    break;
                }
            }

            //
            // Check if the fromNumber is a valid Twilio number, if it isn't then use the default Twilio Number.
            //
            fromNumber = CleanPhone(fromNumber);
            foreach (Lookup lk in validNumbers)
            {
                string cleaned = CleanPhone(lk.Qualifier);

                if (lk.Active && fromNumber == cleaned)
                {
                    twilioNumber = cleaned;
                    break;
                }
            }

            //
            // Verify that we have our default twilio number defined.
            //
            if (String.IsNullOrEmpty(twilioNumber))
            {
                if (communicationID != -1 && personID != -1)
                    new PersonCommunicationData().SavePersonCommunication(communicationID, personID, DateTime.Now, "Failed -- Invalid from number specified", ArenaContext.Current.Organization.OrganizationID);

                return;
            }

            //
            // If we don't have a valid outgoing number, fail.
            //
            toNumber = CleanPhone(toNumber);
            if (String.IsNullOrEmpty(toNumber))
            {
                if (communicationID != -1 && personID != -1)
                    new PersonCommunicationData().SavePersonCommunication(communicationID, personID, DateTime.Now, "Failed -- No SMS number available", ArenaContext.Current.Organization.OrganizationID);

                return;
            }

            //
            // Construct the callback URL.
            //
            callback = ArenaContext.Current.AppSettings["ApplicationURLPath"];
            if (!callback.EndsWith("/"))
                callback = callback + "/";
            callback = callback + "UserControls/Custom/HDC/Twilio/SmsStatus.aspx";

            //
            // Update the person communication history to show that we have attempted to send, since this is an
            // asynchronous operation we don't want to chance the callback not working and the message gets
            // sent over and over again.
            //
            if (communicationID != -1 && personID != -1)
            {
                new PersonCommunicationData().SavePersonCommunication(communicationID, personID, DateTime.Now, "Pushed", ArenaContext.Current.Organization.OrganizationID);
            }

            //
            // Verify that the twilio object exists.
            //
            if (twilio == null)
            {
                new PersonCommunicationData().SavePersonCommunication(communicationID, personID, DateTime.Now, "Failed -- Could not initialize Twilio library.", ArenaContext.Current.Organization.OrganizationID);

                return;
            }

            //
            // Send the message.
            //
            msg = twilio.SendMessage(twilioNumber, toNumber, message, callback);
            if (personID != -1 && communicationID != -1)
            {
                if (msg == null)
                {
                    new PersonCommunicationData().SavePersonCommunication(communicationID, personID, DateTime.Now, "Failed -- Could not contact Twilio API.", ArenaContext.Current.Organization.OrganizationID);

                    return;
                }

                if (String.IsNullOrEmpty(msg.Sid))
                {
                    if (communicationID != -1 && personID != -1)
                    {
                        String reason;

                        if (msg.RestException != null && !String.IsNullOrEmpty(msg.RestException.Message))
                            reason = String.Format("Failed -- SMS provider did not accept message ({0}).", msg.RestException.Message);
                        else if (!String.IsNullOrEmpty(msg.Status))
                            reason = String.Format("Failed -- SMS provider did not accept message ({0}).", msg.Status);
                        else
                            reason = String.Format("Failed -- SMS provider did not accept message (Unknown Error).");

                        new PersonCommunicationData().SavePersonCommunication(communicationID, personID, DateTime.Now, reason, ArenaContext.Current.Organization.OrganizationID);
                    }
                }
                else
                {
                    history = new SmsHistory();
                    history.CommunicationId = communicationID;
                    history.PersonId = personID;
                    history.SmsSid = msg.Sid;
                    history.Save(userID);
                }
            }
        }
Exemplo n.º 2
0
        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();
                }
            }
        }