Getting deviceId from Azure IotHub / EventHub - javascript

I am trying to read device Id from Event Hub (on the back of IoTHub) but my syntax in JS seems wrong.
module.exports = function (context, IoTHubMessages) {
context.log(`JavaScript eventhub trigger function called for message array: ${IoTHubMessages}`);
var deviceId = IoTHubMessages.SystemProperties["iothub-connection-device-id"];
The function returns an error: Exception: TypeError: Cannot read property 'iothub-connection-device-id' of undefined
I'm not entirely sure if "iothub-connection-device-id" is the correct name of the attribute on Event Hub but the problem seems to be with SystemProperties.
Appreciate any help.

iothub-connection-device-id is the right key to use, you just have to use it on the right property bag. An unrelated GitHub issue https://github.com/Azure/azure-sdk-for-js/issues/7801 shows how this key is indeed available on each message.
Depending on the cardinality in your functions.json file, IotHubMessages will either be an array of messages or a single message. See IOTHubMessage.forEach is not a function? for more details.
If it is an array of messages, accessing SystemProperties directly on it will not work. You will need to loop through to access each message separately.
Do you see systemProperties on the individual messages? If yes, then message.systemProperties["iothub-connection-device-id"] should work.

You should be reading messages this way. Read this for more about regarding the topic - https://learn.microsoft.com/en-us/samples/azure-samples/functions-js-iot-hub-processing/processing-data-from-iot-hub-with-azure-functions/
IoTHubMessages.forEach(message => {
context.log(`Processed message: ${message}`);
count++;
totalTemperature += message.temperature;
totalHumidity += message.humidity;
deviceId = message.deviceId;
});

First, use the JSON.stringify to print you the payload received. Secondly i believe you should be able to access your device id by doing the following: message.annotations["iothub-connection-device-id"]. For more info, please reference to the Quickstart examples you have available in the Microsoft's Github repos. Navigate to the iot-hub\Quickstarts\read-d2c-messages folder and you should find the example of processing the message payload and printing the output.

I landed on this question when looking for the deviceId when a deviceTwinChange happens on on Azure Iot hub and the message it routed through event hub to my Azure function. In IotHubMessage I wave only getting reported or desired information. I was looking for the deviceId so i knew what device it came from
properties: {
reported: {
//everything in my reported section
}
}
But i found out this:
module.exports = function (context, IoTHubMessages) {
The device Id is in the context variable. I just did not on Azure Iot hub using an Azure function.
var deviceId = context.bindingData.systemProperties["iothub-connection-device-id"];
A bit annoying that the metadata is kept in context and there is no documentation about this.
Extra points: There is no application properties in the context. Does anyone know how to get application properties in the information send to the azure function? This is for when you enrich the data from azure iot hub
This is the information in azure iot hub when doing the routing. Just havent seen the information in my azure function come through.
Add up to 10 message enrichments per IoT Hub. These are added as application properties to messages sent to chosen endpoint(s).

Related

Strange error message being returned when creating calendar event

I'm creating a google calendar event using the Node.js Google Client API, I'm requesting a conference be created with the event using the following object:
var conferenceData =
{
createRequest:
{
requestId: uuid(),
conferenceSolutionKey:
{
type: "hangoutsMeet"
}
}
}
I get an error back from the server saying: Error: Invalid conference type value. Which doesn't make any sense, since, according to this documentation hangoutsMeet is an acceptable value:
The possible values are:
"eventHangout" for Hangouts for consumers (http://hangouts.google.com)
"eventNamedHangout" for classic Hangouts for G Suite users (http://hangouts.google.com)
"hangoutsMeet" for Hangouts Meet (http://meet.google.com)
Anybody have any idea why it could be returning that error?
I am facing the same problem at the moment.
I believe it actually comes from the fact that the calendar where you try to insert the event does not accept the "hangoutsMeet" conference call type.
You can check that by using the API to get the calendar setup details, in conferenceProperties.allowedConferenceSolutionTypes:
- https://developers.google.com/calendar/v3/reference/calendars/get
- https://developers.google.com/calendar/v3/reference/calendars#resource
For my particular case, I can observe that the calendar only supports "eventNamedHangout", and "hangoutsMeet" is not listed.
That being said, I have no idea about how to actually make sure the "hangoutsMeet" type is supported by a specific calendar resource.
Edit
It seems that my problem was coming from the fact I was using a GCP service account - in that case what I observe is that only the eventNamedHangout type is supported.
When sending the very same payload to the API with an access_token obtained via the oauth dance, hangoutsMeet becomes available.
I got this working. As per the events docs you referred to, if providing conferenceSolution then at least one entryPoint must also be provided. Otherwise use createRequest:
"Either conferenceSolution and at least one entryPoint, or createRequest is required."
Does your uuid() return a string ?
and try smth like this instead :
const event = {
"conferenceData": {
"createRequest": {
"requestId": "someRandomKey",
"conferenceSolutionKey": {
"type": "hangoutsMeet"
}
}
}
};

azure function service bus output message properties

I'm trying to set metadata for service bus messages in a JavaScript Azure Function using the service bus binding output. Unfortunately, it appears that the binding only supports the body.
Looking at the docs, I see that you can access this information in service bus triggers via context.bindingData but I don't see any corresponding interface for service bus output.
Is there some way to send a full brokered message and set the message properties (ContentType) and message custom properties?
#l--''''''---------'''''''''''' You need to access the Microsoft.Azure.ServiceBus.Message class. Let's say you have some json called messageBody
and you have some list of properties that you want to add to the message. You can achive it like the below example.
Make sure you add using Microsoft.Azure.ServiceBus;
var myCustomProperties = new List<Dictionary<string,string>>();
var message = new Message(Encoding.UTF8.GetBytes(messageBody));
foreach (var userProperty in myCustomProperties)
{
message.UserProperties.Add(userProperty.Key, userProperty.Value);
}
There is an open issue for this at https://github.com/Azure/Azure-Functions/issues/454
Some customers seemed to have found a workaround. Perhaps you can try their approach mentioned here https://github.com/Azure/Azure-Functions/issues/454#issuecomment-375154151

Send String to Node.js

I'm trying create a simple UI here on my iOS app to test a thing or two out but I'm having some issues here. My app is set up with a UITextField and UIButton. I'm trying to replace a string on my .js file which is saved on my virtual server. In my .js file I have below:
// Prepare a new notification
var notification = new apn.Notification();
// Display the following message (the actual notification text, supports emoji)
notification.alert = 'Hi James';
I basically would like to replace "Hi James" with whatever I typed in the UITextField in my Swift 3 project but not too sure where to start. This would be my first time sending data to .js file so anything would help. I'm thinking so far that it'd be something along the lines to below. Node.js would be similar to Javascript since it's cross platform.
func sendSomething(stringToSend : String) {
appController?.evaluateInJavaScriptContext({ (context) -> Void in
//Get a reference to the "myJSFunction" method that you've implemented in JavaScript
let myJSFunction = evaluation.objectForKeyedSubscript("myJSFunction")
//Call your JavaScript method with an array of arguments
myJSFunction.callWithArguments([stringToSend]) }, completion: { (evaluated) -> Void in
print("we have completed: \(evaluated)")
})
}
Found that on a relevant StackOverflow post so I feel like I'm getting close. Any assistant would be appreciated in advanced. Have a good one!
I recommend using the Node HTTP or ExpressJS server reading the POST fields and posting a document from your iOS app with the desired field
See
https://nodejs.org/en/docs/guides/anatomy-of-an-http-transaction/

How do you link GCM chrome push notifications and payload data?

Push notifications in Chrome via GCM are driving me crazy.
I've got everything up and running. I serve the push using my python server to GCM. A service worker displays the push notification fine.
To my knowledge, there is NO data passed with push events. Sounds like it's coming soon but not available yet.
So just before the push notification shows, I call my server to get extra data for the push notification. But I have no information on the push notification to send to my server to match and return relevant data.
Everything I can think of to match a notification and user data is purely speculative. The closest thing I can find is a timestamp object on the PushEvent{} that roughly matches the successful return of the GCM call for each user.
So how are other people handling custom payload data to display Chrome push notifications?
The PushEvent{} does not seem to have any ID associated with it. I know the user that the push is for because I've previously stored that information at the time of registration.
But once I receive a push, I have no idea of knowing what the push was for.
I would like to avoid:
Trying to match based on timestamp (since notifications displays are not guaranteed to be instant).
Trying to pull the 'latest' data for a user because in my case, there could be several notifications that are sent for different bits of data around the same time.
How are other sites like Whatsapp and Facebook linking custom payload data with a seemingly sterile event data as a result of a push notification?
How are you doing it? Any suggestions?
Here's what my receiver code looks like:
self.addEventListener('push', function(event) {
event.waitUntil(
fetch("https://oapi.co/o?f=getExtraPushData&uid=" + self.userID + "&t=" + self.userToken).then(function(response) {
if (response.status !== 200) {
console.log('Looks like there was a problem. Status Code: ' + response.status);
throw new Error();
}
return response.json().then(function(data) {
if (data.error || !data.notification) {
console.error('The API returned an error.', data.error);
throw new Error();
}
var title = data.notification.title;
var message = data.notification.message;
var icon = data.notification.icon;
return self.registration.showNotification(title, {
body: message,
icon: icon,
});
});
}).catch(function(err) {
console.error('Unable to retrieve data', err);
var title = 'An error occurred';
var message = 'We were unable to get the information for this push message';
var icon = "https://oapi.co/occurrences_secure/img/stepNotify_1.png";
var notificationTag = 'notification-error';
return self.registration.showNotification(title, {
body: message,
icon: icon,
tag: notificationTag
});
})
);
});
I understand your problem, and i've been fiddling with the same when i wanted to use chrome notification. You can use indexedDB to save ObjectStore and retrieve data in webServices.
IndexedDB is accessible to webservices. I am using it to store user information and when the user recieves a push notification i pass the stored access key to identify the user and pass him relevent information.
Here's matt gaunt's tutorial which says indexed db is accessible to web services:
http://www.html5rocks.com/en/tutorials/service-worker/introduction/
Here's a good indexedDB tutorial:
http://blog.vanamco.com/indexeddb-fundamentals-plus-a-indexeddb-example-tutorial/
Assuming you are still in the past. That is, sending only a push trigger to your browser with no payload it's now time to move on with time. You can now send payload in your push events. Since you seem familiar with GCM, it's ok to go with that though there is now the Web Push Protocol which is browser vendor independent.
Briefly, to make that work you need to encrypt your payload with specifications found here, in your server.
There is a node by google chrome and PHP implementations for that, that I know of.
You may check out the PHP Web Push here.
In the browser you would need to provide the subscription object now with the p256dh and auth on top of the endpoint as before.
You may check this out for more details.

LinkedIn Access_token request getting error using jsoauth library

hi i am try to integrate LinkedIn with my mobile application which is developing in phonegap with Xcode.
Now i have get the authorization using javascript library from github(https://github.com/bytespider/jsOAuth/blob/daa8823a02fa570b285ac26f66ff6c5d8be9d4ec/src/OAuth/Consumer.js)
jsoauth but i do not know how to set header for "https://api.linkedin.com/uas/oauth/accessToken" any one please give example for it.Now i got oauth_token,verifier,oath_token_secret.how can i use it? i get the problem send like
code is:
var options={
consumerKey:'XXXXXXXXXX',
consumerSecret:'XXXXXXXX',
verifier: verifier,
signatureMethod:'HMAC-SHA1'
};
oauth = OAuth(options);
oauth.post('https://api.linkedin.com/uas/oauth/accessToken', null,
function(data) {alert('acess');
window.plugins.childBrowser.close();
},
function(data) {
alert('no access');
console.log(data.error);
}
);
here the error function called and Xcode error shows like:
* WebKit discarded an uncaught exception in the webView:decidePolicyForNavigationAction:request:frame:decisionListener: delegate: * -[JKArray objectAtIndex:]: index (1) beyond bounds (1)
any one help me how get the AccessToken of LinkeIn.
I don't think you can set the verifier as an option.
Try using the function
oauth.setVerifier('verifier')
&
oauth.setAccessToken('MY-ACCESS-KEY', 'MY-ACCESS-SECRET');
http://bytespider.github.io/jsOAuth/api-reference/
After that, the jsOAuth will set the headers for you.
I also just had a problem fetching the access token using this library and it turned out that it was including the callback parameter unnecessarily, which made the request fail.

Categories

Resources