Updated NotificationsExtensions WnsRecipe Nuget to support Windows 8.1 templates now available

A short post to let you know that I have just published the updated NotificationsExtensions WnsRecipe Nuget with support for the new notification templates that were added in Windows 8.1.

Here is a short demonstration of how to use it to send a new TileSquare310x310ImageAndText01 template with the WnsRecipe Nuget Package

Install the package using Nuget Package Manager Console. (Note you could also do this using Manage package references in solution explorer)

install-package WnsRecipe

Add using statements to the NotificationsExtensions namespace

using NotificationsExtensions;
using NotificationsExtensions.TileContent;

New up a new WnsAccessTokenProvider and provide it your credentials configured in the Windows Store app Dashboard

private WnsAccessTokenProvider _tokenProvider = new WnsAccessTokenProvider("ms-app://", "");

Use Tile Content Factory to create your tile template

var tile = TileContentFactory.CreateTileSquare310x310ImageAndText01();

tile.Image.Src = "https://nickha.blob.core.windows.net/tiles/empty310x310.png";
tile.Image.Alt = "Images";
tile.TextCaptionWrap.Text = "New Windows 8.1 Tile Template 310x310";

// Note you really should not do the line below :), 
// instead you should be setting the required content 
// through property tile.Wide310x150Content so that users
// get updates irrespective of what size tile they have pinned to Start
tile.RequireWide310x150Content = false;  

//Send the notification to the desired channel
var result = tile.Send(new Uri(channel), _tokenProvider);

and here is the output
310x310tile

Enjoy, Nick Harris

How to implement Periodic Notifications in Windows Store apps with Azure Mobile Services Custom API

I blogged previously on how to make your Push Notification implementation more efficient.  In this post I will detail an alternative to Push, that is Periodic Notifications, which is are a poll based solution for updating your live Tiles and Badge content (Note that it can’t be used for Toast or Raw). It turns out if your app scenario can deal with only receiving notifications every thirty minutes or more that this is a much easier way for you to update your tiles.  All you need to do is configure you app for periodic notifications, and point it at a service API that will return the appropriate XML template for the badge or tile update in your app whether you are using WCF, Web API or others this is quite an easy thing to achieve.  In this case I will demonstrate how you can implement this using Mobile Services.

Let’s start with the backend service by creating a Custom API.  To do this all you need to do is select the API tab in the Mobile Services portal.

MobileServices_CustomAPITab Next provide a name for your endpoint and set the permissions for get to everyone

MobileServices_CustomAPIDialog

Next define the return XML return payload for your custom API.  You can see examples of each different Tile templates here

exports.get = function(request, response) {
    // Use "request.service" to access features of your mobile service, e.g.:
    //   var tables = request.service.tables;
    //   var push = request.service.push;
 
    response.send(200, ''+
                            ''+
                                ''+
                                    ''+
                                    '@ntotten enjoying himself a little too much :)'+
                                ''+
                            ''+
                        '');
};

    Note:

  • If you are supporting multiple tile sizes you should sending the whole payload in for each of the varying tile sizes
  • This is just an example  – you really should be providing dynamic content here rather than the same tile template every time

Next configure you’re app to point at your Custom API through the package.appxmanifest

VisualStudio2013_PackageManifestPeriodicNotifications

Run your app, ensure your app is pinned to start in the right dimension for the content you are returning e.g

Windows_PinLargeTile

Pin your tile and wait for the update after app has been run once.

Windows_LargeTileUpdatedByPeriodicNotification

Job done! – the tile will be updated with the content from your site with the periodic update per your package manifest definition.

Enjoy, Nick Harris

BUILD 2013 session recap

//BUILD 2013 was an awesome event! this post is a little late (I had a bunch more events back to back right after this one and I am finally digging out :) . Although late this content is still extremely relevant if you are building Connected Mobile Apps. If your interested in building mobile apps you should checkout some of the content I contributed to build this year.

Keynote Demo of Windows Azure Mobile Services

For //BUILD 2013 I was fortunate enough to be on point for delivering the Day 2 Windows Azure Mobile Services keynote content. If you have not watched this keynote I would recommend you check it out – the Windows Azure Mobile Services Demo starts about 31mins 30 seconds in

Watch the direct from Channel9 here

Build Connected Windows 8.1 Apps with Mobile Services

Want less slides and more live action? Me too! Come join me in this session where you’ll learn how to develop XAML/C# Windows Store apps that take advantage of Mobile Services as a cloud backend. During this session we’ll leverage a number of the Windows Runtime APIs used for Geolocation, Media capture and Notifications. Following this I’ll demonstrate how you can take advantage of Mobile Services to store your geospatial data, media, send notifications and auth users of your service using popular social identity providers.

Download slides and/or watch direct from Channel9 here

Enjoy, Nick Harris

How to handle WNS Response codes and Expired Channels in your Windows Azure Mobile Service

When implementing push notification solutions for your Windows Store apps many people will implement the basic flow you typically see in a demo then consider their implementation as job done. While this works well in demos and apps that are running at a small scale with few users those that are successful will likely want to optimize their solution to be more efficient to reduce compute and storage costs. While this post is not a complete guide I am providing it to at least give you enough information to get you thinking about the right things.
A few quick up front questions you should ask yourself are:

  • Is push appropriate? Should I be using Local, Scheduled or Periodic notifications instead?
  • Do I need updates at a more granular frequency then every 30 minutes?
  • Am I sending notifications that are personalized for each recipient or am I sending a broadcast style notification with the same content to a group of users?

A typical implementation

If you figured out push is the right choice and implemented the basic flow it will normally look something like this:

 

  1. Requesting a channel
  2. using Windows.Networking.PushNotifications;
    …
    var channel = await PushNotificationChannelManager.CreatePushNotificationChannelForApplicationAsync();
    
  3. Registering that channel with your cloud service
  4. var token = Windows.System.Profile.HardwareIdentification.GetPackageSpecificToken(null);
    string installationId = Windows.Security.Cryptography.CryptographicBuffer.EncodeToBase64String(token.Id);
    
    var ch = new JObject();
    ch.Add("channelUri", channel.Uri);
    ch.Add("installationId", installationId);
    
    try
    {
       await App.pushdemoClient.GetTable("channels").InsertAsync(ch);
    }
    catch (Exception exception)
    {
       HandleInsertChannelException(exception);
    }
    
  5. Authenticate against WNS and sending a push notification
  6. //Note: Mobile Services handles your Auth against WNS for your, all you have to do is configure your Store app and the portal WNS credentials.
    
    function SendPush() {
        var channelTable = tables.getTable('channels');
        channelTable.read({
            success: function (channels) {
                channels.forEach(function (channel) {
                    push.wns.sendTileWideText03(channel.uri, {
                        text1: 'hello W8 world: ' + new Date().toString()
                    });
                });
            }
        });
    }
    

And for most people this is about as far as the push implementation goes. What many are not aware of is that WNS actually provides two useful pieces of information that you can use to make your push implementation more efficient – a Channel Expiry time and a WNS response that includes both notification status codes and device status codes using this information you can make your solution more efficient. Let’s take a look at the first one

Handling Expired Channels

When you request a channel from WNS it will return to you both a channel and an expiry time, typically 30 days from your request. Consider that your app over time is popular but you do have users that over time end up deciding either to not use your app for extended periods or delete it all together. Over time these channels will hit their expiry date and will no longer be of any use and there is no need to a) send notifications to these channels and b) keep these channels in your datastore. Let’s have a look at a simple implementation that will cleanup your expired channels.

Using a Scheduled Job in Mobile Services we can perform a simple clean of your channels but first we must send the Expiry to your Mobile Service. To do this you must update step 2 of the above implementation to pass up the channel expiry as a property in your JObject – you will find the channel expiration in the channel.ExpirationTime property. For my channel table I have called this Expiry.

Following that once you have created your scheduled push job at say an interval of X (I am using 15 minutes) you can then add a function that deletes the expired channels similar to the following

function cleanChannels() {
    var sql = "DELETE FROM channels WHERE Expiry < GetDate()";
    mssql.query(sql, {
        success: function (results) {
            console.log('deleting expired channels:', results)
        },
        error: function (error) {
            console.log(error);
        }
    });
}

As you can see there is no real magic here and you probably want to handle UTC dates – but in short it demonstrates the concept that the expired channels are not useful for sending notifications so delete them, flag them as deleted or anything else that keeps them out of the valid set that you will push to… moving on

Handling the WNS response codes

When you send a notification to a channel via WNS, WNS will send a response. Within this response are many useful response headers. Today i’ll just focus on X-WNS-NotificationStatus but it’s worth noting that you should also consider X-WNS-DeviceConnectionStatus – more details here

Let’s look at a typical response:

{
headers:
{ ‘x-wns-notificationstatus': ‘received’,
‘x-wns-msg-id': ‘707E20A6167E338B’,
‘x-wns-debug-trace': ‘BN1WNS1011532′ },
statusCode: 200,
channel: ‘https://bn1.notify.windows.com/?token=AgYAAACghhaYbZa4sqjJ23pWp3kGDcEOEb3JxxdeBahCINn15fc11TiG0mlTpR5heYQmEaQrgZc3TSSwoUllW9s4Lsn3eyvSn19DcrX%2bOvSOY4Bq%2bPKGWbdy3mjTmaRi2Yb1dIM%3d’
}

Of interest in this response is X-WNS-NotificationStatus which can be one of three different states:

  • received
  • dropped
  • channelthrottled

As you can probably guess if you are sending notifications when you are either throttled or dropped it is probably not a good use of your compute power and as such you should really handle channels that are not returning received status in a fitting way. Consider the following when the scheduled job runs delete any expired channels and send notifications to channels in (the status of received) OR (that are not in the status of received AND that last had a push sent over an hour ago). This can be easily achieved by tracking the X-WNS-NotificationStatus every time a notification is sent. Code follows:

function SendPush() {
    cleanChannels();
    doPush();
}

function cleanChannels() {
    var sql = "DELETE FROM channel WHERE Expiry < GetDate()";

    mssql.query(sql, {
        success: function (results) {
            console.log('deleting expired channels:', results)
        },
        error: function (error) {
            console.log(error);
        }
    });
}

function doPush() {
    //send only to received channels OR channels that are not in the state of received that last had a push sent over an hour ago 
    var sql = "SELECT * FROM channel WHERE notificationStatus IS NULL OR notificationStatus = 'received' 
                    OR ( notificationStatus <> 'received'
                           AND CAST(GetDate() - lastSend AS float) * 24 >= 1) ";

    mssql.query(sql, {
        success: function (channels) {
            channels.forEach(function (channel) {

                push.wns.sendTileWideText03(channel.uri, {
                    text1: 'hello W8 world: ' + new Date().toString()
                }, {
                    success: function (response) {
                        handleWnsResponse(response, channel);
                    },
                    error: function (error) {
                        console.log(error);
                    }
                });
            });
        }
    });
}

// keep track of the last know X-WNS-NotificationStatus status for a channel
function handleWnsResponse(response, channel) {
    console.log(response);

    var channelTable = tables.getTable('channel');

    // http://msdn.microsoft.com/en-us/library/windows/apps/hh465435.aspx
    channel.notificationStatus = response.headers['x-wns-notificationstatus'];
    channel.lastSend = new Date();

    channelTable.update(channel);
}

That’s about it I hope this post has helped you to start thinking about how to handle your Push Notification implementation beyond the basic 101 demo push implementation

Enjoy, Nick Harris

TechEd North America 2013 sessions

Hi All,

Yep its been a couple really busy months of events.  TechEd, /BUILD and ImagineCup. Thanks for coming to my TechEd North America 2013 sessions back in June.  If you missed the sessions below you can find the respective Channel 9 videos and slide decks if you feel like presenting to your local user group.

Developing Connected Windows Store Apps with Windows Azure Mobile Service: Overview (200)

Join us for a demo-packed introduction to how Windows Azure Mobile Services can bring your Windows Store and Windows Phone 8 apps to life. We look at Mobile Services end-to-end and how easy it is to add authentication, secure structured storage, and send push notifications to update live tiles. We also cover adding some business logic to CRUD operations through scripts as well as running scripts on a schedule. Learn how to point your Windows Phone 8 and Windows Store apps to the same Mobile Service in order to deliver a consistent experience across devices.

Watch directly on Channel9 here and get the Slides here

Build Real-World Modern Apps with Windows Azure Mobile Services on Windows Store, Windows Phone or Android (300)

Join me for and in-depth walkthrough of everything you need to know to build an engaging and dynamic app with Mobile Services. See how to work with geospatial data, multiple auth providers (including third party providers using Auth0), periodic push notifications and your favorite APIs through scripts. We’ll begin with a Windows Store app then point Windows Phone and Android apps to the same Mobile Service in order to ensure a consistent experience across devices. We’ll finish up with versioning APIs.

Watch directly on Channel9 here and get the Slides here

ping me on twitter @cloudnick  if you have questions – Thanks, Nick Harris