New Exam! AWS Certified Alexa Skill Builder – Specialty Exam

Earlier this summer, myself along with other Alexa Skill Subject Matter Experts (including Voicify CTO, Nick Laidlaw) joined Amazon to help create the new Certification Exam for Alexa Skill Builders.

We put in a lot of work over some intense workshops to develop and iterate on exam-worth questions and continue to work with the team at Amazon to determine the standard of grading the exam.

But the exam is now in a public beta! Take it now and let me know what you think.

AWS Certified Alexa Skill Builder – Specialty Beta Exam: https://aws.amazon.com/certification/beta-exam/

Taking the exam in beta form allows for strengthening the exam and the certification as well as future AWS specialty exams.

Other Exams from Alex

If you just LOVE exams and can’t get enough of the ones I help work on – be sure to take my Pluralsight Skill IQ Assessments. Read about them here: New Pluralsight Android Skill IQ Tests

Coming Soon to Blog Posts Near You

Side note for my more avid blog followers – apologies for the slow rollouts – I’ve been doing quite a bit of travelling and extra work the first quarter of 2019 but I have some great drafts in the works that will come around including work around:

  • ASP.NET Core
  • Xamarin
  • Kotlin
  • AWS Resources
  • Alexa
  • Google Assistant
  • Cortana
  • Bixby?
  • More 🙂

So stay tuned and thanks for your patience! I’m working on making more supportable and robust posts and OSS projects around them so there is a bit of upfront work as well but it will be worth it! 😀


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.

Advertisements

Seed Your Entity Framework Core Data at Startup with ASP.NET Core 2

If you’re developing large scale database designs using Entity Framework, especially with Code First Migrations, you’ve likely wanted to seed some data. Perhaps it’s some constant lookup values or test data used in your local dev environments for on-boarding new team members. It’s also nice to run migrations on startup for when you are deploying to different environments!

This blog post is just a simple set of tools I commonly use to allow for automatically running migrations and seeding some data with some examples.

Basically we’ll:

  • Design a Code First Database with EF Core
  • Add a migration
  • Build two different Seeder classes
  • Build an extension method to run Migrations and the Seeders when the application starts

This doesn’t care about how you actually setup your DbContext within your app, what database provider you use, etc.

Database Design

Let’s go with a simple example of a Blog website database design. Let’s first add some POCOs for out entities then create our DbContext.

Post.cs

public class Post 
{
    public long Id { get; set; }
    public string Title { get; set;}
    public string Content { get; set; }
    public string PostTypeId { get; set; }
    public virtual PostType PostType { get; set; }
}

PostType.cs

public class PostType
{
    public long Id { get; set; }
    public string Name { get; set; }
    public virtual ICollection<Post> Posts { get; set; }
}

BlogContext.cs

public class BlogContext : DbContext 
{
    public DbSet<Post> Posts { get; set; }
    public DbSet<PostType> PostTypes { get; set; }
}

Add Migration

Now that we have a DbContext and our tables, let’s create our migration!

In the Visual Studio Package Manager Console:

add-migration InitialCreate

or in the CLI:

dotnet ef migrations add InitialCreate

Building Seeder Classes

Now we have a database designed and a migration, so let’s create a seeder for creating some PostTypes that should be the same for every environment and then another TestDataSeeder to seed some examples for developers to use when running the app for the first time.

PostTypesSeeder

public class PostTypesSeeder
{
    private readonly BlogContext _context;
    public PostTypesSeeder(BlogContext context)
    {
        _context = context;
    }

    public void SeedData()
    {
        AddNewType(new PostType { Id = 0, Name = "Standard" });
        AddNewType(new PostType { Id = 1, Name = "Aside" });
        AddNewType(new PostType { Id = 2, Name = "Snippet" });
        _context.SaveChanges();
    }

    // since we run this seeder when the app starts
    // we should avoid adding duplicates, so check first
    // then add
    private void AddNewType(PostType postType)
    {
        var existingType = _context.PostTypes.FirstOrDefault(p => p.Name == postType.Name);
        if(existingType == null)
        {
            _context.PostTypes.Add(postType);
        }
    }
}

This seeder let’s us add 3 different PostTypes if they don’t already exist.

TestDataSeeder.cs

public class TestDataSeeder
{
    private readonly BlogContext _context;
    public TestDataSeeder(BlogContext context)
    {
        _context = context;
    }

    public void SeedData()
    {
        _context.Posts.Add(new Post
        {
            Name = "Test Post 1",
            Content = "This is my standard post for testing",
            PostTypeId = 0
        };
        _context.Posts.Add(new Post
        {
            Name = "Test Post 2",
            Content = "This is my aside post for testing",
            PostTypeId = 2
        };

        _context.SaveChanges();
    }
}

Building the WebHost Extension

Now that we have our seeders. Let’s build that extension method for running the migration and running this seeders.

WebHostExtensions.cs

public static class WebHostExtensions
{
    public static IWebHost SeedData(this IWebHost host)
    {
        using (var scope = host.Services.CreateScope())
        {
            var services = scope.ServiceProvider;
            var context = services.GetService<BlogContext>();

            // now we have the DbContext. Run migrations
            context.Database.Migrate();

            // now that the database is up to date. Let's seed
            new PostTypesSeeder(context).SeedData();

#if DEBUG
            // if we are debugging, then let's run the test data seeder
            // alternatively, check against the environment to run this seeder
            new TestDataSeeder(context).SeedData();
#endif
        }
    }
}

Implementing the Extension

Now that we have our database and entities, seeders, and an extension method – let’s just drop it in our Program class to run when we are creating the WebHost!

Program.cs

public class Program
{
    public static void Main(string[] args)
    {
        CreateWebHostBuilder(args).Build().SeedData().Run();
    }

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseStartup<Startup>();

}

Note: although this Program is in the ASP.NET Core 2.1 style, the same code works in the original 2.0 style. Just stick it after the Build() call wherever you run that.

And that’s it! Now we have always-up-to-date data whenever we run our ASP.NET Core app! 😀


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.

New Pluralsight Android Skill IQ Tests

I recently worked with Pluralsight (pluralsight.com) to help produce 2 brand spankin’ new Skill IQ Tests! Test your skills and knowledge of Android development, Android Studio, Kotlin and more!

Android Tooling Skill Assessment

The first is Android Tooling! You can test your knowledge of:

  • Android Studio – Analyze
  • Android Studio – Basics
  • Android Studio – Build
  • Android Studio – Code Manipulation
  • Android Studio – File Structure
  • Android Studio – Run
  • Android Studio – Settings
  • Android Studio – Tools
  • Android Studio – Version Control
  • Gradle

Although this exam is still in Beta (as of writing this post), you can still take the exam and I encourage you to as well! Pluralsight does some really cool work to calibrate the curve of the skill assessment so give it a go and let me know how you do 🙂

Take it here: https://app.pluralsight.com/score/skill-assessment/android-tooling/intro#/v2/landing 


Kotlin: Enhancing App Experience

The second skill assessment is for you Kotlin lovers like me and dives into some deeper knowledge of building better Android apps with Kotlin!

Kotlin is an open-source JVM language created by JetBrains. It is one of the most popular languages used in Android development.

The assessment may cover:

  • Activities
  • Enhanced System Integration
  • Threading and Background Work
  • User Interface and Experience

This assessment is also still in Beta, but be sure to try this one out and see if your Kotlin skills are up to snuff.

Check Out My Course!

Oh wow how topical and convenient! Be sure to check out my course on Building Android Apps with Kotlin: Getting Started to learn a lot about the fundamentals of both the Kotlin language and Android development as a whole! I assure it will help drive that Skill IQ Up for both of these assessments 🙂 

https://app.pluralsight.com/library/courses/building-android-apps-kotlin-getting-started 

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.Tip – Build Your Own In-App Developer Options

This post is a continuation of building gesture based “easter eggs” into your Xamarin apps (native or Forms).

In this post, we are going to continue from these posts:
Xamarin.Tip – Add Easter Eggs to UWP with Key Combos
Xamarin.Tip – Add Easter Eggs on Shake

to talk about how we can use these gestures in Debug mode to give ourselves some shortcuts for testing and moving through our application quicker.

To breakdown the process setup – we added shake handlers (and keyboard shortcuts for UWP) that can invoke any contextual code in our application. We talked about using this for funny easter eggs, but this functionality can be made into something super useful for us.

I call this “Contextual Developer Options”. The idea is take that easter egg handler and use it to display some contextual options that can be controlled page by page or view by view. This can be toggling some UI updates, auto-navigating through the app, testing different scenarios, etc.

In this example we’ll be using MVVM and Xamarin.Forms to demonstrate the possibilities, but the same idea can be applied to any other pattern or practice. Basically we need to:

  • Register dev options to whatever context we want
  • Determine what context we are in
  • Display the actionable dev options

Before starting, I suggest looking at something like Allan Ritchie’s incredibly useful UserDialogs package https://github.com/aritchie/userdialogs

We’ll use it in our examples.

Setting Up Developer Options

First things first, let’s define our developer options.

DevelopmentOption.cs

public class DevelopmentOption
{
    public string Title { get; set; }
    public Action Action { get; set; }
}

Now, like I said, our example will be doing this in MVVM and we can use the current page the user is on as the context we want to apply.

I’ll start by creating a BasePageViewModel that we can use to set up our developer options and execute the action

BasePageViewModel.cs

public abstract class BasePageViewModel : ViewModelBase
{
    protected List<DevelopmentOption> _developerOptions;
    private bool _isShowingDeveloperOptions = false;

    public BasePageViewModel()
    {
        _developerOptions = new List<DevelopmentOptions>();
    }

    /// <summary>
    /// Shows the developer options. This should be called after a native easter egg such as a shake.
    /// </summary>
    public virtual async Task ShowDeveloperOptionsAsync()
    {
        if (_developerOptions.Any() && !_isShowingDeveloperOptions)
        {
            var titles = _developerOptions.Select(d => d.Title);
            _isShowingDeveloperOptions = true;
            var actionResult = await UserDialogs.Instance.ActionSheetAsync("Developer Options", "Cancel", null, null, titles.ToArray());
            _isShowingDeveloperOptions = false;
            // see if an option was selected
            if (titles.Contains(actionResult))
            {
                // call it if we find it.
                var option = _developerOptions.FirstOrDefault(d => d.Title == actionResult);
                option?.Action();
            }
        }
    }

    /// <summary>
    /// Sets up the developer options.
    /// </summary>
    protected virtual void SetupDeveloperOptions()
    {
        _developerOptions.Add(new DevelopmentOption()
        {
            Title = "Go to debug page",
            Action = () => UserDialogs.Instance.Toast("Not implemented")
        });
    }

    /// <summary>
    /// Adds the developer option.
    /// </summary>
    /// <param name="title">Title.</param>
    /// <param name="action">Action to perform when selected.</param>
    protected void AddDeveloperOption(string title, Action action)
    {
        _developerOptions.Add(new DevelopmentOption()
        {
            Title = title,
            Action = action
        });
    }
}

Alright let’s breakdown what’s going on here.

Our BasePageViewModel has a List that represents our different options for the given page. Then we have some protected methods we can use in our extended PageViewModels to setup different options.

In our SetupDeveloperOptions method, we can setup any option we want for the page, and we put a universal “Go to debug page” example action that is there on every page.

So here’s an example of a useful ViewModel that sets up a login page developer option.

LoginPageViewModel.cs

public class LoginPageViewModel : BasePageViewModel
{
    public string Email { get; set; }
    public string Password { get; set; }
    protected override void SetupDeveloperOptions()
    {
        AddDeveloperOption("Use test user", () => 
        {
            Email = "mytestuser@mydomain.com";
            Password = "myP@ssw0rd";
        });
    }
}

So what we want on this login page is to be able to shake the device and see the Action Sheet that shows “Use test user” and when selected, it should fill out the fields on the page automatically.

Now that our setup is done, let’s wire up accessing these developer options.

Wiring It Up

We need to be able to access our Page’s ViewModel in order to execute the developer options when the shake happens. To do this, we can access the current page via the Xamarin.Forms.Application.Current static accessor. Then use the MainPage property to get around.

I like to add a simple helper property getter on my App class for this:

App.xaml.cs

public class App : Application
{
    // ...

    // assuming MainPage is a NavigationPage. You can do some extra logic if it isn't
    public ContentPage CurrentPage => (MainPage as NavigationPage)?.Navigation?.NavigationStack?.Last()
    // ...
}

Now in our native app logic, where we were executing the easter egg we can call:

// we don't want developer options in production 🙂
#if DEBUG
await ((App.Current as App)?.CurrentPage?.BindingContext as BasePageViewModel)?.ShowDeveloperOptionsAsync();
#endif

So now if we are in our LoginPage and our BindingContext is set to our LoginPageViewModel, our shake should reveal the action sheet!

Conclusion

We can make our lives a whole lot easier when testing and running through our app by giving ourselves easier and contextual options throughout the entire application.

I’ve personally used this for some pretty awesome and intense stuff like:

  • Filling out forms with different values
  • Changing styles/themes of the app to easily compare 2 different UIs
  • Test different states of a page such as if a user is logged in or not
  • Test error scenarios
  • Build a page that shows logs of all interactions and background tasks in the app and use the developer options to navigate to that page whenever to see those custom logs live (even when not attached to the debugger)
  • Execute custom native code to make debugging easier
  • Navigate quickly to the page deep in the app I am currently working on

Remember to still write unit and UI tests for your app too! This is meant to be something to make real hands-on testing even easier too.

It has saved me hundreds of hours easily. Let me know if you end up implementing something like this too!

For now, I don’t have any complete open source project to demo this, but if enough of you want to see a full example and screenshots and different scenarios, I’ll consider putting a full project together. Let me know in the comments or on twitter!


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.

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 – Using Entity Framework in Your C# Alexa Skill Lambda

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 the previous Alexa.Tip, we explored Accessing Lambda Environment Variables in .NET in order to access a secure connection string and initialize a DbContext to use.

If you don’t know how to access Lambda Environment variables already, PLEASE read that post first as this post’s samples will NOT show the use of hard coded connection strings – let’s follow some best practices! 😀

Alright, let’s get into it. If you’re developing Alexa Skills in .NET, you probably need to access data somewhere! At least if you’re building a real-world scale voice application. Also, if you’re a .NET developer, you’re probably used to accessing data through Entity Framework at this point rather than using some of the AWS SDKs and data services such as DynamoDB.

It’s super easy…

Initial Skill

First off, this example uses a super basic skill where the only custom intent is to get facts about animals. Here’s the intent setup in the UI:
AnimalFactIntent_Full

You can also find the interactionModel.json here:
https://github.com/SuavePirate/Cross-Platform-Voice-NET/blob/master/src/End/AnimalFacts/AnimalFacts/InteractionModels/alexaInteractionModel.json

Let’s start by abstracting some handlers out so we aren’t writing everything in our Function class – this isn’t JavaScript after all:

WelcomeHandler.cs

public class WelcomeHandler : IResponseHandler
{
    public SkillResponse GetResponse(SkillRequest input)
    {
        return ResponseBuilder.Ask("Welcome to the animal facts voice app! You can ask me about all kinds of animals - try saying, tell me about dogs.");
    }
}

AnimalFactHandler.cs

public class AnimalFactHandler : IAsyncResponseHandler
{
    public async Task<SkillResponse> GetResponse(SkillRequest input)
    {
        // TODO: Do something with data to get the fact.
    }    
}

Then we can setup our Function:

Function.cs

public class Function
{
    // using these interfaces can help us use something like Moq to unit test this bad boy.
    private readonly IResponseHandler _welcomeHandler;
    private readonly IAsyncResponseHandler _animalFactHandler;

    public Function() 
    {
        _welcomeHandler = new WelcomeHandler();
        _animalFactHandler = new AnimalFactHandler();
    }  

    public async Task<SkillResponse> FunctionHandler(SkillRequest input, ILambdaContext context)
    {
        var requestType = input.GetRequestType();

        if (requestType == typeof(IntentRequest))
        {
            if ((input.Request as IntentRequest).Intent.Name == "AnimalFactIntent")
            { 
                return await _animalFactHandler.GetResponse(input);
            }
        }
        else if (requestType == typeof(Alexa.NET.Request.Type.LaunchRequest))
        {
            return _welcomeHandler.GetResponse(input);
        }    

        return ResponseBuilder.Ask("I'm not sure I know how to do that. Try asking me for an animal fact!");
    }
}

So we have a basic setup, but we need to actually implement something in the AnimalFactHandler. In this case, we want to do a SQL search for a fact about the animal that was asked about!

SO let’s start wiring up Entity Framework to this skill:

Add Models and Context

Let’s create a model for our AnimalFact entity to represent our table:

AnimalFact.cs

public class AnimalFact
{
    public int Id { get; set; }
    public string AnimalName { get; set; }
    public string Fact { get; set; }
}

And now let’s create a DbContext implementation with our AnimalFact:

AnimalContext

public class AnimalContext : DbContext
{
    public DbSet<AnimalFact> AnimalFacts { get; set; }
    public AnimalContext(DbContextOptions options)
        : base(options)
    {

    }

    public AnimalContext()
    {

    }
}

NOTE: If you are NOT also using this AnimalContext in a web app that handles the migrations, you’ll need to add either a web app or a console project with .NET Core to handle the migrations since it needs to be an executable project type. The assumption here is that you already have a project running these migrations so you can actually add data to it, but if you are starting here, simply create a new .NET Core web app project or Console app, reference your DbContext from a shared library between the Labmda project and the app project, then run your migrations from the app project.

From here on out, we assume you have the db created from your context and some data in it.

Updating the Skill Lambda

Now that we have a DbContext, let’s add it to our Function and AnimalFactHandler in order to search for the fact!

Let’s go to the AnimalFactHandler and setup the class to take the AnimalContext in the constructor so we can easily unit test and then use the slot value from the request to query for the animal:

AnimalFactHandler.cs

public class AnimalFactHandler : IAsyncResponseHandler
{
    private readonly AnimalContext _context;
    public AnimalFactHandler(AnimalContext context)
    {
        _context = context;
    }

    public async Task<SkillResponse> GetResponse(SkillRequest input)
    {
        // get the animal name from the slot
        var intent = (input.Request as IntentRequest).Intent;
        var animal = intent.Slots["Animal"].Value;

        // query for the fact
        var animalFact = _context.AnimalFacts
                            .Where(a => a.AnimalName.ToLower() == animal.ToLower())
                            .FirstOrDefaultAsync();

        // we found the animal!
        if (animalFact != null)
        {
            return ResponseBuilder.Tell(animalFact.Fact);
        }

        // couldn't find the animal - return a decent response
        return ResponseBuilder.Ask("I don't know about that animal. Try asking me about a different one!");
    }    
}

Now that we have the updated handler, let’s update the entry point to initialize and pass in the AnimalContext.

Function.cs

public class Function
{
    // using these interfaces can help us use something like Moq to unit test this bad boy.
    private readonly IResponseHandler _welcomeHandler;
    private readonly IResponseHandler _animalFactHandler;
    private readonly AnimalContext _context;

    public Function() 
    {
        var connectionString = Environment.GetEnvironmentVariable("DatabaseConnectionString");
        var timeoutSetting = Environment.GetEnvironmentVariable("DatabaseCommandTimeout");
        var optionsBuilder = new DbOptionsBuilder<AnimalFactContext>()
            .UseSqlServer(connectionString, providerOptions => providerOptions.CommandTimeout(int.Parse(timeoutSetting)));
        _context = new AnimalFactContext(optionsBuilder.Build());
        _welcomeHandler = new WelcomeHandler();
        _animalFactHandler = new AnimalFactHandler(_context);
    }  

    public SkillResponse FunctionHandler(SkillRequest input, ILambdaContext context)
    {
        var requestType = input.GetRequestType();

        if (requestType == typeof(IntentRequest))
        {
            if ((input.Request as IntentRequest).Intent.Name == "AnimalFactIntent")
            { 
                return _animalFactHandler.GetResponse(input);
            }
        }
        else if (requestType == typeof(Alexa.NET.Request.Type.LaunchRequest))
        {
            return _welcomeHandler.GetResponse(input);
        }    

        return ResponseBuilder.Ask("I'm not sure I know how to do that. Try asking me for an animal fact!");
    }
}

Now we can publish this and check out our results!

Results

For example, I’ll use Swagger to create an animal fact, and then ask for it!

Boom – created:
create_dog_fact.PNG

And now let’s ask for it!

dog_fact_response

Conclusion

Adding data-driven responses to your custom Alexa Skills is dead easy using techniques you may already be familiar with if you are a .NET web developer! Show me what you’ve built with .NET and Alexa in the comments!


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/