public async Task SetupClient() { if (!Initialized) { TwilioData config = await TwilioConfigDataProvider.GetConfigAsync(); if (!config.IsConfigured()) { throw new Error(this.__ResStr("notConfigured", "Twilio is not configured.")); } string acctSid = null, acctToken = null; if (config.TestMode) { acctSid = config.TestAccountSid; acctToken = config.TestAuthToken; } else { acctSid = config.LiveAccountSid; acctToken = config.LiveAuthToken; } TwilioClient.Init(acctSid, acctToken); Initialized = true; } }
public void Post([FromBody] TwilioData data) { var body = data.Body; if (string.IsNullOrEmpty(body)) { return; } body = body.ToLower(); if (!body.Contains("play")) { return; } body = body .Replace("play", "") .ToLower() .Trim(); var videoKey = ConfigurationManager.AppSettings[body]; if (string.IsNullOrEmpty(videoKey)) { return; } //TODO: Figure out the correct way to do this logic var temp = char.ToUpper(body[0]); var array = body.ToCharArray(); array[0] = temp; Clients.All.deliverMessage(data.From, new { Title = new string(array), Key = videoKey }); }
public void UpdateData(TwilioData data) { LiveAccountSid = data.LiveAccountSid; LiveAuthToken = data.LiveAuthToken; TestAccountSid = data.TestAccountSid; TestAuthToken = data.TestAuthToken; }
/// <summary> /// Returns whether the SMS provider is in test mode. /// </summary> /// <returns>True if it is in test mode, false otherwise.</returns> public async Task <bool> IsTestModeAsync() { if (!await IsAvailableAsync()) { throw new InternalError("SMS processing not available"); } TwilioData config = await TwilioConfigDataProvider.GetConfigAsync(); return(config.TestMode); }
public async Task SendSMSAsync(string toNumber, string text, string FromNumber) { TwilioData config = await TwilioConfigDataProvider.GetConfigAsync(); string accountSid = config.TestMode ? config.TestAccountSid : config.LiveAccountSid; string authToken = config.TestMode ? config.TestAuthToken : config.LiveAuthToken; string fromNumber = config.TestMode ? config.TestSMSNumber : config.LiveSMSNumber; if (!string.IsNullOrWhiteSpace(FromNumber)) { fromNumber = FromNumber; } fromNumber = PhoneNumberNationalAttribute.GetE164(fromNumber); if (fromNumber == null) { throw new InternalError($"Invalid fromNumber {fromNumber} - {nameof(SendSMSAsync)}"); } toNumber = PhoneNumberNationalAttribute.GetE164(toNumber); if (toNumber == null) { throw new InternalError($"Invalid toNumber {toNumber} - {nameof(SendSMSAsync)}"); } string callbackUrl = null; if (config.DeliveryReceipts) { callbackUrl = YetaWFManager.Manager.CurrentSite.MakeUrl( Utility.UrlFor(typeof(TwilioResponseController), nameof(TwilioResponseController.Response), new { ValidateToNumber = toNumber }), PagePageSecurity: config.UseHttps?YetaWF.Core.Pages.PageDefinition.PageSecurityType.httpsOnly: YetaWF.Core.Pages.PageDefinition.PageSecurityType.httpOnly ); } TwilioClient.Init(accountSid, authToken); MessageResource m = MessageResource.Create( from: fromNumber, // From number, must be an SMS-enabled Twilio number to: toNumber, body: text, statusCallback: callbackUrl != null ? new Uri(callbackUrl) : null ); if (m.ErrorCode != null) { Logging.AddErrorLog("TwilioProcessor SendSMS failed: {0} {1} - {2} - {3}", fromNumber, toNumber, m.ErrorCode, m.ErrorMessage); } else { Logging.AddLog("TwilioProcessor SendSMS queued: {0} {1}", fromNumber, toNumber); } }
public async Task <ActionResult> TwilioConfig() { using (TwilioConfigDataProvider dataProvider = new TwilioConfigDataProvider()) { Model model = new Model { }; TwilioData data = await dataProvider.GetItemAsync(); if (data == null) { throw new Error(this.__ResStr("notFound", "The TwilioProcessor settings could not be found")); } model.SetData(data); model.UpdateData(data); return(View(model)); } }
public async Task <ActionResult> TwilioConfig_Partial(Model model) { using (TwilioConfigDataProvider configDP = new TwilioConfigDataProvider()) { TwilioData 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); return(FormProcessed(model, this.__ResStr("okSaved", "TwilioProcessor settings saved"), NextPage: Manager.ReturnToUrl)); } }
public void SetData(TwilioData data) { ObjectSupport.CopyData(data, this); }
public TwilioData GetData(TwilioData data) { ObjectSupport.CopyData(this, data); return(data); }
/// <summary> /// Returns whether the SMS provider is available. /// </summary> /// <returns>True if it is available, false otherwise.</returns> public async Task <bool> IsAvailableAsync() { TwilioData twilioConfig = await TwilioConfigDataProvider.GetConfigCondAsync(); return(twilioConfig != null && twilioConfig.IsSMSConfigured()); }
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}"); } }