Esempio n. 1
0
        public object MessageCallback(TwilioCallback data)
        {
            if (data.MessageStatus == "delivered" && TwilioProvider.HasTwilio())
            {
                Metrics.Info($"Callback: delivered message {data.MessageSid}");
                using (var db = new Email2SmsContext())
                {
                    var     twilio = TwilioProvider.GetTwilio();
                    Message msg    = null;
                    for (int i = 0; i < 10; i++)
                    {
                        msg = twilio.GetMessage(data.MessageSid);
                        Metrics.Info($"Message {data.MessageSid} price: {msg.Price}");
                        if (msg.Price < 0)
                        {
                            break;
                        }

                        Thread.Sleep(1000);
                    }
                    if (msg.Price == 0)
                    {
                        Metrics.Error($"Couldn't get price for message {data.MessageSid}");
                        throw new ApplicationException("Couldn't get price");
                    }


                    using (var scope = db.Database.BeginTransaction())
                    {
                        try
                        {
                            var dbMsg = db.InvoiceItems
                                        .Where(f => f.Sid == data.MessageSid)
                                        .Select(f => new { Msg = f, Sub = f.SendTo.Subscription }).FirstOrDefault();

                            if (dbMsg != null && !dbMsg.Msg.Price.HasValue)
                            {
                                dbMsg.Msg.Price = -msg.Price;
                                db.SaveChanges();
                                scope.Commit();
                            }
                        }
                        catch (Exception)
                        {
                            scope.Rollback();
                            throw;
                        }
                    }
                }
            }
            return("OK");
        }
Esempio n. 2
0
        public object Post(EmailMessage message)
        {
            try
            {
                using (var db = new Email2SmsContext())
                {
                    var msgLog = GetMessageLog(message);
                    db.MessageLog.Add(msgLog);
                    db.SaveChanges();

                    string plainMessage  = message.plain;
                    var    locationMatch = Regex.Match(plainMessage, "(4\\d\\.\\d+)[N ,]+[W\\- ]?(12\\d+\\.\\d+)", RegexOptions.IgnoreCase);
                    if (locationMatch.Success)
                    {
                        plainMessage += string.Format(" http://maps.google.com/?q={0},-{1}", locationMatch.Groups[1].Value, locationMatch.Groups[2].Value);
                    }

                    // A quick in-memory duplicate check backed up by a database dupe check in case we've been recycled.
                    DateTime duplicateTime = DateTime.UtcNow.AddMinutes(-5);
                    lock (cacheLock)
                    {
                        if (messageCache.Contains(plainMessage))
                        {
                            return("Duplicate");
                        }
                        else
                        {
                            messageCache.Add(plainMessage, DateTime.UtcNow, DateTimeOffset.UtcNow.AddMinutes(5));
                        }
                    }

                    if (db.InvoiceItems.Any(f => f.Message.Text == plainMessage && f.SendTime > duplicateTime))
                    {
                        return("Duplicate");
                    }

                    var list = db.Phones.Where(f => f.Active).ToList();
                    if (TwilioProvider.HasTwilio())
                    {
                        var twilioClient   = TwilioProvider.GetTwilio();
                        var twilioFroms    = TwilioProvider.GetNumbers();
                        var fromIndex      = 0;
                        var twilioCallback = ConfigurationManager.AppSettings["twilio:callback"];

                        foreach (var item in list)
                        {
                            var twilioMsg = twilioClient.SendMessage(twilioFroms[fromIndex], item.Address, plainMessage, twilioCallback);
                            fromIndex = (fromIndex + 1) % twilioFroms.Length;
                            db.InvoiceItems.Add(new InvoiceLog {
                                SendTo = item, Sid = twilioMsg.Sid, SendTime = DateTime.UtcNow, Message = msgLog
                            });
                            db.SaveChanges();
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Metrics.Exception(ex);
            }
            return("OK");
        }
Esempio n. 3
0
        public ActionResult Setup(string phones)
        {
            string[] list    = phones.Split('\n').Select(f => f.Trim()).Distinct().Where(f => !string.IsNullOrWhiteSpace(f)).ToArray();
            string   message = null;

            for (int i = 0; i < list.Length; i++)
            {
                if (list[i].Length != 10 || !Regex.IsMatch(list[i], "\\d{10}"))
                {
                    message = (message ?? "Error: ") + " Don't understand " + list[i];
                }
            }
            if (message != null)
            {
                Metrics.Info(ViewBag.Message);
                ViewBag.Message = message;
                return(Setup());
            }

            using (var db = new Email2SmsContext())
            {
                var userId = GetUserId();

                var dupes = db.Phones
                            .Where(f => f.Subscription.User != userId)
                            .Select(f => f.Address)
                            .ToArray()
                            .Intersect(list)
                            .ToArray();

                if (dupes.Length > 0)
                {
                    ViewBag.Message = "Error: Phone numbers already used by someone else: " + string.Join(", ", dupes);
                    Metrics.Info(ViewBag.Message);
                    return(Setup());
                }

                var sub = db.Subscriptions.Include(f => f.Phones).SingleOrDefault(f => f.User == userId);
                foreach (var p in list)
                {
                    var match = sub.Phones.FirstOrDefault(f => f.Address == p);
                    if (match == null)
                    {
                        if (TwilioProvider.HasTwilio())
                        {
                            var client = TwilioProvider.GetTwilio();

                            Metrics.Info($"Sending welcome text to {p}");
                            client.SendMessage(TwilioProvider.GetNumbers().First(), p, "This number will now receive SAR pages. [email protected]");
                        }
                        sub.Phones.Add(new Phone {
                            Active = true, Address = p, Subscription = sub
                        });
                    }
                    else if (match.Active == false)
                    {
                        Metrics.Info($"Marking {p} as active");
                        match.Active = true;
                    }
                }

                foreach (var p in sub.Phones.ToArray())
                {
                    var match = list.FirstOrDefault(f => f == p.Address);
                    if (match == null)
                    {
                        if (db.InvoiceItems.Any(f => f.PhoneId == p.Id))
                        {
                            Metrics.Info($"Marking phone {p.Address} inactive");
                            p.Active = false;
                        }
                        else
                        {
                            Metrics.Info($"Removing unused phone {match}");
                            sub.Phones.Remove(p);
                            db.Phones.Remove(p);
                        }
                    }
                    else
                    {
                        // Already marked active in above loop
                    }
                }
                db.SaveChanges();
            }

            ViewBag.Message = $"Saved {list.Count()} numbers";
            return(Setup());
        }