Beefy Boxes and Bandwidth Generously Provided by pair Networks Bob
more useful options
 
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
  • Outside of code tags, you may need to use entities for some characters:
            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 chanting in the Monastery: (9)
    As of 2014-04-17 13:19 GMT
    Sections?
    Information?
    Find Nodes?
    Leftovers?
      Voting Booth?

      April first is:







      Results (447 votes), past polls