├── IVRPhoneTree.Web ├── Views │ ├── IVR │ │ └── Index.cshtml │ ├── _ViewStart.cshtml │ ├── Shared │ │ ├── Error.cshtml │ │ └── _Layout.cshtml │ └── Web.config ├── favicon.ico ├── Global.asax ├── Scripts │ └── _references.js ├── App_Start │ ├── FilterConfig.cs │ ├── BundleConfig.cs │ └── RouteConfig.cs ├── Content │ └── Site.css ├── Global.asax.cs ├── libman.json ├── Controllers │ ├── ControllerBase.cs │ ├── IVRController.cs │ ├── PhoneExchangeController.cs │ └── MenuController.cs ├── Web.Debug.config ├── Web.Release.config ├── Properties │ └── AssemblyInfo.cs ├── packages.config ├── Web.config.sample ├── Web.config └── IVRPhoneTree.Web.csproj ├── .mergify.yml ├── .github ├── workflows │ └── NetFx.yml └── dependabot.yml ├── IVRPhoneTree.Web.Test ├── Extensions │ └── ControllerResultTestExtensions.cs ├── Controllers │ ├── IVRControllerTest.cs │ ├── PhoneExchangeControllerTest.cs │ └── MenuControllerTest.cs ├── Properties │ └── AssemblyInfo.cs ├── app.config ├── packages.config └── IVRPhoneTree.Web.Test.csproj ├── README.md ├── IVRPhoneTree.sln └── .gitignore /IVRPhoneTree.Web/Views/IVR/Index.cshtml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /IVRPhoneTree.Web/Views/_ViewStart.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | Layout = "~/Views/Shared/_Layout.cshtml"; 3 | } 4 | -------------------------------------------------------------------------------- /IVRPhoneTree.Web/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TwilioDevEd/ivr-phone-tree-csharp/HEAD/IVRPhoneTree.Web/favicon.ico -------------------------------------------------------------------------------- /IVRPhoneTree.Web/Global.asax: -------------------------------------------------------------------------------- 1 | <%@ Application Codebehind="Global.asax.cs" Inherits="IVRPhoneTree.Web.MvcApplication" Language="C#" %> 2 | -------------------------------------------------------------------------------- /IVRPhoneTree.Web/Scripts/_references.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TwilioDevEd/ivr-phone-tree-csharp/HEAD/IVRPhoneTree.Web/Scripts/_references.js -------------------------------------------------------------------------------- /.mergify.yml: -------------------------------------------------------------------------------- 1 | pull_request_rules: 2 | - name: automatic merge for Dependabot pull requests 3 | conditions: 4 | - author~=^dependabot(|-preview)\[bot\]$ 5 | - status-success=build 6 | actions: 7 | merge: 8 | method: squash 9 | -------------------------------------------------------------------------------- /IVRPhoneTree.Web/App_Start/FilterConfig.cs: -------------------------------------------------------------------------------- 1 | using System.Web.Mvc; 2 | 3 | namespace IVRPhoneTree.Web 4 | { 5 | public class FilterConfig 6 | { 7 | public static void RegisterGlobalFilters(GlobalFilterCollection filters) 8 | { 9 | filters.Add(new HandleErrorAttribute()); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /IVRPhoneTree.Web/Views/Shared/Error.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | Layout = null; 3 | } 4 | 5 | 6 | 7 | 8 | 9 | Error 10 | 11 | 12 |
13 |

Error.

14 |

An error occurred while processing your request.

15 |
16 | 17 | 18 | -------------------------------------------------------------------------------- /IVRPhoneTree.Web/App_Start/BundleConfig.cs: -------------------------------------------------------------------------------- 1 | using System.Web.Optimization; 2 | 3 | namespace IVRPhoneTree.Web 4 | { 5 | public class BundleConfig 6 | { 7 | // For more information on bundling, visit http://go.microsoft.com/fwlink/?LinkId=301862 8 | public static void RegisterBundles(BundleCollection bundles) 9 | { 10 | bundles.Add(new StyleBundle("~/Content/css").Include( 11 | "~/Scripts/lib/dist/css/font-awesome.css", 12 | "~/Content/Site.css")); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /IVRPhoneTree.Web/Content/Site.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; 3 | font-size: 90%; 4 | background-image: url("http://365psd.com/images/previews/cee/woman-talking-on-the-phone-25962.jpg"); 5 | background-repeat: no-repeat; 6 | background-attachment: fixed; 7 | background-position: center; 8 | } 9 | 10 | footer { 11 | position: absolute; 12 | bottom: 10px; 13 | text-align: center; 14 | width: 99% 15 | } 16 | 17 | .body-content { 18 | padding-left: 15px; 19 | padding-right: 15px; 20 | } 21 | -------------------------------------------------------------------------------- /IVRPhoneTree.Web/App_Start/RouteConfig.cs: -------------------------------------------------------------------------------- 1 | using System.Web.Mvc; 2 | using System.Web.Routing; 3 | 4 | namespace IVRPhoneTree.Web 5 | { 6 | public class RouteConfig 7 | { 8 | public static void RegisterRoutes(RouteCollection routes) 9 | { 10 | routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 11 | 12 | routes.MapRoute( 13 | "Default", 14 | "{controller}/{action}/{id}", 15 | new {controller = "IVR", action = "Index", id = UrlParameter.Optional} 16 | ); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /IVRPhoneTree.Web/Global.asax.cs: -------------------------------------------------------------------------------- 1 | using System.Web; 2 | using System.Web.Mvc; 3 | using System.Web.Optimization; 4 | using System.Web.Routing; 5 | 6 | namespace IVRPhoneTree.Web 7 | { 8 | public class MvcApplication : HttpApplication 9 | { 10 | protected void Application_Start() 11 | { 12 | AreaRegistration.RegisterAllAreas(); 13 | FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); 14 | RouteConfig.RegisterRoutes(RouteTable.Routes); 15 | BundleConfig.RegisterBundles(BundleTable.Bundles); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /IVRPhoneTree.Web/Views/Shared/_Layout.cshtml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | IVR Phone Tree 7 | @Styles.Render("~/Content/css") 8 | 9 | 10 |
11 | @RenderBody() 12 |
13 | 17 | @RenderSection("scripts", required: false) 18 | 19 | 20 | -------------------------------------------------------------------------------- /IVRPhoneTree.Web/libman.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1.0", 3 | "defaultProvider": "cdnjs", 4 | "libraries": [ 5 | { 6 | "library": "font-awesome@4.7.0", 7 | "destination": "Scripts/lib/dist/", 8 | "files": [ 9 | "css/font-awesome.min.css", 10 | "css/font-awesome.css", 11 | "css/font-awesome.css.map", 12 | "fonts/fontawesome-webfont.eot", 13 | "fonts/fontawesome-webfont.svg", 14 | "fonts/fontawesome-webfont.ttf", 15 | "fonts/fontawesome-webfont.woff", 16 | "fonts/fontawesome-webfont.woff2", 17 | "fonts/FontAwesome.otf" 18 | ] 19 | } 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /IVRPhoneTree.Web/Controllers/ControllerBase.cs: -------------------------------------------------------------------------------- 1 | using Twilio.AspNet.Mvc; 2 | using Twilio.TwiML; 3 | using Twilio.TwiML.Voice; 4 | 5 | namespace IVRPhoneTree.Web.Controllers 6 | { 7 | public abstract class ControllerBase : TwilioController 8 | { 9 | public TwiMLResult RedirectWelcome() 10 | { 11 | var response = new VoiceResponse(); 12 | response.Say("Returning to the main menu", 13 | voice: Say.VoiceEnum.PollyAmy, 14 | language: "en-GB" 15 | ); 16 | response.Redirect(Url.ActionUri("Welcome", "IVR")); 17 | 18 | return TwiML(response); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /.github/workflows/NetFx.yml: -------------------------------------------------------------------------------- 1 | name: NetFx 2 | 3 | on: 4 | push: 5 | branches: [ main ] 6 | pull_request: 7 | branches: [ main ] 8 | 9 | jobs: 10 | build: 11 | runs-on: windows-latest 12 | 13 | steps: 14 | - uses: actions/checkout@v2 15 | name: Checkout Code 16 | 17 | - name: Setup MSBuild Path 18 | uses: microsoft/setup-msbuild@v1 19 | 20 | - name: Setup NuGet 21 | uses: NuGet/setup-nuget@v1 22 | 23 | - name: Restore NuGet Packages 24 | run: nuget restore IVRPhoneTree.sln 25 | 26 | - name: Build Web App 27 | run: msbuild IVRPhoneTree.sln /verbosity:minimal 28 | 29 | - name: Run Tests with NUnit Console 30 | run: .\packages\NUnit.ConsoleRunner.3.11.1\tools\nunit3-console IVRPhoneTree.Web.Test\bin\Debug\IVRPhoneTree.Web.Test.dll 31 | -------------------------------------------------------------------------------- /IVRPhoneTree.Web/Controllers/IVRController.cs: -------------------------------------------------------------------------------- 1 | using System.Web.Mvc; 2 | using Twilio.AspNet.Mvc; 3 | using Twilio.TwiML; 4 | using Twilio.TwiML.Voice; 5 | 6 | namespace IVRPhoneTree.Web.Controllers 7 | { 8 | public class IVRController : TwilioController 9 | { 10 | // GET: IVR 11 | public ActionResult Index() 12 | { 13 | return View(); 14 | } 15 | 16 | // POST: IVR/Welcome 17 | [HttpPost] 18 | public TwiMLResult Welcome() 19 | { 20 | var response = new VoiceResponse(); 21 | var gather = new Gather(action: Url.ActionUri("Show", "Menu"), numDigits: 1); 22 | gather.Say("Thank you for calling the E.T. Phone Home Service - the " + 23 | "adventurous alien's first choice in intergalactic travel. " + 24 | "Press 1 for directions, press 2 to make a call."); 25 | response.Append(gather); 26 | 27 | return TwiML(response); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /IVRPhoneTree.Web/Controllers/PhoneExchangeController.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Web.Mvc; 3 | using Twilio.AspNet.Mvc; 4 | using Twilio.TwiML; 5 | 6 | namespace IVRPhoneTree.Web.Controllers 7 | { 8 | public class PhoneExchangeController : ControllerBase 9 | { 10 | // POST: PhoneExchange/Interconnect 11 | [HttpPost] 12 | public ActionResult Interconnect(string digits) 13 | { 14 | var userOption = digits; 15 | var optionPhones = new Dictionary 16 | { 17 | {"2", "+19295566487"}, 18 | {"3", "+17262043675"}, 19 | {"4", "+16513582243"} 20 | }; 21 | 22 | return optionPhones.ContainsKey(userOption) 23 | ? Dial(optionPhones[userOption]) : RedirectWelcome(); 24 | } 25 | 26 | private TwiMLResult Dial(string phoneNumber) 27 | { 28 | var response = new VoiceResponse(); 29 | response.Dial(phoneNumber); 30 | 31 | return TwiML(response); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /IVRPhoneTree.Web.Test/Extensions/ControllerResultTestExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Web.Mvc; 3 | using System.Xml.Linq; 4 | using TestStack.FluentMVCTesting; 5 | using Twilio.AspNet.Mvc; 6 | 7 | namespace IVRPhoneTree.Web.Test.Extensions 8 | { 9 | public static class ControllerResultTestExtensions 10 | { 11 | public static TwiMLResult ShouldReturnTwiMLResult( 12 | this ControllerResultTest controllerResultTest) where T : Controller 13 | { 14 | controllerResultTest.ValidateActionReturnType(); 15 | return (TwiMLResult)controllerResultTest.ActionResult; 16 | } 17 | 18 | public static TwiMLResult ShouldReturnTwiMLResult( 19 | this ControllerResultTest controllerResultTest, 20 | Action assertion) where T : Controller 21 | { 22 | controllerResultTest.ValidateActionReturnType(); 23 | 24 | var twiMLResult = (TwiMLResult)controllerResultTest.ActionResult; 25 | var xdocument = twiMLResult.Data as XDocument; 26 | 27 | assertion(xdocument); 28 | 29 | return (TwiMLResult)controllerResultTest.ActionResult; 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /IVRPhoneTree.Web.Test/Controllers/IVRControllerTest.cs: -------------------------------------------------------------------------------- 1 | using System.Xml.XPath; 2 | using FluentMvcTesting.Extensions.Mocks; 3 | using IVRPhoneTree.Web.Controllers; 4 | using IVRPhoneTree.Web.Test.Extensions; 5 | using NUnit.Framework; 6 | using TestStack.FluentMVCTesting; 7 | 8 | // ReSharper disable PossibleNullReferenceException 9 | 10 | namespace IVRPhoneTree.Web.Test.Controllers 11 | { 12 | public class IVRControllerTest 13 | { 14 | [Test] 15 | public void GivenAWelcomeAction_ThenTheResponseContainsGatherPlay() 16 | { 17 | var controllerPropertiesMock = new ControllerPropertiesMock(); 18 | var controller = new IVRController 19 | { 20 | ControllerContext = controllerPropertiesMock.ControllerContext, 21 | Url = controllerPropertiesMock.Url(RouteConfig.RegisterRoutes) 22 | }; 23 | 24 | controller.WithCallTo(c => c.Welcome()) 25 | .ShouldReturnTwiMLResult(data => 26 | { 27 | Assert.That(data.XPathSelectElement("Response/Gather/Say"), Is.Not.Null); 28 | Assert.That(data.XPathSelectElement("Response/Gather").Attribute("action").Value, 29 | Is.EqualTo("/Menu/Show")); 30 | }); 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /IVRPhoneTree.Web/Web.Debug.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 17 | 18 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /IVRPhoneTree.Web/Web.Release.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 17 | 18 | 19 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /IVRPhoneTree.Web/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | // General Information about an assembly is controlled through the following 5 | // set of attributes. Change these attribute values to modify the information 6 | // associated with an assembly. 7 | [assembly: AssemblyTitle("IVRPhoneTree.Web")] 8 | [assembly: AssemblyDescription("")] 9 | [assembly: AssemblyConfiguration("")] 10 | [assembly: AssemblyCompany("")] 11 | [assembly: AssemblyProduct("IVRPhoneTree.Web")] 12 | [assembly: AssemblyCopyright("Copyright © 2015")] 13 | [assembly: AssemblyTrademark("")] 14 | [assembly: AssemblyCulture("")] 15 | 16 | // Setting ComVisible to false makes the types in this assembly not visible 17 | // to COM components. If you need to access a type in this assembly from 18 | // COM, set the ComVisible attribute to true on that type. 19 | [assembly: ComVisible(false)] 20 | 21 | // The following GUID is for the ID of the typelib if this project is exposed to COM 22 | [assembly: Guid("76b20636-0888-40a9-b21c-97ef2fa197b1")] 23 | 24 | // Version information for an assembly consists of the following four values: 25 | // 26 | // Major Version 27 | // Minor Version 28 | // Build Number 29 | // Revision 30 | // 31 | // You can specify all the values or you can default the Revision and Build Numbers 32 | // by using the '*' as shown below: 33 | [assembly: AssemblyVersion("1.0.0.0")] 34 | [assembly: AssemblyFileVersion("1.0.0.0")] 35 | -------------------------------------------------------------------------------- /IVRPhoneTree.Web.Test/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("IVRPhoneTree.Web.Test")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("IVRPhoneTree.Web.Test")] 13 | [assembly: AssemblyCopyright("Copyright © 2015")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("7e939935-37d4-4134-80ef-85f1d294a422")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /IVRPhoneTree.Web/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /IVRPhoneTree.Web/Views/Web.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |
7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /IVRPhoneTree.Web.Test/Controllers/PhoneExchangeControllerTest.cs: -------------------------------------------------------------------------------- 1 | using System.Xml.XPath; 2 | using FluentMvcTesting.Extensions; 3 | using FluentMvcTesting.Extensions.Mocks; 4 | using IVRPhoneTree.Web.Controllers; 5 | using IVRPhoneTree.Web.Test.Extensions; 6 | using NUnit.Framework; 7 | using TestStack.FluentMVCTesting; 8 | 9 | // ReSharper disable PossibleNullReferenceException 10 | 11 | namespace IVRPhoneTree.Web.Test.Controllers 12 | { 13 | public class PhoneExchangeControllerTest 14 | { 15 | private PhoneExchangeController _controller; 16 | 17 | [SetUp] 18 | public void SetUp() 19 | { 20 | var controllerPropertiesMock = new ControllerPropertiesMock(); 21 | _controller = new PhoneExchangeController 22 | { 23 | ControllerContext = controllerPropertiesMock.ControllerContext, 24 | Url = controllerPropertiesMock.Url(RouteConfig.RegisterRoutes) 25 | }; 26 | } 27 | 28 | [TestCase("2")] 29 | [TestCase("3")] 30 | [TestCase("4")] 31 | public void GivenAShowAction_WhenTheSelectedOptionIsEither_2_Or_3_Or_4_ThenTheResponseContainsDial(string userOption) 32 | { 33 | _controller.WithCallTo(c => c.Interconnect(userOption)) 34 | .ShouldReturnTwiMLResult(data => 35 | { 36 | Assert.That(data.XPathSelectElement("Response/Dial"), Is.Not.Null); 37 | Assert.That(data.XPathSelectElement("Response/Dial").Value, Is.Not.Null); 38 | Assert.That(data.XPathSelectElement("Response/Redirect"), Is.Null); 39 | }); 40 | } 41 | 42 | [Test] 43 | public void GivenAShowAction_WhenTheSelectedOptionIsDifferentThan_2_Or_3_Or_4_ThenTheResponseRedirectsToIVRWelcome() 44 | { 45 | _controller.WithCallTo(c => c.Interconnect("*")) 46 | .ShouldReturnTwiMLResult(data => 47 | { 48 | Assert.That(data.XPathSelectElement("Response/Redirect").Value, Is.EqualTo("/IVR/Welcome")); 49 | }); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: nuget 4 | directory: "/IVRPhoneTree.Web.Test" 5 | schedule: 6 | interval: daily 7 | open-pull-requests-limit: 10 8 | ignore: 9 | - dependency-name: Microsoft.IdentityModel.Logging 10 | versions: 11 | - 6.10.0 12 | - 6.10.1 13 | - 6.10.2 14 | - 6.9.0 15 | - dependency-name: System.IdentityModel.Tokens.Jwt 16 | versions: 17 | - 6.10.0 18 | - 6.10.1 19 | - 6.10.2 20 | - 6.9.0 21 | - dependency-name: Microsoft.IdentityModel.Tokens 22 | versions: 23 | - 6.10.0 24 | - 6.10.1 25 | - 6.10.2 26 | - 6.9.0 27 | - dependency-name: JWT 28 | versions: 29 | - 8.0.0 30 | - 8.1.0 31 | - 8.1.2 32 | - 8.1.3 33 | - 8.1.4 34 | - 8.1.5 35 | - 8.1.6 36 | - dependency-name: Twilio 37 | versions: 38 | - 5.53.1 39 | - 5.54.0 40 | - 5.55.0 41 | - 5.56.0 42 | - 5.57.0 43 | - 5.58.0 44 | - dependency-name: NUnit 45 | versions: 46 | - 3.13.0 47 | - 3.13.1 48 | - dependency-name: Moq 49 | versions: 50 | - 4.16.0 51 | - package-ecosystem: nuget 52 | directory: "/IVRPhoneTree.Web" 53 | schedule: 54 | interval: daily 55 | open-pull-requests-limit: 10 56 | ignore: 57 | - dependency-name: System.IdentityModel.Tokens.Jwt 58 | versions: 59 | - 6.10.0 60 | - 6.10.1 61 | - 6.10.2 62 | - 6.9.0 63 | - dependency-name: Microsoft.IdentityModel.Tokens 64 | versions: 65 | - 6.10.0 66 | - 6.10.1 67 | - 6.10.2 68 | - 6.9.0 69 | - dependency-name: Microsoft.IdentityModel.Logging 70 | versions: 71 | - 6.10.0 72 | - 6.10.1 73 | - 6.10.2 74 | - 6.9.0 75 | - dependency-name: Microsoft.IdentityModel.JsonWebTokens 76 | versions: 77 | - 6.10.0 78 | - 6.10.1 79 | - 6.10.2 80 | - 6.9.0 81 | - dependency-name: JWT 82 | versions: 83 | - 8.0.0 84 | - 8.1.0 85 | - 8.1.2 86 | - 8.1.3 87 | - 8.1.4 88 | - 8.1.5 89 | - 8.1.6 90 | - dependency-name: Twilio 91 | versions: 92 | - 5.53.1 93 | - 5.54.0 94 | - 5.55.0 95 | - 5.56.0 96 | - 5.57.0 97 | - 5.58.0 98 | -------------------------------------------------------------------------------- /IVRPhoneTree.Web/Web.config.sample: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /IVRPhoneTree.Web.Test/app.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /IVRPhoneTree.Web/Controllers/MenuController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Web.Mvc; 4 | using Twilio.AspNet.Mvc; 5 | using Twilio.TwiML; 6 | using Twilio.TwiML.Voice; 7 | 8 | namespace IVRPhoneTree.Web.Controllers 9 | { 10 | public class MenuController : ControllerBase 11 | { 12 | // POST: Menu/Show 13 | [HttpPost] 14 | public ActionResult Show(string digits) 15 | { 16 | var selectedOption = digits; 17 | var optionActions = new Dictionary>() 18 | { 19 | {"1", ReturnInstructions}, 20 | {"2", Planets} 21 | }; 22 | 23 | return optionActions.ContainsKey(selectedOption) ? 24 | optionActions[selectedOption]() : 25 | RedirectWelcome(); 26 | } 27 | 28 | private TwiMLResult ReturnInstructions() 29 | { 30 | var response = new VoiceResponse(); 31 | response.Say("To get to your extraction point, get on your bike and go down " + 32 | "the street. Then Left down an alley. Avoid the police cars. Turn left " + 33 | "into an unfinished housing development. Fly over the roadblock. Go " + 34 | "passed the moon. Soon after you will see your mother ship.", 35 | voice: Say.VoiceEnum.PollyAmy, language: "en-GB"); 36 | 37 | response.Say("Thank you for calling the E.T. Phone Home Service - the " + 38 | "adventurous alien's first choice in intergalactic travel. Good bye."); 39 | 40 | response.Hangup(); 41 | 42 | return TwiML(response); 43 | } 44 | 45 | private TwiMLResult Planets() 46 | { 47 | var response = new VoiceResponse(); 48 | var gather = new Gather(action: Url.ActionUri("Interconnect", "PhoneExchange"), numDigits: 1); 49 | gather.Say("To call the planet Broh doe As O G, press 2. To call the planet " + 50 | "DuhGo bah, press 3. To call an oober asteroid to your location, press 4. To " + 51 | "go back to the main menu, press the star key ", 52 | voice: Say.VoiceEnum.PollyAmy, language: "en-GB", loop: 3); 53 | response.Append(gather); 54 | 55 | return TwiML(response); 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /IVRPhoneTree.Web.Test/Controllers/MenuControllerTest.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using System.Xml.XPath; 3 | using FluentMvcTesting.Extensions; 4 | using FluentMvcTesting.Extensions.Mocks; 5 | using IVRPhoneTree.Web.Controllers; 6 | using IVRPhoneTree.Web.Test.Extensions; 7 | using NUnit.Framework; 8 | using TestStack.FluentMVCTesting; 9 | 10 | // ReSharper disable PossibleNullReferenceException 11 | 12 | namespace IVRPhoneTree.Web.Test.Controllers 13 | { 14 | public class MenuControllerTest 15 | { 16 | private MenuController _controller; 17 | 18 | [SetUp] 19 | public void SetUp() 20 | { 21 | var controllerPropertiesMock = new ControllerPropertiesMock(); 22 | _controller = new MenuController 23 | { 24 | ControllerContext = controllerPropertiesMock.ControllerContext, 25 | Url = controllerPropertiesMock.Url(RouteConfig.RegisterRoutes) 26 | }; 27 | } 28 | 29 | [Test] 30 | public void GivenAShowAction_WhenTheSelectedOptionIs1_ThenTheResponseContainsSayTwiceAndAHangup() 31 | { 32 | _controller.WithCallTo(c => c.Show("1")) 33 | .ShouldReturnTwiMLResult(data => 34 | { 35 | Assert.That(data.XPathSelectElements("Response/Say").Count(), Is.EqualTo(2)); 36 | Assert.That(data.XPathSelectElement("Response/Hangup"), Is.Not.Null); 37 | }); 38 | } 39 | 40 | [Test] 41 | public void GivenAShowAction_WhenTheSelectedOptionIs2_ThenTheResponseContainsGatherAndSay() 42 | { 43 | _controller.WithCallTo(c => c.Show("2")) 44 | .ShouldReturnTwiMLResult(data => 45 | { 46 | Assert.That(data.XPathSelectElement("Response/Gather/Say"), Is.Not.Null); 47 | Assert.That(data.XPathSelectElement("Response/Gather").Attribute("action").Value, 48 | Is.EqualTo("/PhoneExchange/Interconnect")); 49 | }); 50 | } 51 | 52 | [Test] 53 | public void GivenAShowAction_WhenTheSelectedOptionIsDifferentThan_1_Or_2_ThenTheResponseRedirectsToIVRWelcome() 54 | { 55 | _controller.WithCallTo(c => c.Show("*")) 56 | .ShouldReturnTwiMLResult(data => 57 | { 58 | Assert.That(data.XPathSelectElement("Response/Redirect").Value, 59 | Is.EqualTo("/IVR/Welcome")); 60 | }); 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | Twilio 3 | 4 | 5 | # IVR Phone Tree: IVR for beginners. Powered by Twilio - ASP.NET MVC 6 | 7 | ![](https://github.com/TwilioDevEd/ivr-phone-tree-csharp/workflows/NetFx/badge.svg) 8 | 9 | An example application implementing an automated phone line using Twilio. 10 | 11 | [Read the full tutorial here](https://www.twilio.com/docs/tutorials/walkthrough/ivr-phone-tree/csharp/mvc)! 12 | 13 | ## Local development 14 | 15 | This project is built using the [ASP.NET MVC](http://www.asp.net/mvc) web framework. 16 | 17 | 1. First clone this repository and `cd` into its directory: 18 | ``` 19 | git clone git@github.com:TwilioDevEd/ivr-phone-tree-csharp.git 20 | cd ivr-phone-tree-csharp 21 | ``` 22 | 23 | 1. Build the solution. 24 | 25 | 1. Expose your application to the wider internet using [ngrok](http://ngrok.com). This step 26 | is important because the application won't work as expected if you run it through 27 | localhost. 28 | 29 | To start using `ngrok` in our project you'll have execute to the following line in the _command prompt_. 30 | 31 | ```shell 32 | ngrok http 1112 -host-header="localhost:1112" 33 | ``` 34 | 35 | Keep in mind that our endpoint is: 36 | 37 | ``` 38 | http://.ngrok.io/ivr/welcome 39 | ``` 40 | 41 | Remember to update the Local.config file with the generated ngrok subdomain. 42 | 43 | 1. Configure Twilio to call your webhooks. 44 | 45 | You will also need to configure Twilio to call your application when calls are 46 | received in your [*Twilio Number*](https://console.twilio.com/us1/develop/phone-numbers/manage/active?frameUrl=%2Fconsole%2Fphone-numbers%2Fincoming%3Fx-target-region%3Dus1). 47 | The voice url should look something like this: 48 | 49 | ``` 50 | http://.ngrok.io/ivr/welcome 51 | ``` 52 | 53 | [Learn how to configure your Twilio phone number for Programmable Voice](https://www.twilio.com/docs/voice/tutorials/ivr-phone-tree-csharp-mvc#respond-to-the-phone-call). 54 | 55 | ## Unit Tests 56 | 57 | To run the unit tests within Visual Studio, install the NUnit 3 Test Adapter: 58 | https://marketplace.visualstudio.com/items?itemName=NUnitDevelopers.NUnit3TestAdapter 59 | 60 | ## Meta 61 | 62 | * No warranty expressed or implied. Software is as is. Diggity. 63 | * [MIT License](http://www.opensource.org/licenses/mit-license.html) 64 | * Lovingly crafted by Twilio Developer Education. 65 | -------------------------------------------------------------------------------- /IVRPhoneTree.Web.Test/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /IVRPhoneTree.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.30717.126 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IVRPhoneTree.Web", "IVRPhoneTree.Web\IVRPhoneTree.Web.csproj", "{3F60D72D-D360-43CC-AB7F-16B53CA60EEF}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IVRPhoneTree.Web.Test", "IVRPhoneTree.Web.Test\IVRPhoneTree.Web.Test.csproj", "{CA5D33F3-3083-45C3-97F5-09948BC48CA2}" 9 | EndProject 10 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{F95D2194-11EF-4F2C-BDB8-88E9BB381B5C}" 11 | ProjectSection(SolutionItems) = preProject 12 | .gitignore = .gitignore 13 | .mergify.yml = .mergify.yml 14 | README.md = README.md 15 | EndProjectSection 16 | EndProject 17 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".github", ".github", "{D772EDC2-88B5-4A4A-8C8C-F8770B8D0E94}" 18 | EndProject 19 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{B781D28E-CADE-4E3A-B993-D92D7C5D1699}" 20 | ProjectSection(SolutionItems) = preProject 21 | .github\workflows\NetFx.yml = .github\workflows\NetFx.yml 22 | EndProjectSection 23 | EndProject 24 | Global 25 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 26 | Debug|Any CPU = Debug|Any CPU 27 | Release|Any CPU = Release|Any CPU 28 | EndGlobalSection 29 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 30 | {3F60D72D-D360-43CC-AB7F-16B53CA60EEF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 31 | {3F60D72D-D360-43CC-AB7F-16B53CA60EEF}.Debug|Any CPU.Build.0 = Debug|Any CPU 32 | {3F60D72D-D360-43CC-AB7F-16B53CA60EEF}.Release|Any CPU.ActiveCfg = Release|Any CPU 33 | {3F60D72D-D360-43CC-AB7F-16B53CA60EEF}.Release|Any CPU.Build.0 = Release|Any CPU 34 | {CA5D33F3-3083-45C3-97F5-09948BC48CA2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 35 | {CA5D33F3-3083-45C3-97F5-09948BC48CA2}.Debug|Any CPU.Build.0 = Debug|Any CPU 36 | {CA5D33F3-3083-45C3-97F5-09948BC48CA2}.Release|Any CPU.ActiveCfg = Release|Any CPU 37 | {CA5D33F3-3083-45C3-97F5-09948BC48CA2}.Release|Any CPU.Build.0 = Release|Any CPU 38 | EndGlobalSection 39 | GlobalSection(SolutionProperties) = preSolution 40 | HideSolutionNode = FALSE 41 | EndGlobalSection 42 | GlobalSection(NestedProjects) = preSolution 43 | {D772EDC2-88B5-4A4A-8C8C-F8770B8D0E94} = {F95D2194-11EF-4F2C-BDB8-88E9BB381B5C} 44 | {B781D28E-CADE-4E3A-B993-D92D7C5D1699} = {D772EDC2-88B5-4A4A-8C8C-F8770B8D0E94} 45 | EndGlobalSection 46 | GlobalSection(ExtensibilityGlobals) = postSolution 47 | SolutionGuid = {F3725EB1-598E-4669-99C7-FC53A2B107EC} 48 | EndGlobalSection 49 | EndGlobal 50 | -------------------------------------------------------------------------------- /IVRPhoneTree.Web/Web.config: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Copied from: https://github.com/github/gitignore/blob/1587f288ee3c5132ad5e14be232d9e5784209286/VisualStudio.gitignore 2 | ## Ignore Visual Studio temporary files, build results, and 3 | ## files generated by popular Visual Studio add-ons. 4 | 5 | # User-specific files 6 | *.suo 7 | *.user 8 | *.userosscache 9 | *.sln.docstates 10 | 11 | # User-specific files (MonoDevelop/Xamarin Studio) 12 | *.userprefs 13 | 14 | # Build results 15 | [Dd]ebug/ 16 | [Dd]ebugPublic/ 17 | [Rr]elease/ 18 | [Rr]eleases/ 19 | x64/ 20 | x86/ 21 | build/ 22 | bld/ 23 | [Bb]in/ 24 | [Oo]bj/ 25 | 26 | # Visual Studio 2015 cache/options directory 27 | .vs/ 28 | 29 | # MSTest test Results 30 | [Tt]est[Rr]esult*/ 31 | [Bb]uild[Ll]og.* 32 | 33 | # NUNIT 34 | *.VisualState.xml 35 | TestResult.xml 36 | 37 | # Build Results of an ATL Project 38 | [Dd]ebugPS/ 39 | [Rr]eleasePS/ 40 | dlldata.c 41 | 42 | # DNX 43 | project.lock.json 44 | artifacts/ 45 | 46 | *_i.c 47 | *_p.c 48 | *_i.h 49 | *.ilk 50 | *.meta 51 | *.obj 52 | *.pch 53 | *.pdb 54 | *.pgc 55 | *.pgd 56 | *.rsp 57 | *.sbr 58 | *.tlb 59 | *.tli 60 | *.tlh 61 | *.tmp 62 | *.tmp_proj 63 | *.log 64 | *.vspscc 65 | *.vssscc 66 | .builds 67 | *.pidb 68 | *.svclog 69 | *.scc 70 | 71 | # Chutzpah Test files 72 | _Chutzpah* 73 | 74 | # Visual C++ cache files 75 | ipch/ 76 | *.aps 77 | *.ncb 78 | *.opensdf 79 | *.sdf 80 | *.cachefile 81 | 82 | # Visual Studio profiler 83 | *.psess 84 | *.vsp 85 | *.vspx 86 | 87 | # TFS 2012 Local Workspace 88 | $tf/ 89 | 90 | # Guidance Automation Toolkit 91 | *.gpState 92 | 93 | # ReSharper is a .NET coding add-in 94 | _ReSharper*/ 95 | *.[Rr]e[Ss]harper 96 | *.DotSettings.user 97 | 98 | # JustCode is a .NET coding add-in 99 | .JustCode 100 | 101 | # TeamCity is a build add-in 102 | _TeamCity* 103 | 104 | # DotCover is a Code Coverage Tool 105 | *.dotCover 106 | 107 | # NCrunch 108 | _NCrunch_* 109 | .*crunch*.local.xml 110 | 111 | # MightyMoose 112 | *.mm.* 113 | AutoTest.Net/ 114 | 115 | # Web workbench (sass) 116 | .sass-cache/ 117 | 118 | # Installshield output folder 119 | [Ee]xpress/ 120 | 121 | # DocProject is a documentation generator add-in 122 | DocProject/buildhelp/ 123 | DocProject/Help/*.HxT 124 | DocProject/Help/*.HxC 125 | DocProject/Help/*.hhc 126 | DocProject/Help/*.hhk 127 | DocProject/Help/*.hhp 128 | DocProject/Help/Html2 129 | DocProject/Help/html 130 | 131 | # Click-Once directory 132 | publish/ 133 | 134 | # Publish Web Output 135 | *.[Pp]ublish.xml 136 | *.azurePubxml 137 | # TODO: Comment the next line if you want to checkin your web deploy settings 138 | # but database connection strings (with potential passwords) will be unencrypted 139 | *.pubxml 140 | *.publishproj 141 | 142 | # NuGet Packages 143 | *.nupkg 144 | # The packages folder can be ignored because of Package Restore 145 | **/packages/* 146 | # except build/, which is used as an MSBuild target. 147 | !**/packages/build/ 148 | # Uncomment if necessary however generally it will be regenerated when needed 149 | #!**/packages/repositories.config 150 | 151 | # Windows Azure Build Output 152 | csx/ 153 | *.build.csdef 154 | 155 | # Windows Store app package directory 156 | AppPackages/ 157 | 158 | # Visual Studio cache files 159 | # files ending in .cache can be ignored 160 | *.[Cc]ache 161 | # but keep track of directories ending in .cache 162 | !*.[Cc]ache/ 163 | 164 | # Others 165 | ClientBin/ 166 | [Ss]tyle[Cc]op.* 167 | ~$* 168 | *~ 169 | *.dbmdl 170 | *.dbproj.schemaview 171 | *.pfx 172 | *.publishsettings 173 | node_modules/ 174 | orleans.codegen.cs 175 | 176 | # RIA/Silverlight projects 177 | Generated_Code/ 178 | 179 | # Backup & report files from converting an old project file 180 | # to a newer Visual Studio version. Backup files are not needed, 181 | # because we have git ;-) 182 | _UpgradeReport_Files/ 183 | Backup*/ 184 | UpgradeLog*.XML 185 | UpgradeLog*.htm 186 | 187 | # SQL Server files 188 | *.mdf 189 | *.ldf 190 | 191 | # Business Intelligence projects 192 | *.rdl.data 193 | *.bim.layout 194 | *.bim_*.settings 195 | 196 | # Microsoft Fakes 197 | FakesAssemblies/ 198 | 199 | # Node.js Tools for Visual Studio 200 | .ntvs_analysis.dat 201 | 202 | # Visual Studio 6 build log 203 | *.plg 204 | 205 | # Visual Studio 6 workspace options file 206 | *.opt 207 | 208 | # Project files 209 | IVRPhoneTree.Web/Scripts/lib/ 210 | -------------------------------------------------------------------------------- /IVRPhoneTree.Web.Test/IVRPhoneTree.Web.Test.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {CA5D33F3-3083-45C3-97F5-09948BC48CA2} 8 | Library 9 | Properties 10 | IVRPhoneTree.Web.Test 11 | IVRPhoneTree.Web.Test 12 | v4.7.2 13 | 512 14 | {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 15 | 10.0 16 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) 17 | $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages 18 | False 19 | UnitTest 20 | 21 | 22 | 23 | 24 | 25 | true 26 | full 27 | false 28 | bin\Debug\ 29 | DEBUG;TRACE 30 | prompt 31 | 4 32 | 33 | 34 | pdbonly 35 | true 36 | bin\Release\ 37 | TRACE 38 | prompt 39 | 4 40 | 41 | 42 | 43 | ..\packages\Portable.BouncyCastle.1.8.9\lib\net40\BouncyCastle.Crypto.dll 44 | 45 | 46 | ..\packages\Castle.Core.4.4.1\lib\net45\Castle.Core.dll 47 | 48 | 49 | ..\packages\FluentMvcTesting.Extensions.1.0.4\lib\net45\FluentMvcTesting.Extensions.dll 50 | 51 | 52 | ..\packages\Portable.JWT.1.0.5\lib\portable-net45+win+wpa81+wp80+MonoAndroid10+xamarinios10+MonoTouch10\JWT.dll 53 | 54 | 55 | 56 | ..\packages\Microsoft.IdentityModel.JsonWebTokens.6.8.0\lib\net461\Microsoft.IdentityModel.JsonWebTokens.dll 57 | 58 | 59 | ..\packages\Microsoft.IdentityModel.Logging.6.8.0\lib\net461\Microsoft.IdentityModel.Logging.dll 60 | 61 | 62 | ..\packages\Microsoft.IdentityModel.Tokens.6.8.0\lib\net461\Microsoft.IdentityModel.Tokens.dll 63 | 64 | 65 | ..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll 66 | 67 | 68 | ..\packages\Moq.4.15.2\lib\net45\Moq.dll 69 | 70 | 71 | ..\packages\Newtonsoft.Json.12.0.3\lib\net45\Newtonsoft.Json.dll 72 | 73 | 74 | ..\packages\NUnit.3.12.0\lib\net45\nunit.framework.dll 75 | 76 | 77 | 78 | 79 | ..\packages\System.IdentityModel.Tokens.Jwt.6.8.0\lib\net461\System.IdentityModel.Tokens.Jwt.dll 80 | 81 | 82 | 83 | 84 | ..\packages\System.Runtime.CompilerServices.Unsafe.5.0.0\lib\net45\System.Runtime.CompilerServices.Unsafe.dll 85 | 86 | 87 | ..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll 88 | 89 | 90 | 91 | ..\packages\Microsoft.AspNet.WebPages.3.2.7\lib\net45\System.Web.Helpers.dll 92 | 93 | 94 | ..\packages\Microsoft.AspNet.Mvc.5.2.7\lib\net45\System.Web.Mvc.dll 95 | 96 | 97 | ..\packages\Microsoft.AspNet.Razor.3.2.7\lib\net45\System.Web.Razor.dll 98 | 99 | 100 | ..\packages\Microsoft.AspNet.WebPages.3.2.7\lib\net45\System.Web.WebPages.dll 101 | 102 | 103 | ..\packages\Microsoft.AspNet.WebPages.3.2.7\lib\net45\System.Web.WebPages.Deployment.dll 104 | 105 | 106 | ..\packages\Microsoft.AspNet.WebPages.3.2.7\lib\net45\System.Web.WebPages.Razor.dll 107 | 108 | 109 | 110 | 111 | ..\packages\TestStack.FluentMVCTesting.3.0.0\lib\NET45\TestStack.FluentMVCTesting.dll 112 | 113 | 114 | ..\packages\Twilio.5.52.1\lib\net451\Twilio.dll 115 | 116 | 117 | ..\packages\Twilio.AspNet.Common.5.37.2\lib\net45\Twilio.AspNet.Common.dll 118 | 119 | 120 | ..\packages\Twilio.AspNet.Mvc.5.37.2\lib\net451\Twilio.AspNet.Mvc.dll 121 | 122 | 123 | ..\packages\Twilio.Mvc.3.1.15\lib\3.5\Twilio.Mvc.dll 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | {3F60D72D-D360-43CC-AB7F-16B53CA60EEF} 152 | IVRPhoneTree.Web 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | False 161 | 162 | 163 | False 164 | 165 | 166 | False 167 | 168 | 169 | False 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. 179 | 180 | 181 | 182 | 189 | -------------------------------------------------------------------------------- /IVRPhoneTree.Web/IVRPhoneTree.Web.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Debug 7 | AnyCPU 8 | 9 | 10 | 2.0 11 | {3F60D72D-D360-43CC-AB7F-16B53CA60EEF} 12 | {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc} 13 | Library 14 | Properties 15 | IVRPhoneTree.Web 16 | IVRPhoneTree.Web 17 | v4.7.2 18 | false 19 | true 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | true 32 | full 33 | false 34 | bin\ 35 | DEBUG;TRACE 36 | prompt 37 | 4 38 | 39 | 40 | pdbonly 41 | true 42 | bin\ 43 | TRACE 44 | prompt 45 | 4 46 | 47 | 48 | 49 | ..\packages\Antlr.3.5.0.2\lib\Antlr3.Runtime.dll 50 | 51 | 52 | ..\packages\Portable.BouncyCastle.1.8.9\lib\net40\BouncyCastle.Crypto.dll 53 | 54 | 55 | ..\packages\Portable.JWT.1.0.5\lib\portable-net45+win+wpa81+wp80+MonoAndroid10+xamarinios10+MonoTouch10\JWT.dll 56 | 57 | 58 | 59 | ..\packages\Microsoft.IdentityModel.JsonWebTokens.6.8.0\lib\net461\Microsoft.IdentityModel.JsonWebTokens.dll 60 | 61 | 62 | ..\packages\Microsoft.IdentityModel.Logging.6.8.0\lib\net461\Microsoft.IdentityModel.Logging.dll 63 | 64 | 65 | ..\packages\Microsoft.IdentityModel.Tokens.6.8.0\lib\net461\Microsoft.IdentityModel.Tokens.dll 66 | 67 | 68 | ..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll 69 | 70 | 71 | 72 | ..\packages\Newtonsoft.Json.12.0.3\lib\net45\Newtonsoft.Json.dll 73 | 74 | 75 | ..\packages\RestSharp.106.11.7\lib\net452\RestSharp.dll 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | ..\packages\System.IdentityModel.Tokens.Jwt.6.8.0\lib\net461\System.IdentityModel.Tokens.Jwt.dll 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | ..\packages\Microsoft.AspNet.WebPages.3.2.7\lib\net45\System.Web.Helpers.dll 112 | 113 | 114 | ..\packages\Microsoft.AspNet.Mvc.5.2.7\lib\net45\System.Web.Mvc.dll 115 | 116 | 117 | ..\packages\Microsoft.AspNet.Web.Optimization.1.1.3\lib\net40\System.Web.Optimization.dll 118 | 119 | 120 | ..\packages\Microsoft.AspNet.Razor.3.2.7\lib\net45\System.Web.Razor.dll 121 | 122 | 123 | 124 | ..\packages\Microsoft.AspNet.WebPages.3.2.7\lib\net45\System.Web.WebPages.dll 125 | 126 | 127 | ..\packages\Microsoft.AspNet.WebPages.3.2.7\lib\net45\System.Web.WebPages.Deployment.dll 128 | 129 | 130 | ..\packages\Microsoft.AspNet.WebPages.3.2.7\lib\net45\System.Web.WebPages.Razor.dll 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | ..\packages\Twilio.5.52.1\lib\net451\Twilio.dll 143 | 144 | 145 | ..\packages\Twilio.AspNet.Common.5.37.2\lib\net45\Twilio.AspNet.Common.dll 146 | 147 | 148 | ..\packages\Twilio.AspNet.Mvc.5.37.2\lib\net451\Twilio.AspNet.Mvc.dll 149 | 150 | 151 | ..\packages\WebGrease.1.6.0\lib\WebGrease.dll 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | Global.asax 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | Web.config 178 | 179 | 180 | Web.config 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 10.0 208 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | True 221 | True 222 | 1112 223 | / 224 | http://localhost:1112/ 225 | False 226 | False 227 | 228 | 229 | False 230 | 231 | 232 | 233 | 234 | 235 | 236 | This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. 237 | 238 | 239 | 240 | 241 | 242 | 248 | --------------------------------------------------------------------------------