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.

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/


Alexa.Tip – Build Better Responses in .NET With SSML

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 are looking at a VERY simple, but useful tool when developing Alexa Skills – SSML or Speech Synthesis Markup Language.

If you’re new to voice application development, SSML is a common standard among all the big players – Alexa, Google, Cortana, etc. At its simplest form, it’s a simple set of XML elements that are used to tell the Voice Assistant (such as Alexa) how to speak your response in a particular way. The alternative to using SSML is to return simple text as a string and let the assistant respond with their normal speech. However, this commonly falls short on things like:

  • Abbreviations
  • Dates
  • Emphasis
  • Pauses
  • Tone
  • Pitch

This is especially true when the assistant is reading out a particularly long set of text. It becomes too… robotic. Ironically…

So let’s look at an example of a C# and .NET response using simple text:

Function.cs

public SkillResponse SimpleTextResponse()
{
    return ResponseBuilder.Tell(new PlainTextOutputSpeech
    {
        Text = "When one door of happiness closes, another opens; but often we look so long at the closed door that we do not see the one which has been opened for us."
    });
}

With a response like this, Alexa will likely read it too quickly which can really diminish the power behind such a great quote (by Helen Keller).

Now we can very easily update a response like this to give ourselves something more powerful:

Function.cs

public SkillResponse RichTextResponse()
{
    return ResponseBuilder.Tell(new SsmlOutputSpeech
    {
        Ssml = 
            @"<speak>
                When <emphasis level=""moderate"">one</emphasis> door of happiness closes, another opens;
                <break time=""1.5s""/>
                <s>but often we look so long at the <emphasis level=""strong"">closed</emphasis> door that we do not see the one which has been opened for us.</s>
            </speak>"
    });
}

Now with this, we can add emphasis of different levels on certain words, add breaks in the speech when we need to, and separate contextual sentences!

For a full list of SSML tags that Alexa supports check this out:
https://developer.amazon.com/docs/custom-skills/speech-synthesis-markup-language-ssml-reference.html

And be sure to check back for more intro to expert level tips on Alexa Skill development!
Or take a look at other posts in the Alexa.Tip series here!

Side note: I’m also working on a tool to make building SSML responses even better – especially for very large and dynamic pieces of conversations. The idea is to build a more Fluid Design approach for something like this:

// returns a string
return SsmlBuilder.Speak("When")
    .Emphasis("one", Emphasis.Moderate)
    .Speak("door of hapiness closes, another opens;)
    .Break(1.5)
    .Sentence("but often we look so long at the closed door that we do not see the one which has been opened for us.")
    .Build();

Or something like:

// returns a string - uses string searching
return SsmlBuilder.Speak("When one door of happiness closes, another opens; but often we look so long at the closed door that we do not see the one which has been opened for us.")
    .Emphasis("one", Emphasis.Moderate)
    .Break(";")
    .Sentence("but often we look so long at the closed door that we do not see the one which has been opened for us.")
    .Emphasis("closed", Emphasis.Strong)
    .Build();

Or:

// returns a string - uses indexes and lengths
return SsmlBuilder.Speak("When one door of happiness closes, another opens; but often we look so long at the closed door that we do not see the one which has been opened for us.")
    .Emphasis(4, 3, Emphasis.Moderate)
    .Break(47)
    .Sentence(49, 112)
    .Emphasis(59, 6, Emphasis.Strong)
    .Build();

Let me know what you think in the comments or on twitter @Suave_Pirate – Would you rather build SSML Responses like this or is writing the XML in a big fat string working alright for you?


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/