Alexa.Tip – Build Unit Tested Skills in .NET

In this Alexa.Tip series, we explore some little bits of code that can make your life easier in developing Alexa Skills in many languages including C# + .NET, node.jS + TypeScript, Kotlin, etc. We look at concepts, design patterns, and implementations that developers might not be aware of, and how they can be applied to voice application development, best practices, and more!

In this post, we explore some more best practices in developing Alexa Skills in C# whether you are using an ASP.NET Core API or an AWS Lambda. This post will expand our previous posts about building better abstractions for handling Alexa responses and demonstrate how we can now properly Unit test these handlers as well as any other separated bits of logic that the Handler implementations consume.

Check out all the raw source code for this post, and more here: https://github.com/SuavePirate/Alexa.Tips.Net

Prerequisite

If you haven’t read up on how to use the Handler Registration Pattern, take a look at my earlier post here: Alexa.Tip – Using Handler Registration Pattern in .NET

The short version is that we use this pattern of registering IHandler implementations to handle different types of requests that our skill receives, regardless of whether we are using AWS Lambdas or ASP.NET Core APIs.

Unit Testing Handlers

Since we now have nice atomized units (Handlers) built for each of our RequestTypes and Intents, they are SCREAMING to be unit tested. So, we can easily test them against different scenarios given our positive and negative cases.

Take for example, the SimpleLaunchHandler that is responsible only for LaunchRequest, and whose HandleAsync() implementation returns a static response. The two main cases we want to test against is the HandleAsync() returning properly for a proper LaunchRequest, and that the CanHandle() implementation returns false for non LaunchRequest skill requests.

In these samples, I’m using xUnit for my Unit tests, but the same concept is applicable with any other Unit testing framework (and really any other language).

In each case, we want to separate our 3 A’s of testing, “Arrange”, “Act”, and “Assert”. For these basic examples, the three steps are pretty clear.

  1. Arrange the Testable SkillRequest object
  2. Act on the subject’s method we are testing by sending it the SkillRequest
  3. Assert our final response

Let’s first test the CanHandle() against the postive case, meaning we want to send it data we want to be successful:

public class SimpleLaunchHandlerTests
{
    private readonly SimpleLaunchHandler _subject;
    public SimpleLaunchHandlerTests()
    {
        _subject = new SimpleLaunchHandler();
    }


    [Fact]
    public void SimpleHandler_CanHandleLaunchRequest()
    {
        // arrange
        var request = new SkillRequest()
        {
            Version = "1.0",
            Request = new LaunchRequest
            {
                Type = "LaunchRequest"
            }
        };

        // act
        var canHandle = _subject.CanHandle(request);

        // assert
        Assert.True(canHandle);
    }

}

Now let’s perform the opposite by sending it a request of a different type:

 [Fact]
public void SimpleHandler_CanNotHandleIntentRequest()
{
    // arrange
    var request = new SkillRequest()
    {
        Version = "1.0",
        Request = new IntentRequest
        {
            Type = "IntentRequest"
        }
    };

    // act
    var canHandle = _subject.CanHandle(request);

    // assert
    Assert.False(canHandle);
}

Now, we can look at the positive example of passing the LaunchRequest into the HandleAsync method:

[Fact]
public async Task SimpleHandler_ReturnsResponse()
{
    // arrange
    var request = new SkillRequest()
    {
        Version = "1.0",
        Request = new LaunchRequest
        {
            Type = "LaunchRequest"
        }
    };

    // act
    var response = await _subject.HandleAsync(request);

    // assert
    Assert.NotNull((response.Response.OutputSpeech as PlainTextOutputSpeech)?.Text);
}

Now that we have our LaunchRequest tested, let’s take a look at a simple static IntentRequest set of tests:

DogFactHandlerTests.cs

public class DogFactHandlerTests : IClassFixture<DogFactHandler>
{
    private readonly DogFactHandler _subject = new DogFactHandler();


    [Fact]
    public async Task DogFactHandler_ReturnsResponse()
    {
        // arrange
        var request = new SkillRequest()
        {
            Version = "1.0",
            Request = new IntentRequest
            {
                Type = "IntentRequest",
                Intent = new Intent
                {
                    Name = "DogFactIntent"
                }
            }
        };

        // act
        var response = await _subject.HandleAsync(request);

        // assert
        Assert.NotNull((response.Response.OutputSpeech as PlainTextOutputSpeech)?.Text);
    }

    [Fact]
    public void DogFactHandler_CanHandleIntentRequest()
    {
        // arrange
        var request = new SkillRequest()
        {
            Version = "1.0",
            Request = new IntentRequest
            {
                Type = "IntentRequest",
                Intent = new Intent
                {
                    Name = "DogFactIntent"
                }
            }
        };
        // act
        var canHandle = _subject.CanHandle(request);

        // assert
        Assert.True(canHandle);
    }
    [Fact]
    public void DogFactHandler_CanNotHandleLaunchRequest()
    {
        // arrange
        var request = new SkillRequest()
        {
            Version = "1.0",
            Request = new LaunchRequest
            {
                Type = "LaunchRequest"
            }
        };


        // act
        var canHandle = _subject.CanHandle(request);

        // assert
        Assert.False(canHandle);
    }
    [Fact]
    public void DogFactHandler_CanNotHandleOtherIntents()
    {
        // arrange
        var request = new SkillRequest()
        {
            Version = "1.0",
            Request = new IntentRequest
            {
                Type = "IntentRequest",
                Intent = new Intent
                {
                    Name = "AMAZON.HelpIntent"
                }
            }
        };


        // act
        var canHandle = _subject.CanHandle(request);

        // assert
        Assert.False(canHandle);
    }
}

Okay, cool, but what about stuff that isn’t static? What if I’m getting my data from somewhere else and want to test those cases? Let’s bring Moq into the picture!

Let’s take this handler for example:

SampleFactHandler.cs

public class SampleFactHandler : GenericHandler, IHandler
{
    private readonly SampleMessageDbContext _context;
    public SampleFactHandler(SampleMessageDbContext context)
    {
        _context = context;
    }
    public override string IntentName => "SampleMessageIntent";

    public override Type RequestType => typeof(IntentRequest);

    public override async Task<SkillResponse> HandleAsync(SkillRequest request)
    {
        // just grab one as an example
        var message = await _context.SampleMessages.FirstOrDefaultAsync();
        return ResponseBuilder.Tell(message?.Content ?? "I don't have any messages for you.");
    }
}

So this Handler uses an Entity Framework Core DbContext with a table of SampleMessage objects to get the content. In this sample, we just grab the first one, but you could imagine some more complex data-logic to pull out the proper message.

To unit test this, we can pass in different “Mock” implementations of the SampleMessageDbContext. For this, I usually use Moq, but you can also pass in a full implementation that you’ve built yourself.

Here are some samples of testing this with different Moq’d contexts to test a few scenarios. Note: we still want to test against the CanHandle and HandleAsync as well, but now we have two different cases to test for such as if there are no messages in the db, and when there is one.

SampleFactHandlerTests.cs

public class SampleFactHandlerTests
{
    [Fact]
    public async Task SampleFactHandler_ReturnResponseWithData()
    {
        // arrange
        var context = new Mock<SampleMessageDbContext>();
        context.Setup(d => d.SampleMessages.FirstOrDefaultAsync(CancellationToken.None)).Returns(Task.FromResult(new SampleMessage
        {
            Id = Guid.NewGuid().ToString(),
            Content = "This is a mocked response message"
        }));
        var subject = new SampleFactHandler(context.Object);
        var request = new SkillRequest()
        {
            Version = "1.0",
            Request = new IntentRequest
            {
                Type = "IntentRequest",
                Intent = new Intent
                {
                    Name = "SampleMessageIntent"
                }
            }
        };

        // act
        var response = await subject.HandleAsync(request);

        // assert
        Assert.NotNull((response.Response.OutputSpeech as PlainTextOutputSpeech)?.Text);
    }
    [Fact]
    public async Task SampleFactHandler_ReturnFallbackResponseWithNoData()
    {
        // arrange
        var context = new Mock<SampleMessageDbContext>();
        context.Setup(d => d.SampleMessages.FirstOrDefaultAsync(CancellationToken.None)).Returns(Task.FromResult<SampleMessage>(null));
        var subject = new SampleFactHandler(context.Object);
        var request = new SkillRequest()
        {
            Version = "1.0",
            Request = new IntentRequest
            {
                Type = "IntentRequest",
                Intent = new Intent
                {
                    Name = "SampleMessageIntent"
                }
            }
        };

        // act
        var response = await subject.HandleAsync(request);

        // assert
        Assert.True((response.Response.OutputSpeech as PlainTextOutputSpeech)?.Text == "I don't have any messages for you.");
    }
}

We can also, and probably should also add some CanHandle and non-assinable Intent types to test, but for the sake of not making you read the same thing over and over again, these are the two that matters.

Unit Testing Controllers

Personally, I don’t typically unit test my Controllers, but that’s because I have some general rules in place to not change them one they are implemented. However, when working on a team, it may be easier and more sustainable to implement a few test on the controller to guarantee that changes made to it don’t affect the currently working implementation.

Some basic positive/negative test might look like this:

SimpleAlexaControllerTests.cs

public class SimpleAlexaControllerTests
{
    [Fact]
    public async Task AlexaController_ResponseWithHandler() 
    {
        // arrange
        var subject = new SimpleAlexaController(new List<IHandler>{ new DogFactHandler() });
        var request = new SkillRequest()
        {
            Version = "1.0",
            Request = new IntentRequest
            {
                Type = "IntentRequest",
                Intent = new Intent
                {
                    Name = "DogFactIntent"
                }
            }
        };
        // act
        var response = _subject.HandleRequest(request);

        // assert
        Assert.NotNull((response.Response.OutputSpeech as PlainTextOutputSpeech)?.Text);
    }

    [Fact]
    public async Task AlexaController_ResponseWithoutHandler() 
    {
        // arrange
        var subject = new SimpleAlexaController(new List<IHandler>{ new SimpleLaunchHandler() }); // no DogFactHandler
        var request = new SkillRequest()
        {
            Version = "1.0",
            Request = new IntentRequest
            {
                Type = "IntentRequest",
                Intent = new Intent
                {
                    Name = "DogFactIntent"
                }
            }
        };

        // act
        var response = _subject.HandleRequest(request);

        // assert
        Assert.Null(response);
    }
}

Unit Testing Lambda Functions

Just like testing the Controller, if you are using AWS Lambda rather than ASP.NET Core, you can create unit tests against your Function endpoint in order to get some coverage. That could look simple like something here:

FunctionHandlerTests.cs

public class FunctionHandlerTests
{

    [Fact]
    public async Task LambdaFunction_ResponseWithHandler() 
    {
        // arrange
        var subject = new SimpleAlexaHandler();
        subject.Handlers = new List<IHandler>{ new DogFactIntent() });
        var request = new SkillRequest()
        {
            Version = "1.0",
            Request = new IntentRequest
            {
                Type = "IntentRequest",
                Intent = new Intent
                {
                    Name = "DogFactIntent"
                }
            }
        };
        // act
        var response = _subject.HandleRequest(request, null);

        // assert
        Assert.NotNull((response.Response.OutputSpeech as PlainTextOutputSpeech)?.Text);
    }

    [Fact]
    public async Task LambdaFunction_ResponseWithoutHandler() 
    {
        // arrange
        var subject = new SimpleAlexaHandler();
        subject.Handlers = new List<IHandler>{ new SimpleLaunchHandler() }); // no DogFactIntent handler
        var request = new SkillRequest()
        {
            Version = "1.0",
            Request = new IntentRequest
            {
                Type = "IntentRequest",
                Intent = new Intent
                {
                    Name = "DogFactIntent"
                }
            }
        };

        // act
        var response = _subject.HandleRequest(request);

        // assert
        Assert.Null(response);
    }

}

That’s all the unit test types for now! Anything else that needs testing would be tested outside the Alexa specific logic. But hey! Now we can write some strong and code-covered tested skills which leads to better skills overall

What’s next?

Check out more Alexa Developer Tips here: https://alexdunn.org/tag/alexa/


If you like what you see, don’t forget to follow me on twitter @Suave_Pirate, check out my GitHub, and subscribe to my blog to learn more mobile and AI developer tips and tricks!

Interested in sponsoring developer content? Message @Suave_Pirate on twitter for details.


voicify_logo
I’m the Director and Principal Architect over at Voicify. Learn how you can use the Voice Experience Platform to bring your brand into the world of voice on Alexa, Google Assistant, Cortana, chat bots, and more: https://voicify.com/


Advertisements

Alexa.Tip – Using Handler Registration Pattern in .NET

In this Alexa.Tip series, we explore some little bits of code that can make your life easier in developing Alexa Skills in many languages including C# + .NET, node.jS + TypeScript, Kotlin, etc. We look at concepts, design patterns, and implementations that developers might not be aware of, and how they can be applied to voice application development, best practices, and more!

In this post, we explore some more best practices in developing Alexa Skills in C# whether you are using an ASP.NET Core API or an AWS Lambda. This time, we talk about using the Registration Pattern for our Request Handlers. This post builds off of some of the concepts found in a previous post: Alexa.Tip – Build Intent Handlers in .NET but uses a newer abstraction tactic I like that can be found in my Alexa .NET Samples Repo here: https://github.com/SuavePirate/Alexa.Tips.Net

If you followed the previous post, you saw the benefits of abstracting our Alexa specific business logic into Handlers. That post talked specifically about IntentHandlers, but I’ve gone about implementing a new pattern for handling all request types that follows some of the same patterns of the official Alexa Skills Kit SDKs in JavaScript and Java but with all the C# goodness of Dependency Injection, Abstractions, async, and more.

Build Handlers

The primary concept is to create Handlers that register with information about what types of requests they can handle, then register those handlers for Dependency Injection (but in a slightly different way than normal), then finding the proper Handler for the given request and passing the rest of the transaction off to it to run its logic.

Here’s a look at our foundation: the IHandler:

IHandler.cs

public interface IHandler
{
    Type RequestType { get; }
    string IntentName { get; }
    bool CanHandle(SkillRequest request);
    Task<SkillResponse> HandleAsync(SkillRequest request);
}

So with this, we can use RequestType to validate what type of request the handler is for such as LaunchRequest or IntentRequest. You can take a peep at all the request types of Alexa Skills here: https://developer.amazon.com/docs/custom-skills/request-types-reference.html

We can also use the IntentName to easily assign a specific intent to a handler if the RequestType is IntentRequest. Then CanHandle() is used for applying custom validation logic to tell the registration what type of requests it is for. An implementation of this might validate the RequestType and IntentName while still allowing a specific Handler to apply its own logic to whether it can handle the request or not such as checking sessionAttributes or Context.

To handle this abstraction, I implemented an abstract class to implement the default CanHandle:

GenericHandler.cs

public abstract class GenericHandler : IHandler
{
    public abstract string IntentName { get; }
    public abstract Type RequestType { get; }
    public abstract Task<SkillResponse> HandleAsync(SkillRequest request);
    public virtual bool CanHandle(SkillRequest request)
    {
        if (request.GetRequestType() != RequestType)
            return false;
        if(request.GetRequestType() == typeof(IntentRequest))
        {
            if ((request?.Request as IntentRequest)?.Intent?.Name != IntentName)
                return false;
        }
        return true;
    }
}

If you are using C# 8 (I’m not in this case because its in preview at time of writing this), you can just use the Default Interface Implementation feature instead of using this extra abstract class at all. So your IHandler would look like this:

IHandler.cs

public interface IHandler
{
    Type RequestType { get; }
    string IntentName { get; }
    Task<SkillResponse> HandleAsync(SkillRequest request);
    bool CanHandle(SkillRequest request)
    {
        if (request.GetRequestType() != RequestType)
            return false;
        if(request.GetRequestType() == typeof(IntentRequest))
        {
            if ((request?.Request as IntentRequest)?.Intent?.Name != IntentName)
                return false;
        }
        return true;
    }
}

The last bit is the actual HandleAsync() which is just used to actually process the request and build a response to send back to Alexa.

So let’s look at a real implementation with the most simple example I can think of.

SimpleLaunchHandler.cs

public class SimpleLaunchHandler : GenericHandler, IHandler
{
    public override string IntentName => null;

    public override Type RequestType => typeof(LaunchRequest);

    public override Task<SkillResponse> HandleAsync(SkillRequest request)
    {
        return Task.FromResult(ResponseBuilder.Ask("Welcome to abstracted .NET Alexa Skills. How can I help?", null));
    }
}

Request type of LaunchRequest because we are handling the welcome message of the skill. We don’t override the CanHandle because we only care about the RequestType, and then the HandleAsync just returns a result task with a simple text-only response welcoming the user.

Here’s an example of a basic Intent Handler for a specific intent:

DogFactHandler.cs

public class DogFactHandler : GenericHandler, IHandler
{
    public override string IntentName => "DogFactIntent";

    public override Type RequestType => typeof(IntentRequest);

    public override Task<SkillResponse> HandleAsync(SkillRequest request)
    {
        return Task.FromResult(ResponseBuilder.Tell("Dogs do in fact have a sense of time, and even miss you when you're gone."));
    }
}

Just like the SimpleLaunchHandler, we set the RequestType but instead to IntentRequest, then supply the name of the Intent we want to handle.

Find and Execute Handlers

Now that we have some implementations of IHandlers, we can register them to use in our actual skill. The general idea is to create the collection of these handlers, then find the correct one to use given the type of request and execute it.

In it’s simplest form, we have a collection of handlers:

var handlers = new List<IHandler> { new SimpleLaunchHandler(), new DogFactHandler() };

Then find the right one to use:

var foundHandler = handlers.FirstOrDefault(h => h.CanHandle());

Then execute it:

var response = await foundHandler.HandleAsync(request);

Implement in ASP.NET Core

Let’s take a look at a real sample of how to do this using ASP.NET Core as if we were using HTTPS as our fulfillment URL of our skill rather than an AWS Lambda ARN.

First thing we should do is register our IHandlers for dependency injection in our Startup:

Startup.cs

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        // Register your handlers here!
        services.AddScoped<ICollection<IHandler>>(s =>
        {
            return new List<IHandler>
            {
                new SimpleLaunchHandler(),
                new DogFactHandler()
            };
        });

        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
            app.UseDeveloperExceptionPage();
        else
            app.UseHsts();

        app.UseHttpsRedirection();
        app.UseMvc();
    }
}

Now we can create a Controller that consumes an ICollection in the constructor. Alternatively, you can also register the IHandlers independently and then build the collection in the constructor of the Controller instead, but I kinda like this way better.

SimpleAlexaController.cs

[Route("[controller]")]
public class SimpleAlexaController : Controller
{
    private readonly ICollection<IHandler> _handlers;
    public SimpleAlexaController(ICollection<IHandler> handlers)
    {
        _handlers = handlers;
    }
    [HttpPost]
    public async Task<SkillResponse> HandleRequest([FromBody]SkillRequest request)
    {
        var viableHandler = _handlers.FirstOrDefault(h => h.CanHandle(request));
        return await viableHandler.HandleAsync(request);
    }
}

And that’s it! Now we can send requests to our /SimpleAlexa/ endpoint and use the handlers we registered. As we add more functionality to our Skill, we just create new IHandlers and add them to the Startup registration.

Implement in Lambda

So you might already know that Lambda functions don’t really play well with dependency injection outside of building a simple service locator, and their recommended practice is to build your code all in the lambda (yucky for us C# devs) or build your depdendent classes all at the beginning of executing the function. For this scenario, I like to have a single method for building my primary dependency (in this case, it’s the list of handlers again!). So our full Lambda Function code might looke like this:

Function.cs

public class Function 
{
    public async Task FunctionHandler(SkillRequest request, ILambdaContext context)
    {
        var viableHandler = BuildHandlers().FirstOrDefault(h => h.CanHandle(request));
        return await viableHandler.HandleAsync(request);
    }

    private ICollection<IHandler> BuildHandlers()
    {
        return new List<IHandler> { new SimpleLaunchHandler(), new DogFactHandler() };
    }
}

What’s next?

This is a pretty neat design pattern I’ve been working out in some custom Alexa Skills to help scale the codebase of more complex scenarios. These samples are quite simple, but hopefully convey how easy it is to get setup with this pattern, and start to get you thinking about ways to build ontop of this pattern.

In future posts, we’ll take a look at building on these types of handlers with things like:

  • Well written Unit Tests
  • Full Integration Tests
  • Using Entity Framework
  • Using multi-level dependency injection
  • Advanced Contextual driven handlers

If there’s enough interest in this pattern and the tools I’m building around it, let me know in GitHub or Twitter and I’ll work on getting them into properly libraries and NuGet packages 🙂

Check out more Alexa Developer Tips here: https://alexdunn.org/tag/alexa/


If you like what you see, don’t forget to follow me on twitter @Suave_Pirate, check out my GitHub, and subscribe to my blog to learn more mobile and AI developer tips and tricks!

Interested in sponsoring developer content? Message @Suave_Pirate on twitter for details.


voicify_logo
I’m the Director and Principal Architect over at Voicify. Learn how you can use the Voice Experience Platform to bring your brand into the world of voice on Alexa, Google Assistant, Cortana, chat bots, and more: https://voicify.com/


Alexa.Tip – Build Intent Handlers in .NET

In this Alexa.Tip series, we explore some little bits of code that can make your life easier in developing Alexa Skills in many languages including C# + .NET, node.jS + TypeScript, Kotlin, etc. We look at concepts that developers might not be aware of, design patterns that and how they can be applied to voice application development, best practices, and more!

In this post, we explore some more best practices in developing Alexa Skills in C# whether you are using an ASP.NET Core API or an AWS Lambda. This time, we talk about abstracting our business logic out of either our Function or Controller and into separate Handler classes.

If you’ve done skill development in node.js or in .NET, you’ve probably noticed that a lot of docs, example apps, and real world apps are written with one BIG class or file. That’s pretty gross.

You may some C# examples look like this:

UglyFunction.cs

public class Function
{
    public async Task<SkillResponse> HandleRequest(SkillRequest input)
    {
        if(input.GetRequestType() == typeof(LaunchRequest))
        {
            return ResponseBuilder.Ask("Welcome to my skill written in one big function class with all my business logic in one place and no real testability! Ask me anything!", null);
        }

        if(input.GetRequestType() == typeof(IntentRequest))
        {
            var intentRequest = input.Request as IntentRequest;

            switch(intentRequest.Intent.Name)
            {
                case "MyIntent1":
                    // get slot values
                    // search database
                    // validate data
                    // build response 
                    // add card if it supports a screen
                    // return
                    break;
                case "Intent2":
                    // get slot values
                    // search third party api
                    // validate data
                    // build response 
                    // add card if it supports a screen
                    // return
                    break;
                case "Intent3":
                    // get slot values
                    // search database
                    // validate data
                    // build response 
                    // add card if it supports a screen
                    // return
                    break;
                case "Intent4":
                    // get slot values
                    // search third party api
                    // validate data
                    // build response 
                    // add card if it supports a screen
                    // return
                    break;
                case "Intent5":
                    // get slot values
                    // search database
                    // validate data
                    // build response 
                    // add card if it supports a screen
                    // return
                    break;

                // I think you get my point here...
            }
        }

        return ResponseBuilder.Tell("Something went wrong. Please try again later");
    }
}

So that’s pretty gross right? It’s untestable, difficult to update, and hard to read! But hey, we’re C# developers. So let’s build Alexa Skills like C# developers.

The proposal here is to abstract your intent logic into Handler classes. Then you can inject those either into your Function or your Controller if you’re using a RESTful API.

Here’s something that I hope can get you started:
– A generic IIntentHandler
– An inherited specific IIntentWhateverHandler
– An implementation of the IIntentWhateverHandler
– A testable and injectable version to be used in the function.

Let’s start.

IIntentHandler.cs

public interface IIntentHandler
{
    Task<SkillResponse> HandleIntent(IntentRequest input);
}

Now let’s get specific. In this simple case, this interface is empty but exists for registration – although you can add specific methods here as needed.

IMyIntentHandler.cs

public interface IMyIntentHandler : IIntentHandler
{
}

Now let’s create an example implementation of an intent handler that houses the business logic of the request.

MyIntentHandler.cs

public class MyIntentHandler : IMyIntentHandler
{
    private readonly MyDbContext _context;
    public MyIntentHandler(MyDbContext context)
    {
        // oh snap, we can inject db context
        _context = context;
    }

    public async Task<SkillResponse> HandleIntent(IntentRequest input)
    {
        var mySlot = input.Slots["MySlot"].Value; // assumes the slot is there from it being required in the interaction model
        var myMessage = await _context.Messages.FirstOrDefaultAsync(m => m.SomeValue == mySlot)

        if(myMessage == null)
        {
            return ResponseBuilder.Ask("I don't know that one. Try something else.");
        }

        return ResponseBuilder.Tell(myMessage.Content);
    }
}

Now let’s go about adding these handlers to our Function (the same thing can apply to our Controllers.

PrettyFunction.cs

public class Function
{
    private readonly IMyIntentHandler _myIntentHandler;

    private void Setup()
    {
        _myIntentHandler = new MyIntentHandler(...);
        // create the others - optionally implement a ServiceCollection
        // to handle proper dependency injection
    }
    public async Task<SkillResponse> HandleRequest(SkillRequest input)
    {
        if(input.GetRequestType() == typeof(LaunchRequest))
        {
            return ResponseBuilder.Ask("Welcome to my skill written in one big function class with all my business logic in one place and no real testability! Ask me anything!", null);
        }

        if(input.GetRequestType() == typeof(IntentRequest))
        {
            var intentRequest = input.Request as IntentRequest;

            switch(intentRequest.Intent.Name)
            {
                case "MyIntent1":
                    return await _myIntentHandler.HandleIntent(intentRequest);
                    break;
            }
        }

        return ResponseBuilder.Tell("Something went wrong. Please try again later");
    }
}

So now you can separately test your Handler classes, your Data classes, and your Function as a whole.

SO much better 🙂

Conclusion

We don’t have to follow how Amazon writes their node.js skills when we write them in C# – let’s use some proper OO design and testability to build some scalable and awesome skills!

In the next post, we’ll talk about taking this one step closer to avoid that gross switch statement and simply register our Handler implementations for certain intents or RequestTypes which is more similar to how the actual ASK SDK works.

Stay tuned!


If you like what you see, don’t forget to follow me on twitter @Suave_Pirate, check out my GitHub, and subscribe to my blog to learn more mobile and AI developer tips and tricks!

Interested in sponsoring developer content? Message @Suave_Pirate on twitter for details.


voicify_logo
I’m the Director and Principal Architect over at Voicify. Learn how you can use the Voice Experience Platform to bring your brand into the world of voice on Alexa, Google Assistant, Cortana, chat bots, and more: https://voicify.com/


Alexa.Tip – Access Lambda Environment Variables in .NET

In this Alexa.Tip series, we explore some little bits of code that can make your life easier in developing Alexa Skills in many languages including C# + .NET, node.jS + TypeScript, Kotlin, etc. We look at concepts that developers might not be aware of, design patterns that and how they can be applied to voice application development, best practices, and more!

In this post, we’ll look at a simple tip to help secure your Alexa Skills when using an AWS Lambda. In a future post, we’ll look at a similar concept in .NET for developers using ASP.NET Core Web API instead of Lambdas.

So, you’ve taken the step to building proper data-driven Alexa Skills and have stepped out of the simple “todo” examples. Perhaps you need a database connection in your source code, need to change values depending on what environment you are running the skill in, or want to run your skill with options you can change without having to redeploy the codebase over and over again.

For all of these problems, your best bet is to use the Lambda Environment variables. Doing it is INCREDIBLY simple, yet I still see many developers unaware of how to use them and instead use runtime checks or don’t bother scaling their application at all to needing them.

In this example, we’ll look at how to create an instance of an Entity Framework DbContext and set it up for a testable injection based project.

Let’s look at a code snipet example of a piece of an Alexa Skill running in a .NET Lambda using a hard coded connection string:

Message.cs

// a simple table to represent some messages we can grab
public class Message
{
    public int Id { get; set; }
    public string Content { get; set; }
}

And here’s our DbContext we are going to grab data from:
MessageDbContext.cs

public class MessageDbContext : DbContext 
{
    public DbSet<Message> Messages { get; set; }

    public MessageDbContext(DbContextOptions options) : base(options) { }
}

Now check out a lambda I typically see with hard coded connection strings and settings:

BadLambda.cs

public class BadLambda
{
    // an EF DbContext with some message tables
    private readonly MessageDbContext _context;

    public BadLambda()
    {
        var optionsBuilder = new DbOptionsBuilder<MessageDbContext>()
            .UseSqlServer("my_connection_string", providerOptions => providerOptions.CommandTimeout(60));
        _context = new MessageDbContext(optionsBuilder.options);
    }

    public async Task<SkillResponse>(SkillRequest input)
    {
        var message = await _context.Messages.FirstOrDefaultAsync();
        return ResponseBuilder.Tell(message.Content);
    }
}

So breaking down the code… We have an EF DbContext with one table called “Messages” which has a column of Id and Content, and our Skill Lambda sets up the DbContext with a hard coded connection string and timeout setting, then returns the first messages as a simple response.

Let’s take this lambda and add environment variables so we can run mutliple environments for multiple dbs including a localhost db if we wanted to test locally before deploying to Lambda and so we can test updates before we make changes to our production skill!

In AWS

Head over to your lambda in AWS and scroll down to “Environment Variables”:
Labmda_env

Here you can add any key-value pairs you want. For this demo, we want to put our database connection string and our timeout setting here:

Lambda_env_filled

Now make sure you smash that save button and head back to Visual Studio to make our final updates!

Don’t forget you can now also create another lambda for a development or staging environment separate from your production lambda – be sure to use a different database connection in your environment variables, and then you can publish to both 😀

In the Code

Now we just have to use the

Environment.GetEnvironmentVariable(string key);

method to grab the values of these environment variables we set up and we’re off to the races!

Here’s what that looks like when updates:

GoodLambda.cs

public class GoodLambda
{
    // an EF DbContext with some message tables
    private readonly MessageDbContext _context;

    public GoodLambda()
    {
        var connectionString = Environment.GetEnvironmentVariable("DatabaseConnectionString");
        var timeoutSetting = Environment.GetEnvironmentVariable("DatabaseCommandTimeout");
        var optionsBuilder = new DbOptionsBuilder<MessageDbContext>()
            .UseSqlServer(connectionString, providerOptions => providerOptions.CommandTimeout(int.Parse(timeoutSetting)));
        _context = new MessageDbContext(optionsBuilder.options);
    }

    public async Task<SkillResponse>(SkillRequest input)
    {
        var message = await _context.Messages.FirstOrDefaultAsync();
        return ResponseBuilder.Tell(message.Content);
    }
}

Now publish it to your lambda and you’re done!

Recap

  • For the love of god, stop hard coding connection strings and settings in your lambda
  • Use environment variables
  • Setup multiple environments for scalability and testability
  • Abuse Environment.GetEnvironmentVariable()
  • Build more Alexa Skill 🙂

If you like what you see, don’t forget to follow me on twitter @Suave_Pirate, check out my GitHub, and subscribe to my blog to learn more mobile and AI developer tips and tricks!

Interested in sponsoring developer content? Message @Suave_Pirate on twitter for details.


voicify_logo
I’m the Director and Principal Architect over at Voicify. Learn how you can use the Voice Experience Platform to bring your brand into the world of voice on Alexa, Google Assistant, Cortana, chat bots, and more: https://voicify.com/


Alexa.Tip – How to Host Alexa Skills in Azure

If you’re a .NET developer in the Azure cloud sphere and want to start dabbling in Alexa Skill Development, you don’t have to uproot your entire career and development process to go learn AWS, how Lambdas work, the serverless lifecycle, etc. In this post, we’ll go over just how easy it can be to build an Alexa Skill using C#, ASP.NET Core, and Azure!

The traditional setup for Alexa Skills is:
– AWS Lambda
– .NET Core Lambda project template

But we’re going to be using:
– Azure App Services
– ASP.NET Core API project template

NOTE: This is not an introduction into how Alexa skills work, or how to create your very first skill. This is meant to provide options for hosting your skills, and for how to build skills in general using .NET. If you’re BRAND new to Alexa Skill development, start by reading through their documentation (mostly using node.js, but focus on the structure of an interaction model, what intents and slots are, etc.)

For source of the entire project checkout: https://github.com/SuavePirate/Alexa.NET.WebApi

Step 1 – Create an Alexa Developer Account

If you haven’t already created an Alexa Developer account, you’ll need one in order to register and test your skill.

Simply follow, the Amazon documentation on how to do this – super simple: https://developer.amazon.com/alexa

Step 2 – Create a Skill in the Developer Console

With your Alexa developer account, create a new Skill.

Choose Custom Skill:

create_skill

Then choose the empty “Start from Scratch” template:

choose_template

Now you can manage your interaction model.

For this example, we are going to create a skill that let’s users ask for information about Animals. We’ll use a custom Intent for this, but use the built in AMAZON.Animal slot.

On the left side, go to JSON Editor and paste this interaction model. You can make adjustments as you see fit:

interactionModel.json

{
  "interactionModel": {
    "languageModel": {
      "invocationName": "animal facts",
      "intents": [
        {
          "name": "AMAZON.FallbackIntent",
          "samples": []
        },
        {
          "name": "AMAZON.CancelIntent",
          "samples": [
            "I'm all set"
          ]
        },
        {
          "name": "AMAZON.HelpIntent",
          "samples": []
        },
        {
          "name": "AMAZON.StopIntent",
          "samples": [
            "Quit",
            "Goodbye"
          ]
        },
        {
          "name": "AnimalFactIntent",
          "slots": [
            {
              "name": "Animal",
              "type": "AMAZON.Animal"
            }
          ],
          "samples": [
            "I'd like to know about {Animal}",
            "What is an {Animal}",
            "Give me information about the {Animal}",
            "Tell me about {Animal}"
          ]
        }
      ],
      "types": []
    }
  }
}

This allows our users to ask things such as “Tell me about Monkeys” and then use the animal they are asking for to send information back to them!

Step 3 – Create the ASP.NET Core API

In Visual Studio, create a new project and choose the ASP.NET Core Web Application:

aspnetcore

In the next dialog, select the API template, and be sure that HTTPS is enabled:

API_project_with_https

With your new web application, you’ll need to install the Alexa.NET Nuget Package from Tim Heuer
https://www.nuget.org/packages/Alexa.NET/1.5.5-pre

This nuget package has models for the JSON that Alexa sends to your API and a convenient fluid API design for building your responses that is similar to how the actual Alexa Java and JavaScript SDKs work.

Now that the Alexa models are available, let’s create a new API controller:

AlexaController.cs

[Route("api/[controller]")]
public class AlexaController : Controller
{
    /// <summary>
    /// This is the entry point for the Alexa skill
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpPost]
    public SkillResponse HandleResponse([FromBody]SkillRequest input)
    {
        var requestType = input.GetRequestType();

        // return a welcome message
        if(requestType == typeof(LaunchRequest))
        {
            return ResponseBuilder.Ask("Welcome to animal facts, ask me about information on an animal", null);
        }

        // return information from an intent
        else if (requestType == typeof(IntentRequest))
        {
            // do some intent-based stuff
            var intentRequest = input.Request as IntentRequest;

            // check the name to determine what you should do
            if (intentRequest.Intent.Name.Equals("AnimalFactIntent"))
            {
                // get the slots
                var animal = intentRequest.Intent.Slots["Animal"].Value;
                if(animal == null)
                    return ResponseBuilder.Ask("You forgot to ask about an animal! Please try again.", null);

                return ResponseBuilder.Tell($"I would normally tell you facts about ${animal} but I'm not a real skill yet.");
            }
        }

        return ResponseBuilder.Ask("I didn't understand that, please try again!", null);
    }
}

This controller contains a single HTTP POST endpoint that takes in an SkillRequest. It then breaks down the request in order to respond accordingly. So if the user opens the skill which initiates the LaunchRequest, we can give them a welcome message with hints on what they can ask about. Then if they ask for information about an animal, we can handle the IntentRequest with the intent name of “AnimalFactIntent” and use the Animal slot value!

That’s all there is too it! I’d normally suggest abstracting this out of using the controller so that it is more easily testable with unit tests, but for the sake of a simple example, it will work fine.

Step 4 – Publish to Azure App Service

Now that we have our ASP.NET Core project, we need to publish it to an Azure App Service. You can do this directly in Visual Studio or in the Azure portal. For the sake of this example, we’ll do it directly in Visual Studio – assuming you have a valid Azure license and account setup.

From the Solution Explorer – right click your project and Select “Publish”.

Select the “App Service” option and click “Create”.

Then fill out the form to create a new App Service:
AzurePublish

Once your publish is done, you’ll need to ensure that HTTPS / SSL is configured correctly for your app service.

In the Azure portal, go to your new App Service, then scroll to the SSL Settings section.

Be sure that you enforce SSL (Alexa requires endpoints to use HTTPS with trusted certificates. The default App Service SSL cert is signed with Microsoft’s trusted certificate which means that Amazon will accept it).

azure_ssl.PNG

Now make sure that you can hit your App service API endpoint. I usually prefer to enable Swagger for my API using Swashbuckle for this: https://docs.microsoft.com/en-us/aspnet/core/tutorials/getting-started-with-swashbuckle?view=aspnetcore-2.1&tabs=visual-studio%2Cvisual-studio-xml

Step 5 – Register Endpoint with Alexa Skill

Now that we have our App Service with HTTPS set up, we need to go back to the Alexa Developer Console and to the skill. In the left menu, scroll down to the “Endpoint” option.

In the main view, select “HTTPS” instead of “AWS Lambda ARN”. Then enter the URL for the endpoint in your app service and choose the subdomain ssl cert option:
azure_alexa_endpoint

Once this is done, you can save, and build your skill then proceed to test it!

Step 6 – Test

In the Alexa Developer Console, go to your skill and select the “Test” tab. Here you can type or say things like “Open Animal Facts” or “Ask Animal Facts to tell me about Monkeys”.

animal skill test

Here you can also view the JSON that Alexa is sending to your skill and use that to test against your skill directly using something like Swagger or Postman.

Here’s an example JSON input you could use to test:

{
    "version": "1.0",
    "session": {
        "new": false,
        "sessionId": "...",
        "application": {
            "applicationId": "..."
        },
        "user": {
            "userId": "..."
        }
    },
    "context": {
        "AudioPlayer": {
            "playerActivity": "IDLE"
        },
        "Display": {
            "token": ""
        },
        "System": {
            "application": {
                "applicationId": "..."
            },
            "user": {
                "userId": "..."
            },
            "device": {
                "deviceId": "...",
                "supportedInterfaces": {
                    "AudioPlayer": {},
                    "Display": {
                        "templateVersion": "1.0",
                        "markupVersion": "1.0"
                    }
                }
            },
            "apiEndpoint": "https://api.amazonalexa.com",
            "apiAccessToken": "..."
        }
    },
    "request": {
        "type": "IntentRequest",
        "requestId": "...",
        "timestamp": "2018-09-04T17:07:45Z",
        "locale": "en-US",
        "intent": {
            "name": "AnimalFactIntent",
            "confirmationStatus": "NONE",
            "slots": {
                "Animal": {
                    "name": "Animal",
                    "value": "monkeys",
                    "confirmationStatus": "NONE"
                }
            }
        }
    }
}

You can also test on a real Alexa device! Once you enabled testing, any device that is assigned to the same email address as your Alexa Developer Account will have it enabled.

And that’s it! Now get out there and build some Alexa Skills in .NET!


If you like what you see, don’t forget to follow me on twitter @Suave_Pirate, check out my GitHub, and subscribe to my blog to learn more mobile and AI developer tips and tricks!

Interested in sponsoring developer content? Message @Suave_Pirate on twitter for details.


voicify_logo
I’m the Director and Principal Architect over at Voicify. Learn how you can use the Voice Experience Platform to bring your brand into the world of voice on Alexa, Google Assistant, Cortana, chat bots, and more: https://voicify.com/


Xamarin.Meetup – Boston Meetup Today: DevOps for Mobile Apps with Dan Hermes

Join us at Microsoft’s NERD Center to learn about DevOps for Mobile Apps! Meet with some of the local Xamarin MVPs and employees while also enjoying some food.

https://www.meetup.com/bostonmobiledev/events/244933704/

How do we keep our iOS and Android builds organized, tested, and distributed to team members and users who need them, with the correct versions flowing into the app stores? This is DevOps for mobile apps.

Dan Hermes, Xamarin MVP and co-organizer of Boston Mobile C# Developers Group, will discuss the high points of his upcoming edX video course for Microsoft on how to do all of these things using Visual Studio Mobile Center (VSMC). He will talk about developing, deploying and managing mobile applications in DevOps environments. He’ll cover setup and management of VSMC and the testing and deployment of mobile apps. Mobile Center Build, Test, and Distribute are powered by Visual Studio Team System (VSTS), Xamarin Test Cloud, and HockeyApp.  Learn the VSMC workflows that tie all of these tools together.

This talk is for any and all native app developers, not just C#.  Many features of VSMC work for Objective-C and Java just as well as Xamarin.

About the Speaker

Dan Hermes is a Xamarin MVP,  Microsoft MVP, and founder of Lexicon Systems, an award-winning Xamarin consulting firm. Mr. Hermes helps developers create great mobile apps and helps businesses develop a winning mobile strategy. His firm’s Xamarin projects include B4UFLY, a drone app for the Federal Aviation Administration, and a cross-platform app for Thermo Fisher Scientific which won a W3, a Davey award, and was a finalist for a Xammy award. Mr. Hermes’ clientele includes dozens of software-building firms such as Fidelity Investments, EDS, and Computerworld Magazine. He has spoken recently at Microsoft Ignite, IBM InterConnect, Microsoft Azure Day, Xamarin DevDays, and mobile user groups nationwide . His mobile cross-platform dev blog is http://mobilecsharpcafe.com/. Connect with him on Twitter at @danhermes. Dan is a writer for MSDN Magazine, a video course instructor for Microsoft’s OpenEdX curriculum, and author of the best-selling Apress book Xamarin Mobile Application Development.

 

 

If you like what you see, don’t forget to follow me on twitter @Suave_Pirate, check out my GitHub, and subscribe to my blog to learn more mobile developer tips and tricks!

Interested in sponsoring developer content? Message @Suave_Pirate on twitter for details.

Xamarin.Meetup – Boston Meetup Today: Xamarin on Azure and Cognitive Services

Join us at Microsoft’s NERD Center to learn about using Azure Cognitive Services in your Xamarin apps! Meet with some of the local Xamarin MVPs and employees while also enjoying some food.

https://www.meetup.com/bostonmobiledev/events/242566795/

Xamarin on Azure and Cognitive Services

Mobile development and cloud technologies are very popular right now. If you are a C# developer and already created your first application with Xamarin, you might be interested in learning some more details about Xamarin and Xamarin Forms. You might also want to use all benefits of Azure in your application or jump right into advanced topics and select one (or a couple) Cognitive Services for your application to integrate with. You will be able to get a flavor of all those tools from this talk. Also final demo will add some visual understanding of the topic.

About the speaker

Veronika Kolesnikova is a web developer at UMass Medical School.

Passionate about backend web development, mainly with Microsoft technologies like C#, .NET, SQL, Azure. Loves to learn new development tools and languages and share the knowledge with the community. Recently started working with Xamarin and cannot wait to provide her insights.
Last year Veronika graduated with MS degree in Information Technology.
In her free time, she likes dancing, traveling and practicing aerial yoga.

 

If you like what you see, don’t forget to follow me on twitter @Suave_Pirate, check out my GitHub, and subscribe to my blog to learn more mobile developer tips and tricks!

Interested in sponsoring developer content? Message @Suave_Pirate on twitter for details.