Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked
 
PerlMonks  

Comment on

( #3333=superdoc: print w/ replies, xml ) Need Help??
~~~~~~~~~~~~~~~~ edit: SOLUTION BELOW. ~~~~~~~~~~~~~~~~ I'm trying to send a WNS notification via Perl with the following code using OAuth2. When I step through the code, it appends the site to make it https://login.live.com/oauth/authorize, which (I think) is causing it to fail. Any suggestions on how to send WNS notifications from Perl?
my $auth = Net::OAuth2::Profile::Password->new( site => 'https://login.live.com/' , site_path => '/accesstoken.srf' , client_id => uri_escape('ms-app://xxxxx') , client_secret => uri_escape('yyyyyyyy') , grant_type => 'client_credentials' , scope => 'notify.windows.com' ); my $token = $auth->get_access_token();
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ I gave up using OAuth2 and rolled my own. Hopefully you folks will find this helpful. You can't just copy and paste, but if you follow the directions in the ##comments, you should be 90% there. This sends a Toast message via WNS to a unique ID (in my case, a user ID) associated with a WNS Channel. The XML payload can obviously be changed to send badges or whatever you want. I store everything in a database. You can use constants, except for the access token which changes, and you'll need to find some way to persist it. To use: sendPushNotificationToast($uniqID);. This will resolve the uniqID to its corresponding WNS channel(which again, in my case is stored in the database next to uniqID), and try to send a push notification.
use DBI; use URI::Escape; use LWP::Simple; use JSON qw( decode_json ); use Data::Dumper; ################################################################## sub getWNSChannel { ## The "ID" here is an ID associated with a WNS channel ## An ID is a unique user or computer my ($id) = @_; ## I persist the WNSURI in a database. ## Fetch WNSURI from persistent store, using ID as a key # Sanity check if ($WNSChannel =~ m#^https://.*notify\.windows\.com\/\?#) { return $WNSChannel; } return $WNS_OFFLINE; } ################################################################## sub sendWNSPost { my ( $server_endpoint, $payload, $hdr_Authorization, $hdr_ContentType, $hdr_XWNSType, $hdr_XWNSCachePolicy, $hdr_XWNSRequestForStatus, $hdr_XWNSTag, $hdr_XWNSTTL ) = @_; my $ua = LWP::UserAgent->new; $ua->agent("ArbitraryUserAgent/0.1 "); my $req = HTTP::Request->new(POST => $server_endpoint); $req->header('Authorization' => $hdr_Authorization + ) if defined $hdr_Authorization; $req->header('Content-Type' => $hdr_ContentType + ) if defined $hdr_ContentType; $req->header('X-WNS-Type' => $hdr_XWNSType + ) if defined $hdr_XWNSType; $req->header('X-WNS-Cache-Policy' => $hdr_XWNSCachePolic +y ) if defined $hdr_XWNSCachePolicy; $req->header('X-WNS-RequestForStatus' => $hdr_XWNSRequestFor +Status ) if defined $hdr_XWNSRequestForStatus; $req->header('X-WNS-Tag' => $hdr_XWNSTag + ) if defined $hdr_XWNSTag; $req->header('X-WNS-TTL' => $hdr_XWNSTTL + ) if defined $hdr_X-WNS-TTL; $req->content($payload); return $ua->request($req); } sub getNewAccessToken { ## Fetch WNS client ID, secret, and URI from persistent store ## (or you can hard code them/put in config file, whatever) ## and put them into client_id, client_secret URL encoded $authenticationUri = "https://login.live.com/accesstoken.srf"; $client_id = uri_escape($client_id); $client_secret = uri_escape($client_secret); my $payload = "grant_type=client_credentials&client_id=$client +_id&client_secret=$client_secret&scope=notify.windows.com"; my $resp = sendWNSPost( $authenticationUri, $payload, undef, 'application/x-www-form-urlencoded', + # Content-Type undef, undef, undef, undef, undef); my $decoded_json = decode_json( $resp->content ); my $access_token = $decoded_json->{'access_token'}; if ($resp->is_success) { ## Update the access token in the database/persistent +store } else { ## Yeeps! Something went wrong. Send an alert, log, e +tc here. } } sub getWNSAccessToken { # Get the current access token ## Nothing fancy. ## Just fetch current WNS access token from persistent store a +nd return it return $accessToken; } sub sendPushNotificationToast { my ($id) = @_; my $WNSChannel = getWNSChannel($id); my $accessToken = getWNSAccessToken(); if ($WNSChannel == $WNS_OFFLINE) { return $WNS_OFFLINE; } # Sanity check if ($WNSChannel !~ /^https.*notify\.windows\.com/) { return $WNS_ERR; } # Get customer details for toast my $toastLine1 = "Toast Line 1"; my $toastLine2 = "Toast Line 2"; my $payload = "<toast duration='long'><visual version='1'><bin +ding template='ToastText02'><text id='1'>$toastLine1</text><text id=' +2'>$toastLine2</text></binding></visual></toast>"; my $resp; $resp = sendWNSPost ($WNSChannel, $payload, "Bearer $accessTok +en", "text/xml", "wns/toast", "no-cache", "true", undef, undef); if ($resp->is_error) { ## If at first you don't succeed, ## get a new access token and try again. getNewAccessToken(); $accessToken = getWNSAccessToken(); $resp = sendWNSPost ($WNSChannel, $payload, "Bearer $a +ccessToken", "text/xml", "wns/toast", "no-cache", "true", undef, 600) +; # TTL = 10 minutes here } if ($resp->is_success) { my $connectionStatus = $resp->header('X-WNS-DeviceConn +ectionStatus'); if ($connectionStatus eq 'connected') { return $WNS_OK; } elsif ($connectionStatus eq 'tempdisconnected') { ## Handle 'tempdisconnected' in whatever way y +ou please. return $WNS_OK; # or whatever you want } elsif ($connectionStatus eq 'disconnected') { return $WNS_OFFLINE; } } return $WNS_ERR; } ;

In reply to OAuth2 WNS by DaisyLou

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.
  • Log In?
    Username:
    Password:

    What's my password?
    Create A New User
    Chatterbox?
    and the web crawler heard nothing...

    How do I use this? | Other CB clients
    Other Users?
    Others musing on the Monastery: (17)
    As of 2015-07-01 15:22 GMT
    Sections?
    Information?
    Find Nodes?
    Leftovers?
      Voting Booth?

      The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









      Results (5 votes), past polls