locked
Help need (push notifications?)

Answers

All replies

  • Wednesday, October 26, 2011 2:38 PM
    Moderator
  • Yes, but I saw only part of code which create 'listener' and even this sample don't have this what I need. (I may be wrong)
    Wednesday, October 26, 2011 2:46 PM
  • What will be updating the tile, a backgroundTask or a WebService?
    Jeff Sanders (MSFT)
    Thursday, October 27, 2011 8:30 PM
    Moderator
  • It will be WebService
    Friday, October 28, 2011 9:16 AM
  • This is the best document for what you want to do: http://msdn.microsoft.com/en-us/library/windows/apps/hh465460

    Here are the basics.  You need to create your application and a webservice.

    Application (you can use the post notifications sample to test your webservice):

    • Create your app (use the Post Notifications sample as a good starting point).
    • Create logic to get a channel and POST the URI to your WebServer (again you can use the post notifications sample to test your webservice).
    • Send the URI to your webservice (switch to scenario two to test receiving the notification).

     Create your webserver that will host the service to update the Toast (here is the harder work):

    • Register your app and get your Package Security Identifier (SID) and secret key (Your webservice will need the SID and Secret key)
    • Create a page to get your POST from your application that it sends when opening the channel (or a service or some other endpoint)
    • Add logic to get an access token using the SID and Secret Key.  You will use this access token for subsequent posts until the token expires.  The notification request used to send the Toast will return an error and at that time you would need to get a new access token.
    • When your service wants to send a Toast it will do so using the access token and the URI sent to it by your application.

    -Jeff


    Jeff Sanders (MSFT)
    Friday, October 28, 2011 7:49 PM
    Moderator
  • This is the correct approach.  Piotr I guess the little piece of information that you might be missing is that push notifications update your tiles even when your app is not running.  So your application can be suspended but the the OS will still receive updates from WNS on your app's behalf and update the tile for you.  The Channel URIs are still valid even when your app has ended.
    Wednesday, November 02, 2011 5:07 PM
  • Piotr,

    This is a real great post about notifications as well: http://blogs.msdn.com/b/b8/archive/2011/11/02/updating-live-tiles-without-draining-your-battery.aspx

    -Jeff


    Jeff Sanders (MSFT)
    Thursday, November 03, 2011 6:20 PM
    Moderator
  • Hi,

    I need help, I don't know how to do working push notifications. 

    My code:

    var pusch = {
        channel: null,
        serverURL: 'http://byyou.yoyo.pl/work/test.php',
        channelOpen: function () {
            var t = this;
            var channelOperation = Windows.Networking.PushNotifications.PushNotificationChannelManager.createPushNotificationChannelForApplicationAsync();
            return channelOperation.then(function (newChannel) {
                t.channel = newChannel;
                $('#info').text('Channel was create');
            },
    function (error) {
                $('#info').text('Open error: ' + error);
            });
        },
        sendURI: function () {
            var t = this;
            this.channelOpen().then(function () {   
    
                var xhr = new WinJS.xhr({
                    type: 'POST',
                    url: t.serverURL,
                    headers: { "Content-Type": "application/x-www-form-urlencoded" },
                    data: "channelUri=" + (t.serverURL)
                }).then(function (req) {
                    $('#info').text('Channel has ben open');
                    t.channel.addEventListener("pushnotificationreceived", pushNotificationReceivedHandler);
                }, function (error) {
                    $('#info').text('Send error: ' + error.statusText);
                });
    
                
               
            }, function (e){ $('#info').text('Error:'+e); });
        }
    }
    
    function pushNotificationReceivedHandler(e) {
        $('#info').html('Change <br />');
        download.appointment();
    }
    


    Monday, November 07, 2011 11:39 AM
  • Which of the steps is not working for you?  Did you verify your server is getting the code and the server is able to get the proper information?
    Jeff Sanders (MSFT)
    Friday, November 11, 2011 8:42 PM
    Moderator
  • I think this one: 
       t.channel.addEventListener("pushnotificationreceived", pushNotificationReceivedHandler);
    
    because when i show response after open channel it is ok.
    Monday, November 14, 2011 8:29 AM
  • Hi Piotr,

    If you were able to open the channel successfully you should be able to verify your server gets the message.  Do you know how to use Network Monitor to see what traffic is being sent and received?  Can you debug your server and verify it is sending a notification out with the update?

    -Jeff


    Jeff Sanders (MSFT)
    Monday, November 14, 2011 1:44 PM
    Moderator
  • Hi, I think something is wrong because after run program I see this:

    wwahost.exe is my program. I don't know what i've looking for.

    Monday, November 14, 2011 2:59 PM
  • Hi Piotr,

    If you are not familiar with tracing network traffic to verify the message is being sent from your code to your server, and your server is sending the notification out, you can debug your server and verify from that end.  Does that make sense to you?

    -Jeff


    Jeff Sanders (MSFT)
    Monday, November 14, 2011 3:53 PM
    Moderator
  • How to get the URI for the channel?
    Tuesday, November 15, 2011 1:51 PM
  • Hi Kondala,

    The sample does this: http://code.msdn.microsoft.com/windowsapps/Push-Notifications-Sample-c6718fa9

    Please review that sample and the documentation I posted earlier.  This will help you understand the Push Mechanism.

    -Jeff


    Jeff Sanders (MSFT)
    Tuesday, November 15, 2011 1:54 PM
    Moderator
  • Hi Jeff,

    Unfortunately I do not have access to the server I can only send requests and read responses. 

    Wednesday, November 16, 2011 10:26 AM
  • Hi Piotr,

    If you do not have access to your server, how are you accomplishing this step?  Create your webserver that will host the service to update the Toast (here is the harder work):


    Jeff Sanders (MSFT)
    • Marked as answer by Piotr C Thursday, November 17, 2011 9:18 AM
    Wednesday, November 16, 2011 12:24 PM
    Moderator
  • Hi,

    Sorry, I forgot about few steps, I try again. Thanks for help ;)

    Wednesday, November 16, 2011 1:49 PM
  • Please help me in creation of webserver. Any links!

    Friday, November 25, 2011 9:04 AM
  • I already did that one. The channel creation was successful but help me in creation of web server.
    Friday, November 25, 2011 9:06 AM
  • Hi Piotr C ,

    Can you please help in the creation of the web server.

    Friday, November 25, 2011 9:09 AM
  • Kondala,

    Are you using IIS for your WebServer?

    -Jeff


    Jeff Sanders (MSFT)
    Monday, November 28, 2011 4:51 PM
    Moderator
  • Hi Kondala,

    We've been working with the Windows Azure team to make it easy to set up a web server which registers channel URLs and sends push notifications.  You can get all set up and working with just a few steps.

    Feel free to check out the Windows Azure Toolkit for Win 8 here:

    http://watwindows8.codeplex.com/

    For more details you can review our talk that we presented at BUILD.  This goes into more detail how push notifications work and how to use the toolkit.

    http://channel9.msdn.com/Events/BUILD/BUILD2011/SAC-863T

    Hope that helps.

    Darren

    Monday, November 28, 2011 6:34 PM
  • Hi Jeff Sanders,

    I am using IIS.

    Friday, December 02, 2011 11:50 AM
  • Kondala,
    

    I created two pages on my server.  This is by NO MEANS complete or production code.  For example you would 
    
    need to persist: Application["channelUri"]  So that if IIS restarts you still have the channelUri.  It should be a good starting point for you.
    
    This first one I POST to (like the sample app does) to set the Channel URI:
    

        protected void Page_Load(object sender, EventArgs e)
        {
            if (Request.HttpMethod != "POST")
            {
                Response.StatusCode = 405;
                Response.StatusDescription = "Incorrect syntax";
                Response.Write("You should use this in a POST to set the channel URI");
                Response.End();
            }
            else
            {
                byte[] aByteReq = new byte[Request.ContentLength];
    
                Request.InputStream.Read(aByteReq,0,Request.ContentLength);
    
                string aStrReq = System.Text.UTF8Encoding.UTF8.GetString(aByteReq);
                int i = aStrReq.IndexOf("channelUri=");
                if (i == 0)
                {
                    aStrReq = aStrReq.Substring(i + 11);
                    Response.Write("Successfully got channelUri: " + aStrReq);
                    if (Application["channelUri"] != null)
                    {
                        Application["channelUri"] = aStrReq;
                    }
                    else
                    {
                        Application.Add("channelUri", aStrReq);
                    }
                }
                else
                {
                    Response.Write("Could not find 'channelUri=' in your posted data.  This is required: " + aStrReq);
                }
                Response.End();
    
            }
        }
    
    

     This second one is used to send a real simple update.

    public partial class SendPushNotification : System.Web.UI.Page
    {
    
    
        #region secretInfo
        ///
        /// <secretinfo>
        /// from: 
    
    /// http://msdn.microsoft.com/en-us/library/windows/apps/hh465460(v=VS.85).aspx#registering_wit_store
    
    

        private string sid = "ms-app://s-1-15-2-XXXXXXXXXXXXXX 2334248381-426615021-900790940-2305730494";
        private string secret = "ugd-XXXXXXXXXX";
        private string accessToken = "";
        /// </secretinfo>
        #endregion
    
        
        [DataContract]
        public class OAuthToken
        {
            [DataMember(Name = "access_token")]
            public string AccessToken { get; set; }
            [DataMember(Name = "token_type")]
            public string TokenType { get; set; }
        }
    
        OAuthToken GetOAuthTokenFromJson(string jsonString)
        {
            using (var ms = new MemoryStream(Encoding.Unicode.GetBytes(jsonString)))
            {
                var ser = new DataContractJsonSerializer(typeof(OAuthToken));
                var oAuthToken = (OAuthToken)ser.ReadObject(ms);
                return oAuthToken;
            }
        }
    
        protected void getAccessToken()
        {
            var urlEncodedSid = HttpUtility.UrlEncode(String.Format("{0}", this.sid));
            var urlEncodedSecret = HttpUtility.UrlEncode(this.secret);
    
            var body =
              String.Format("grant_type=client_credentials&client_id={0}&client_secret={1}&scope=notify.windows.com", urlEncodedSid, urlEncodedSecret);
    
            var client = new WebClient();
            client.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
    
            string response = client.UploadString("https://login.live.com/accesstoken.srf", body);
            var oAuthToken = GetOAuthTokenFromJson(response);
            this.accessToken = oAuthToken.AccessToken;
        }
    
    
        protected string PostToCloud(string uri, string xml, string type = "wns/tile")
        {
            try
            {
                if (accessToken == "")
                {
                    getAccessToken();
                }
                byte[] contentInBytes = Encoding.UTF8.GetBytes(xml);
    
                WebRequest webRequest = HttpWebRequest.Create(uri);
                HttpWebRequest request = webRequest as HttpWebRequest;
                webRequest.Method = "POST";
    
                webRequest.Headers.Add("X-WNS-Type", type);
                webRequest.Headers.Add("Authorization", String.Format("Bearer {0}", accessToken));
    
                Stream requestStream = webRequest.GetRequestStream();
                requestStream.Write(contentInBytes, 0, contentInBytes.Length);
                requestStream.Close();
    
                HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse();
                LogResponse(webResponse);
                return webResponse.StatusCode.ToString();
            }
            catch (WebException webException)
            {
                string exceptionDetails = webException.Response.Headers["WWW-Authenticate"];
                if ( (exceptionDetails != null) && exceptionDetails.Contains("Token expired"))
                {
                    getAccessToken();
                    OutPutInfo("Updated access token");
                    return PostToCloud(uri, xml, type);
                }
                else
                {
                    LogResponse(webException.Response);
                    return "EXCEPTION: " + webException.Message;
                }
            }
            catch (Exception ex)
            {
                return "EXCEPTION: " + ex.Message;
            }
        }
    
        protected void OutPutInfo(string info)
        {
            //TODO: log information in debug build
        }
    
        protected void LogResponse(WebResponse info)
        {
            //TODO: log information in debug build
        }
        
    
        protected void Page_Load(object sender, EventArgs e)
        {
            if (Application["channelUri"] != null)
            {
                if (Request.QueryString["message"] != null)
                {
                    string aStrReq = Application["channelUri"] as string;
                    string xml = "<?xml version=\"1.0\" encoding=\"utf-16\"?><tile><visual lang=\"en-US\"><binding template=\"TileWideText01\"><text id=\"1\">" + Request.QueryString["message"] as string + "</text><text id=\"2\"></text><text id=\"3\"></text><text id=\"4\"></text><text id=\"5\"></text></binding></visual></tile>";
                    
                    Response.Write("Sending notification message: " + Request.QueryString["message"] + " to 'channelUri='" + aStrReq);
                    Response.Write("Result: " + PostToCloud(aStrReq, xml));
                    
                }
                else
                {
                    Response.Write("you did not add a ?message='your message' to the query string!");
                }
            }
            else
            {
                Response.Write("Application 'channelUri=' has not been set yet");
            }
            Response.End();
    
        }
    }

    I issue a GET to so that I can set a simple message for my tile:  http://myserver/SendPushNotification.aspx?message=Hello

     

    -Jeff

     


    Jeff Sanders (MSFT)
    Friday, December 02, 2011 2:24 PM
    Moderator
  • I threw together a simple walkthrough of this for the community:

    http://blogs.msdn.com/b/jpsanders/archive/2011/12/02/walkthrough-creating-an-iis-server-to-use-with-wns-push-notifications-metro.aspx

    Let me know if you find it usefull!

    -Jeff

     


    Jeff Sanders (MSFT)
    Friday, December 02, 2011 5:43 PM
    Moderator
  • Jeff,

    Can you please provide the steps to add the above two pages to IIS. I'm running the local IIS 7.5 on my machine.

    Thanks

    Thursday, December 08, 2011 9:31 PM
  • If you are new to ASP.Net there are some tutorials on this site: http://www.asp.net/

    There should be a few that show you how to use Visual Studio to build a site and add pages.  Let me know if that helps!

    -Jeff


    Jeff Sanders (MSFT)
    Thursday, December 08, 2011 9:33 PM
    Moderator
  • Hi jpsanders:

    I want to know the HttpUtility namespace in windows8. Would you please tell me?(I find "HttpUtility" in your code.)

    Thanks!

    Hilda

    Thursday, May 17, 2012 2:39 AM
  • Hi Hilda,

    I updated my blog with the correct 'using statements'

    http://blogs.msdn.com/b/jpsanders/archive/2011/12/02/walkthrough-creating-an-iis-server-to-use-with-wns-push-notifications-metro.aspx

    -Jeff


    Jeff Sanders (MSFT)

    Thursday, May 17, 2012 1:10 PM
    Moderator
  • Hi Jeff,

    I am using http://blogs.msdn.com/b/jpsanders/archive/2011/12/02/walkthrough-creating-an-iis-server-to-use-with-wns-push-notifications-metro.aspx. I am publishing the web project(two aspx pages) in IIS and  I am able to get the channeluri but when I clicked the "Start listening for push notification" button, I am not getting any output and also when I access my send notification page like http://localhost:9090/SendPushNotification.aspx?message=Nazia in browser, I am getting error at

    client.UploadString("https://login.live.com/accesstoken.srf", body);
    Can you please let me know what could be the issue?

    EDIT: I am getting a webexception with the message "Operation Timed out". The problem raises in getting the access token.


    Nazia


    Tuesday, May 29, 2012 6:52 AM
  • Hi Nazia,

    I can not even dream of what the problem is because you did not say what the error is!  :-)

    -Jef


    Jeff Sanders (MSFT)

    Tuesday, May 29, 2012 12:01 PM
    Moderator