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(); #### 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_XWNSCachePolicy ) if defined $hdr_XWNSCachePolicy; $req->header('X-WNS-RequestForStatus' => $hdr_XWNSRequestForStatus ) 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, etc here. } } sub getWNSAccessToken { # Get the current access token ## Nothing fancy. ## Just fetch current WNS access token from persistent store and 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 = "$toastLine1$toastLine2"; my $resp; $resp = sendWNSPost ($WNSChannel, $payload, "Bearer $accessToken", "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 $accessToken", "text/xml", "wns/toast", "no-cache", "true", undef, 600); # TTL = 10 minutes here } if ($resp->is_success) { my $connectionStatus = $resp->header('X-WNS-DeviceConnectionStatus'); if ($connectionStatus eq 'connected') { return $WNS_OK; } elsif ($connectionStatus eq 'tempdisconnected') { ## Handle 'tempdisconnected' in whatever way you please. return $WNS_OK; # or whatever you want } elsif ($connectionStatus eq 'disconnected') { return $WNS_OFFLINE; } } return $WNS_ERR; } ;