Sunday, June 5, 2016

Use Microsoft Azure to Host Alexa Card Images




Alexa Skills Kit includes the ability to add an image on your card.  So, I uploaded a file to my website and added the url to the response.card.image.smallImageUrl value.  Sadly, all I got was an empty grey box in the card.  It turns out that I needed to setup CORS.

An easy option is to use AWS's S3 storage.  But, I am more familiar with Microsoft Azure.  And I have free credits to use each month, so I wanted to see what it would take to use Azure's storage to host these images.

It turns out that it's not too difficult to setup.  And even if you don't have free credits, it will cost you pennies each year to host thousands of images used in your skills.

This blog will step you through
  1. Creating an Azure Storage Account resource
  2. Uploading files to the blob container
  3. Enabling CORS on your Azure Storage Account


Create a Blob Storage

In your Azure portal click '+ New'


Search for Storage Account.
Click Create.
Give your storage a name.  This will be part of the URI you'll use to access your files.
There are a lot of other options in here that you can choose depending on your needs.  Each choice will change the cost of your storage.  But based on the small files and limited amount of data I'd be storing in here (less than 1GB), I can't see how it would cost me more than pennies every month, no matter which options I choose.



Now add a container.  Make sure to change the Access type to Blob.  This will ensure that your files are accessible to the Alexa app.



Access Keys

You'll need your access keys to finish up a couple of the final steps.  These are available under the settings of your storage account.  Copy your key1 because you will need it later.

(the keys are for my old storage account, so I didn't bother blurring them out)

Upload files

The easiest tool to upload files into your container is available in Microsoft Azure Tool's for Visual Studio.  In the Cloud Explorer, drill down into your resources (Storage Accounts -> [BlobStorageName] -> Blob Containers -> [ContainerName]).



The first time you open your container, you may need to provide your storage account's Access Key.

You can now open up the Blob Container Editor.  This tool allows you to upload blobs/files into your container.  Each file will have a URL associated with it that can be accessed publicly, since this was setup as a blob container.



Test out your uploads in a web browser.  You can right-click on your uploads and copy the url.

You can now upload MP3s to this container and use them in SSML responses.

If you would like to use images in your cards, you'll need one more change.  The echo.amazon.com website and Echo app requires that the hosting site has CORS enabled.  This lets the web browser know that it's ok to download content from your website, even though it's displaying a webpage hosted at Amazon.


Enable CORS

There is MSDN documentation about how to enable CORS on your Azure Storage containers.  I tried to follow the RESTful PUT request to enable this, but first had issues with the format of my authorization header.  I found another article that describes how to format the auth header, but then I ran into another issue. I was getting a generic error about my XML content being malformed.  I gave up and decided to spend time on a different approach, the Azure C# SDK.

I created a new console project and added the nuget package, WindowsAzure.Storage.  Then, with a few lines of code, I enabled the CORS rule necessary for using images on cards.  Copy the code below into the Main() function.  And then update it to include your AccountName and AccountKey.

CloudStorageAccount StorageAccount 
  = CloudStorageAccount.Parse(@"DefaultEndpointsProtocol=https;AccountName=alexademo;AccountKey=CKBnwLxjJqZ0n6zvoe...");

CloudBlobClient BlobClient = StorageAccount.CreateCloudBlobClient();

ServiceProperties blobServiceProperties = BlobClient.GetServiceProperties();
blobServiceProperties.Cors = new CorsProperties();
blobServiceProperties.Cors.CorsRules.Add(new CorsRule()
{
    AllowedMethods = CorsHttpMethods.Get,
    AllowedOrigins = new List() { "http://ask-ifr-download.s3.amazonaws.com" }
});
            
BlobClient.SetServiceProperties(blobServiceProperties);

Run the code once and your storage container will now return images to the Alexa app.

Test it out

Your cards will now be able to access your images (be sure to update your skill code to point to the new azure blob stored images).  If you have any problems, make sure you are following the other requirements around the images
  • Correct format: JPEG or PNG
  • Allowed size: Less than 2MB

Enjoy!

2 comments:

  1. Thanks, this looks very useful. I'll see if I use this as a guideline. Microsoft Azure

    ReplyDelete
  2. Azure app meet rigorous performance, scalability, security and compliance requirements while using a fully managed platform to perform infrastructure maintenance. Quickly create powerful cloud apps using a fully managed platform from Impiger technologies. To know more read this :https://www.impigertech.com/blog/azure-app-service/

    ReplyDelete