Read the statement by Michael Teeuw here.
CORS using node_helper.js for Uber and Lyft APIs
-
Hi all,
I have a bit of programming experience (mostly C and python) but I have never worked with javascript. I am trying to create a module to communicate with the Uber and Lyft APIs. Initially I was trying to do something like this for Lyft , but I kept getting an
'Access-Control-Allow-Origin'error.After some research I found this post which said that a work-around is done in node_helper.js and referenced this module.
So, I have tried my hand at an Uber module done in that fashion, but no luck. I have put a bunch of Log.log() statements in my code but I am not seeing anything in the console to help me debug. The mirror shows the statement “Checking Uber status…”
Here’s the module code:
/* global Module */ /* Magic Mirror * Module: Uber * * based on MagicMirror work by Michael Teeuw http://michaelteeuw.nl * MIT Licensed. */ Module.register("MMM-uber",{ // Default module config. defaults: { lat: null, lng: null, product_id: null, client_id: null, uberServerToken: null, updateInterval: 5 * 60 * 1000, // every 5 minutes animationSpeed: 1000, }, // Define required scripts. getScripts: function() { return ["moment.js", "https://code.jquery.com/jquery-2.2.3.min.js"]; }, // Define required styles. getStyles: function() { return ["MMM-uber.css"]; }, start: function() { Log.info("Starting module: " + this.name); // Set locale. moment.locale(config.language); // variables that will be loaded from service this.uberTime = null; this.uberSurge = null; this.loaded = false; this.sendSocketNotification('CONFIG', this.config); }, // unload the results from uber services processUber: function(FLAG, result) { var self = this; Log.log("ProcessUber"); // go through the time data to find the uberX product if (FLAG === "TIME"){ Log.log("Time"); Log.log(result); for (var i = 0, count = result.times.length; i < count ; i++) { var rtime = result.times[i]; if(rtime.display_name === "uberX"){ // convert estimated seconds to minutes this.uberTime = rtime.estimate / 60; break; } } } // go through the price data to find the uberX product else if (FLAG === "PRICE"){ Log.log("Price"); Log.log(result); for( var i=0, count = result.prices.length; i< count; i++) { var rprice = result.prices[i]; if(rprice.display_name === "uberX"){ // grab the surge pricing this.uberSurge = rprice.surge_multiplier; break; } } } }, // Override dom generator. getDom: function() { var wrapper = document.createElement("div"); var uber = document.createElement("div"); uber.className = "uberButton"; var uberIcon = document.createElement("img"); uberIcon.className = "badge"; uberIcon.src = "modules/MMM-uber/UBER_API_Badges_1x_22px.png"; var uberText = document.createElement("span"); if(this.loaded) { var myText = "UberX in "+ this.uberTime +" min "; Log.log("ubersurge: " + this.uberSurge); // only show the surge pricing if it is above 1.0 if(typeof this.uberSurge !== "undefined" && this.uberSurge > 1.0){ myText += " - " + this.uberSurge + "X surge pricing"; } uberText.innerHTML = myText; } else { // Loading message uberText.innerHTML = "Checking Uber status ..."; } uber.appendChild(uberIcon); uber.appendChild(uberText); wrapper.appendChild(uber); return wrapper; }, socketNotificationReceived: function(notification, payload) { Log.log(this.name + " received a socket notification: " + notification + " - Payload: " + payload); if (notification === "TIME") { this.processUber("TIME", payload); this.updateDom(this.config.animationSpeed) } else if (notification === "PRICE") { this.processUber("PRICE", payload); this.loaded = true; this.updateDom(this.config.animationSpeed); } } });And the code in node_helper.js
'use strict'; /* Magic Mirror * Module: MMM-lyft * * By Kyle Kelly * MIT Licensed. */ const NodeHelper = require('node_helper'); var request = require('request'); var moment = require('moment'); module.exports = NodeHelper.create({ start: function() { var self = this; console.log("Starting node helper for: " + this.name); this.started = false; this.config = null; }, getData: function() { var self = this; request({ url: "https://api.uber.com/v1/estimates/time", method: 'GET', headers: { "Authorization": "Token " + self.config.uberServerToken }, data: { start_latitude: self.config.lat, start_longitude: self.config.lng, product_id: self.product_id }, }, function (error, response, body) { if (!error && response.statusCode == 200) { self.sendSocketNotification("TIME", body); } }); request({ url: "https://api.uber.com/v1/estimates/price", method: 'GET', headers: { "Authorization": "Token " + self.config.uberServerToken }, data: { start_latitude: self.config.lat, start_longitude: self.config.lng, end_latitude: self.config.lat, end_longitude: self.config.lng }, }, function (error, response, body) { if (!error && response.statusCode == 200) { self.sendSocketNotification("PRICE", body); } }); setTimeout(function() { self.getData(); }, this.config.updateInterval); }, socketNotificationReceived: function(notification, payload) { var self = this; if (notification === 'CONFIG' && self.started == false) { self.config = payload; self.getData(); self.started = true; } } });Any help would be appreciated. Thanks!
-
@kal are you looking at the correct console? Log.log logs to electron console, which is visible when starting MM with
npm start dev(or by pressing some shortcut which I forgot; search the forum if you want to know). The terminal where you start MM is kind of useless for debugging :( -
@Anhalter42 said in CORS using node_helper.js for Uber and Lyft APIs:
(or by pressing some shortcut which I forgot; search the forum if you want to know).
Try F12.
-
As an example ONLY!
getStuff: function(url) { request({ url: "https://www.whereever.com/stuff.json", method: 'GET', headers: { 'User-Agent': 'MagicMirror/1.0 ' } }, (error, response, body) => { if (!error && response.statusCode == 200) { blah..blah....blah....... -
@Anhalter42 I’m looking at the JavaScript console. The IP of my laptop is whitelisted, so I go to
https://IP.of.Raspberry.Pi:8080in Chrome and then go to View>Developer>JavaScript Console.Is there another way I can get statements to print to that console ?
-
@cowboysdude isn’t that what I am doing? Can you explain how your solution differs from mine?
-
When you request a webpage, your browser sends a number of headers to the server hosting the site that you’re visiting.
These headers occur during a negotiation process that helps the browser and the hosting server determine the best way to provide the requested information. The user-agent header identifies the application requesting the information from the server, typically a browser. This identification string is called the user-agent string and contains tokens that provide specific details about the program making the request.
-
@cowboysdude I don’t think the user-agent string is required when making an HTTP request. According to the Uber API docs it doesn’t look like I need one.
-
@kal well then… I know its not helping, but it should work as you described. Not seeing anything in js console is a serious problem when developing. Did you try other browsers? If nothing appears in any browser AND on raspberry itself (with
npm start dev), then something is seriously wrong… -
I was able to fix this. See below for the module code
/* global Module */ /* Magic Mirror * Module: Uber * * Shows the time and surge pricing for UberX * * By Kyle Kelly * based on MagicMirror work by Michael Teeuw http://michaelteeuw.nl * and by derickson https://github.com/derickson/MMderickson/tree/master/uber * MIT Licensed. */ Module.register("MMM-uber",{ // Default module config. defaults: { lat: null, lng: null, ride_type: "uberX", uberServerToken: null, updateInterval: 5 * 60 * 1000, // every 5 minutes animationSpeed: 1000, }, // Define required scripts. getScripts: function() { return ["moment.js", "https://code.jquery.com/jquery-2.2.3.min.js"]; }, // Define required styles. getStyles: function() { return ["MMM-uber.css"]; }, start: function() { Log.info("Starting module: " + this.name); // Set locale. moment.locale(config.language); // variables that will be loaded from service this.uberTime = null; this.uberSurge = null; this.loaded = false; Log.log("Sending CONFIG to node_helper.js in " + this.name); Log.log("Payload: " + this.config) this.sendSocketNotification('CONFIG', this.config); }, // unload the results from uber services processUber: function(FLAG, result) { var self = this; Log.log("ProcessUber"); // go through the time data to find the uberX product if (FLAG === "TIME"){ Log.log("Time:"); Log.log(result); for (var i = 0, count = result.times.length; i < count ; i++) { var rtime = result.times[i]; if(rtime.display_name === this.config.ride_type){ // convert estimated seconds to minutes this.uberTime = rtime.estimate / 60; break; } } } // go through the price data to find the uberX product else if (FLAG === "PRICE"){ Log.log("Price:"); Log.log(result); for( var i=0, count = result.prices.length; i< count; i++) { var rprice = result.prices[i]; if(rprice.display_name === this.config.ride_type){ // grab the surge pricing this.uberSurge = rprice.surge_multiplier; break; } } } }, // Override dom generator. getDom: function() { var wrapper = document.createElement("div"); var uber = document.createElement("div"); uber.className = "uberButton"; var uberIcon = document.createElement("img"); uberIcon.className = "badge"; uberIcon.src = "modules/MMM-uber/UBER_API_Badges_1x_22px.png"; var uberText = document.createElement("span"); if(this.loaded) { var myText = this.config.ride_type + " in "+ this.uberTime +" min "; Log.log("ubersurge: " + this.uberSurge); // only show the surge pricing if it is above 1.0 if(typeof this.uberSurge !== "undefined" && this.uberSurge > 1.0){ myText += " - " + this.uberSurge + "X surge pricing"; } uberText.innerHTML = myText; } else { // Loading message uberText.innerHTML = "Checking Uber status ..."; } uber.appendChild(uberIcon); uber.appendChild(uberText); wrapper.appendChild(uber); return wrapper; }, socketNotificationReceived: function(notification, payload) { Log.log(this.name + " received a socket notification: " + notification + " - Payload: " + payload); if (notification === "TIME") { this.processUber("TIME", JSON.parse(payload)); this.updateDom(this.config.animationSpeed) } else if (notification === "PRICE") { this.processUber("PRICE", JSON.parse(payload)); this.loaded = true; this.updateDom(this.config.animationSpeed); } } });and the node_helper.js code
'use strict'; /* Magic Mirror * Module: MMM-uber * * By Kyle Kelly * MIT Licensed. */ const NodeHelper = require('node_helper'); var request = require('request'); var moment = require('moment'); module.exports = NodeHelper.create({ start: function() { var self = this; console.log("Starting node helper for: " + this.name); this.config = null; }, getData: function() { var self = this; this.sendSocketNotification("Test", 2); this.sendSocketNotification("LATITUDE", this.config.lat); this.sendSocketNotification("LONGITUDE", this.config.lng); request({ url: "https://api.uber.com/v1/estimates/time?start_latitude=" + this.config.lat + "&start_longitude=" + this.config.lng, method: 'GET', headers: { 'Authorization': 'Token ' + this.config.uberServerToken, 'Accept-Language': 'en_US', 'Content-Type': 'application/json' }, }, function (error, response, body) { if (!error && response.statusCode == 200) { self.sendSocketNotification("TIME", body); } else { self.sendSocketNotification("ERROR", "In TIME request with status code: " + response.statusCode); } }); request({ url: "https://api.uber.com/v1/estimates/price?start_latitude=" + this.config.lat + "&start_longitude=" + this.config.lng + "&end_latitude=" + this.config.lat + "&end_longitude=" + this.config.lng, method: 'GET', headers: { 'Authorization': 'Token ' + this.config.uberServerToken, 'Accept-Language': 'en_US', 'Content-Type': 'application/json' }, }, function (error, response, body) { if (!error && response.statusCode == 200) { self.sendSocketNotification("PRICE", body); } else { self.sendSocketNotification("ERROR", "In PRICE request with status code: " + response.statusCode); } }); setTimeout(function() { self.getData(); }, this.config.updateInterval); }, socketNotificationReceived: function(notification, payload) { //var self = this; this.sendSocketNotification("Test", 0); if (notification === 'CONFIG') { this.sendSocketNotification("Test", 1); this.config = payload; this.getData(); } } });
Hello! It looks like you're interested in this conversation, but you don't have an account yet.
Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.
With your input, this post could be even better 💗
Register Login