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"); }
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"); }
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()); }