I'm trying to get a registration on the Azure Notification Hub working from html/javascript code running in a web view host (Phonegap / Intel XDK). There is no client library available, so I try to use the REST API (documentation: ).
I have the following Javascript code:
function registerWithAzureNotificationHub()
{
var sas = "Endpoint=sb://eventpusher-ns.servicebus.windows.net/;SharedAccessKeyName=DefaultListenSharedAccessSignature;SharedAccessKey=69XuYoluyBKl6JkkN03Z1oNC7cFSZ4Ku0ZWmPuWoJzs=";
var data = '<?xml version="1.0" encoding="utf-8"?>\
<entry xmlns="http://www.w3.org/2005/Atom">\
<content type="application/xml">\
<MpnsRegistrationDescription xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/netservices/2010/10/servicebus/connect">\
<Tags>myTag, myOtherTag</Tags>\
<ChannelUri>https://eventpusher-ns.servicebus.windows.net/eventpusher</ChannelUri>\
</MpnsRegistrationDescription>\
</content>\
</entry>';
if (AppMobi.iswp8) {
window.alert("IS WP8");
}
else
{
window.alert("IS NOT WP8");
}
$.ajax({
type:"POST",
url: "https://eventpusher-ns.servicebus.windows.net/EVENTPUSHER/registrations/?api-version=2013-08",
contentType: "application/atom+xml;type=entry;charset=utf-8",
headers: {
"Authorization": sas,
"x-ms-version": "2013-08"
},
dataType: "xml",
data: data,
success: function(d) { window.alert("SUCCESS!"); },
error: function(msg) { window.alert("FAILURE:" + JSON.stringify(msg)); }
});
window.alert("SENT!");
}
In the above case I use the Intel XDK with the code running on a WP8 device, so I register for MPNS (Microsoft Push Notification Service).
The above code fails, and returns without descriptive information about the cause of the error.
Questions:
Is it possible to register a mobile device for Azure Notification Hub from javascript code using REST services?
What could be wrong with the above code? Is the ChannelUri the correct Uri?
It is definitely possible top use the REST interface from javascript.
In your code there are two main problems:
in the ChannelURI you should put the channelURI retrieved from the WindowsPhone HttpPushNotificationChannel (as in this tutorial).
the authorization header is a token that is created for your specific request. As described here
A sample using WinJS is available. We will work on having a PhoneGap specific sample very soon!
I did post a server side snippet to register the device with token to the hub and to be able to send out the notification here :
How to register devices to Azure Notification Hub from server side(with NodeJS sdk) ?
I also have the client side code using ngCordova and PushPlugin in Ionic, let me know if anyone wants to see it.
Related
I have a Web App Bot running on Azure.
It's using the Microsoft Bot Framework Direct Line API 3.0.
I want to use the URL Ping Test type instead of the Multi-Stage Web Test for the Availability Test of the Bot because I do not have the Visual Studio 2017 Enterprise edition.
In the Bot's message controller, this is how I handle the response for Pings.
I am able to get expected response in the Bot emulator when running the Bot in localhost.
else if (message.Type == ActivityTypes.Ping)
{
ConnectorClient client = new ConnectorClient(new Uri(message.ServiceUrl));
var reply = message.CreateReply();
reply.Text = "{Some message}";
await client.Conversations.ReplyToActivityAsync(reply);
}
However, when I connect to the Bot in Azure, I am getting HTTP error 500.
I'm not sure what is the root cause and wonder whether it is due to the URL Ping Test does not know the Direct Line secret.
Appreciate your kind help on this.
Thanks very much.
If you check the “Send an activity to the bot” in Direct Line API 3.0 documentation, you can find:
To send an activity to the bot, the client must create an Activity object to define the activity and then issue a POST request, specifying the Activity object in the body of the request.
URL ping test would sned a GET request to the URL that you specified, it would not hit/trigger the code that you defined for Ping activity in your MessagesController.
If you’d like to detect whether your bot is alive by sending a Ping activity, you could make a request like below from your client.
Request:
POST https://directline.botframework.com/v3/directline/conversations/{conversationId}/activities
Authorization: Bearer {directline_secret}
Content-Type: application/json
Body:
{
"type": "ping",
"from": {
"id": "user1"
}
}
I've started to look into the azure sdk for node.js (link below) and interestingly enough I've hit a wall in what I'd image would be one of the most common tasks one would want to achieve using Azure's REST endpoints which is checking the status of a virtual machine.
I can easily get a list of all machine, or one in particular but the response from this services don't include the current status of the VM (running,stopped etc.)
There's absolutely no info out there regarding this particular scenario in the docos or the web other than a blog post (https://github.com/Azure/azure-xplat-cli/issues/2565) which is actually in regards of a different library.
Please not that I'm using the azure-arm-compute library which is part of the Node.js azure sdk.
Any help would be very much appreciated
github repo: https://github.com/Azure/azure-sdk-for-node
To get Virtual Machine statuses, please use function get(resourceGroupName, vmName, optionsopt, optionalCallbackopt), and pass the vaule {expand: 'instanceView'} as the options parameter.
var msRestAzure = require('ms-rest-azure');
var computeManagementClient = require('azure-arm-compute');
// Interactive Login
// It provides a url and code that needs to be copied and pasted in a browser and authenticated over there. If successful,
// the user will get a DeviceTokenCredentials object.
msRestAzure.interactiveLogin(function(err, credentials) {
var client = new computeManagementClient(credentials, 'ed0caab7***');
client.virtualMachines.get('<resourceGroupName>', '<vmName>', {expand: 'instanceView'}, function(err, result, request, response) {
if (err) console.log(err);
console.log(result.instanceView);
});
});
We are implementing an application using Unity 3d and we are consuming the Azure Push Notification REST API.
But there are a couple of issues and questions on how to successfully send and receive the message.
For testing we are using Advanced Rest client extension for chrome.
We are able to create the registration by using the native template ( check https://msdn.microsoft.com/en-us/library/azure/dn223265.aspx )
<?xml version="1.0" encoding="utf-8"?>
<entry xmlns="http://www.w3.org/2005/Atom">
<content type="application/xml">
<GcmRegistrationDescription xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/netservices/2010/10/servicebus/connect">
<Tags></Tags>
<GcmRegistrationId>Some Id from somewhere</GcmRegistrationId>
</GcmRegistrationDescription>
</content>
</entry>
So far we are sending the request with empty Tags, and we are not sure what the GcmRegistration should be, the weird thing is that no matter what we send there we get a valid response.
<entry a:etag="W/"1"">
<id>https://cloudservicechat-ns.servicebus.windows.net/cloudservicechat/registrations/8760279628548469956-1956153846630646542-1?api-version=2015-01</id>
<title type="text">8760279628548469956-1956153846630646542-1</title>
<published>2016-06-01T15:15:16Z</published>
<updated>2016-06-01T15:15:16Z</updated>
<link rel="self" href="https://cloudservicechat-ns.servicebus.windows.net/cloudservicechat/registrations/8760279628548469956-1956153846630646542-1?api-version=2015-01" />
<content type="application/xml">
<GcmRegistrationDescription>
<ETag>1</ETag>
<ExpirationTime>2016-08-30T15:15:16.215Z</ExpirationTime>
<RegistrationId>8760279628548469956-1956153846630646542-1</RegistrationId>
<GcmRegistrationId>Some Id from somewhere</GcmRegistrationId>
</GcmRegistrationDescription>
</content>
</entry>
Now we are trying to send the notification (https://msdn.microsoft.com/en-us/library/azure/dn223273.aspx) but we are not sure of the correct payload to use from azure when using GCM
According to the documentation in GCM
the payload would be something like this
{
"to" : "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
"notification" : {
"body" : "great match!",
"title" : "Portugal vs. Denmark",
"icon" : "myicon"
}
}
However no matter what we do, we always get an Unauthorized response.
Also tried to use the registration using templates, but we are not sure what we should add in (check https://msdn.microsoft.com/en-us/library/azure/dn223265.aspx)
So the questions would be
* Where we can get the GcmRegistrationId from?
* How we should replace format the {BodyTemplate}
* What would be a valid notification payload to use using Azure Test Send
Thanks for the help
Based from this documentation, you need to add the parameter gcmRegistrationId in the MyHandler class to override the onRegistered method, which registers your device with the mobile service Notification Hub. Example:
#Override
public void onRegistered(Context context, final String gcmRegistrationId) {
super.onRegistered(context, gcmRegistrationId);
new AsyncTask<Void, Void, Void>() {
protected Void doInBackground(Void... params) {
try {
ToDoActivity.mClient.getPush().register(gcmRegistrationId, null);
return null;
}
catch(Exception e) {
// handle error
}
return null;
}
}.execute();
}
You can read in this documentation the steps on how to use templates to send platform-agnostic notifications targeting all your devices across platforms, and to personalize broadcast notification to each device.
The standard way to send push notifications is to send, for each notification that is to be sent, a specific payload to platform notification services (WNS, APNS). For example, to send an alert to APNS, the payload is a Json object of the following form:
{"aps": {"alert" : "Hello!" }}
You can check these related threads:
Adding Google GCM Api Key Azure Notification Hub Error
NotificationHubUnauthorizedException: Unauthorized on Azure Notification Hub registration
So I'm using azure mobile services backend to try and make a custom API. However I can't seem to connect to even the template table from the client. When you make a new Azure Mobile Service using the template they provide you with this values API controller that resembles this format
[MobileAppController]
public class ValuesController : ApiController
{
// GET api/values
[Route("api/values")]
public string Get()
{
return "test";
}
}
From the client I'm trying to invoke this endpoint like this
var result = mobileService.InvokeApiAsync<string>("values", HttpMethod.Get, null).Result;
And for some reason I keep getting this exception
{"The request could not be completed. (Bad Request)"}
{Method: GET, RequestUri: 'http://localhost:58457/api/values', Version: 1.1, Content: <null>, Headers:
{
X-ZUMO-FEATURES: AT
X-ZUMO-INSTALLATION-ID: b04f4e19-4f41-46ed-9767-9c1352037559
Accept: application/json
User-Agent: ZUMO/1.3
User-Agent: (lang=Managed; os=Windows; os_version=6.1.65536.7601; arch=Win32NT; version=1.3.30324.0)
X-ZUMO-VERSION: ZUMO/1.3 (lang=Managed; os=Windows; os_version=6.1.65536.7601; arch=Win32NT; version=1.3.30324.0)
}}
This is only the template too, so I need this to work before I get any of my custom endpoints up and running. Any ideas on what the issue may be?
You can opt out of version checking by setting a value of true for the app setting MS_SkipVersionCheck. Specify this either in your web.config or in the Application Settings section of the Azure Portal.
ms_skipversioncheck to true in the portal.
You say Mobile Service, but the controller you're using is MobileAppController.
This indicates you're actually using Mobile App. If you look in your server project packages.config, you may see something like this.
<package id="Microsoft.Azure.Mobile.Server" version="1.0.119.0" targetFramework="net45" />
I suspect that the 400 you are getting is because you're using a Mobile Client version less than 2.0.0.
In your client project package config, try using a newer client version, such as:
<package id="Microsoft.Azure.Mobile.Client" version="2.0.1" targetFramework="win81" />
You should also inspect the body of the 400 response to get an explicit error message. I expect it to say something like:
{"message":"No API version was specified in the request, this request needs to specify a ZUMO-API-VERSION of '2.0.0'. For more information and supported clients see: http://go.microsoft.com/fwlink/?LinkId=690568#2.0.0"}
I have gone through the below link
https://learn.microsoft.com/en-us/azure/app-service-mobile/app-service-mobile-client-and-server-versioning
which actually says both Mobile Apps client and server SDKs are originally based on those in Mobile Services, but they are not compatible with each other. That is, you must use a Mobile Apps client SDK with a Mobile Apps server SDK and similarly for Mobile Services. This contract is enforced through a special header value used by the client and server SDKs, ZUMO-API-VERSION.
So, you must add Headers in the request
HEADERS: ZUMO-API-VERSION: 2.0.0
Or
http://localhost/api/values/get?ZUMO-API-VERSION=2.0.0
Or
You can opt out of version checking by setting a value of true for the app setting MS_SkipVersionCheck, specify this in your web.config under
Actually even if you specify what version of client you are using in your package.config you will still get the same error of Bad Request. No Zumo version specified. You must pass into your InvokeApiAsync method a parameter specifying the version. For example:
var arguments = new Dictionary<string, string>
{
{"ZUMO-API-VERSION", "2.0.0" }
};
var result = MobileService.InvokeApiAsync<string>("CONTROLLERSNAME", "HttpMethod.Get", arguements).Result;
and bingo it will work.
Community:
ServiceWorker is a great advance technology in terms of cache managment, but I have some questions associated with other operations such as:
Push Notification: I made a GCM integration (Google Clud Message) and NodeJS, following this article, the problem is that when GCM sends the information to the client (Chorme), the payload of the message generated by GCM is not accessible in the Notification in ServiceWorker Listener, which would be great for making decisions.
Any Idea when data payload in notifications will be enabled?
Registration: Since ES6 is very mature, it would be good to register a ServiceWorker in other ways, for example:
import sw from './sw.js'
navigator.serviceWorker.register(sw, {scope: '/'}).then(function (registration) {
// Registration was successful
console.log('ServiceWorker registration successful with scope: ', registration.scope);
}).catch(function (err) {
// registration failed :(
console.log('ServiceWorker registration failed: ', err);
});
Is this possible or make sense?
Thanks!!!!
The "Support encrypted payloads for push messages" bug tracks progress on getting payloads exposed in notifications. That bug is Chrome-specific, but other browser vendors are likely to follow the same approach.
The service worker upgrade flow is very much tied to the idea of there being a specific JavaScript file which represents the service worker's code, and that file can then be periodically checked, byte-by-byte, to see if there are any updates. If it were an in-memory JavaScript object that was registered, detached from the file, the upgrade flow wouldn't work as specified. I don't think you'll see the change you're proposing added to the specification.