public async Task <ActionResult> IVRConfig_Partial(Model model) { if (model.GenerateKeys) { string publicKey, privateKey; RSACrypto.MakeNewKeys(out publicKey, out privateKey); model.PrivateKey = privateKey; model.PublicKey = publicKey; model.GenerateKeys = false; } using (IVRConfigDataProvider configDP = new IVRConfigDataProvider()) { IVRConfig config = await configDP.GetItemAsync();// get the original item model.UpdateData(config); if (!ModelState.IsValid) { return(PartialView(model)); } config = model.GetData(config); // merge new data into original model.SetData(config); // and all the data back into model for final display await configDP.UpdateConfigAsync(config); using (ScriptDataProvider scriptDP = new ScriptDataProvider()) { scriptDP.ClearScript(); } return(FormProcessed(model, this.__ResStr("okSaved", "IVR settings saved"), NextPage: Manager.ReturnToUrl)); } }
public async Task <ActionResult> IVRConfig() { using (IVRConfigDataProvider dataProvider = new IVRConfigDataProvider()) { Model model = new Model { }; IVRConfig data = await dataProvider.GetItemAsync(); if (data == null) { throw new Error(this.__ResStr("notFound", "The IVR settings could not be found")); } model.SetData(data); model.UpdateData(data); return(View(model)); } }
public async Task <ModuleAction> GetAction_DisplayAsync(string url, int id) { if (url == null) { IVRConfig config = await IVRConfigDataProvider.GetConfigAsync(); url = config.DisplayVoiceMailUrl; } return(new ModuleAction(this) { Url = string.IsNullOrWhiteSpace(url) ? ModulePermanentUrl : url, QueryArgs = new { Id = id }, Image = "#Display", LinkText = this.__ResStr("displayLink", "Display"), MenuText = this.__ResStr("displayText", "Display"), Tooltip = this.__ResStr("displayTooltip", "Display the voice mail entry"), Legend = this.__ResStr("displayLegend", "Displays an existing voice mail entry"), Style = ModuleAction.ActionStyleEnum.Popup, Category = ModuleAction.ActionCategoryEnum.Read, Mode = ModuleAction.ActionModeEnum.Any, Location = ModuleAction.ActionLocationEnum.NoAuto, SaveReturnUrl = true, }); }
public async Task <ActionResult> Process(string request, string extension, int errCount, string token) { LogCall(request, extension); TwilioData twilioConfig = await TwilioConfigDataProvider.GetConfigCondAsync(); if (twilioConfig == null || !twilioConfig.IsConfigured()) { return(RejectResult("Twilio is not configured")); } string authToken = twilioConfig.TestMode ? twilioConfig.TestAuthToken : twilioConfig.LiveAuthToken; IVRConfig ivrConfig = await IVRConfigDataProvider.GetConfigCondAsync(); if (ivrConfig == null || string.IsNullOrWhiteSpace(ivrConfig.PublicKey) || string.IsNullOrWhiteSpace(ivrConfig.PrivateKey)) { return(RejectResult("Config settings not available")); } #if !DEBUG // There is something very peculiar about twilio verification. The initial request will validate correctly, but anything after that will not. // Even if the only difference is CallStatus (tested with a redirect to Request=Main. So I gave up and validate just the first one // and add my own token validation (as argument) if (string.IsNullOrWhiteSpace(token)) { if (!Verify.VerifyTwilio(authToken, twilioConfig.TestMode ? ivrConfig.TestVerificationProcessCallUrl : ivrConfig.LiveVerificationProcessCallUrl)) { return(RejectResult("Twilio verification failed")); } } else { // verify token. If it wasn't generated within the last 5 minutes, reject it. string decryptedToken; RSACrypto.Decrypt(ivrConfig.PrivateKey, token, out decryptedToken); DateTime tokenTime = new DateTime(Convert.ToInt64(decryptedToken)); if (tokenTime < DateTime.UtcNow.AddMinutes(-5)) { return(RejectResult("Token verification failed")); } } #endif if (string.IsNullOrWhiteSpace(request)) { // call log using (CallLogDataProvider callLogDP = new CallLogDataProvider()) { await callLogDP.AddItemAsync(new CallLogEntry { Caller = GetForm("From")?.Truncate(Globals.MaxPhoneNumber), CallerCity = GetForm("CallerCity")?.Truncate(CallLogEntry.MaxCity), CallerCountry = GetForm("CallerCountry")?.Truncate(CallLogEntry.MaxCountry), CallerState = GetForm("CallerState")?.Truncate(CallLogEntry.MaxState), CallerZip = GetForm("CallerZip")?.Truncate(CallLogEntry.MaxZip), To = GetForm("Called")?.Truncate(Globals.MaxPhoneNumber), }); } // check for blocked numbers using (BlockedNumberDataProvider blockedDP = new BlockedNumberDataProvider()) { BlockedNumberEntry blockedEntry = await blockedDP.GetItemAsync(GetForm("From")); if (blockedEntry != null) { return(RejectResult($"Blocked number {GetForm("From")}")); } } // notify (new call) foreach (ExtensionPhoneNumber notifyNumber in ivrConfig.NotificationNumbers) { if (notifyNumber.SendSMS) { SendSMS sendSMS = new SendSMS(); await sendSMS.SendMessageAsync(notifyNumber.PhoneNumber, this.__ResStr("notifySMS", "Incoming call received from {0} ({1}, {2}, {3}, {4}) - {5}", GetForm("Caller"), GetForm("CallerCity"), GetForm("CallerState"), GetForm("CallerZip"), GetForm("CallerCountry"), GetForm("To")), ThrowError : false); } } // determine main action to run request = SECTION_MAIN; using (HolidayEntryDataProvider holidayDP = new HolidayEntryDataProvider()) { HolidayEntry holiday = await holidayDP.GetItemAsync(DateTime.Now.Date.ToUniversalTime()); if (holiday != null) { request = SECTION_MAINHOLIDAY; } else if (ivrConfig.OpeningHours.IsClosed(DateTime.UtcNow)) { request = SECTION_MAINCLOSED; } } } string called; if (!TryGetForm("CalledVia", out called)) { called = GetForm("Called"); } if (ivrConfig.MaxErrors != 0 && errCount >= ivrConfig.MaxErrors) { request = SECTION_MAINGOODBYE; } request = request.ToLower(); using (ScriptDataProvider scriptDP = new ScriptDataProvider()) { ScriptData script = await scriptDP.GetScriptAsync(called); if (script == null) { return(RejectResult($"Script not found for {called}")); } // See if a valid extension was entered if (request == SECTION_GATHEREXTENSION.ToLower()) { string digits; if (TryGetForm("Digits", out digits)) { Extension ext = script.FindExtension(digits); if (ext != null) { extension = ext.Digits; request = SECTION_ENTEREDEXTENSION.ToLower(); // a valid extension was entered, run EnteredExtension instead } } } // find the entry that matches the name and parameters List <ScriptEntry> entries = (from e in script.Scripts where e.Tag == request select e).ToList(); foreach (ScriptEntry entry in entries) { if (entry.Parms.Count > 0) { // check parms bool valid = true; foreach (ScriptParm parm in entry.Parms) { if (GetForm(parm.Name) != parm.Value) { valid = false; break; } } if (!valid) { continue; } } return(await RunEntryAsync(ivrConfig, script, called, extension, entry, errCount)); } throw new InternalError($"Nothing to execute - tag \"{request}\" for {called}"); } }