From 8333464d43a3bccb0b40fe22efd37609548f0c4a Mon Sep 17 00:00:00 2001 From: Tom Wallace Date: Tue, 25 Feb 2020 11:37:33 -0800 Subject: [PATCH 1/7] Added promise based functions --- demo.js | 78 +++++++++++++++++++++++++++++----------- index.js | 107 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 161 insertions(+), 24 deletions(-) diff --git a/demo.js b/demo.js index 7e654d6..ee1a175 100644 --- a/demo.js +++ b/demo.js @@ -3,34 +3,70 @@ // to match your sensorpush credentials // -const sensorpush = require('sensorpush'); +const sensorpush = require('./index.js'); +const limit = 10 let credentials = { - email: "you@foo.com", - password: "BO000yAH!" + email: "tomwallace75@hotmail.com", + password: "6#3H#577RjEW2S@ymC*W" }; -// step 1: get an authorization code -sensorpush.api.oauth.authorize(credentials, function (err1, res1) { +function init (isPromise) { + if (isPromise) { + let accessToken + // step 1: get an authorization code + return sensorpush.promise.oauth.authorize(credentials) + .then(resp => { + // step 2: get an access token + return sensorpush.promise.oauth.accesstoken({ authorization: resp.authorization }) + }) + .then(resp => { + accessToken = resp.accesstoken; + // steps 3-5: get data, using the access token + return sensorpush.promise.devices.sensors({ accessToken }) + }) + .then(resp => { + console.log("Sensor response:", resp); + return sensorpush.promise.devices.gateways({ accessToken }) + }) + .then(resp => { + console.log("Gateways response:", resp); + // get any readings from the last 10 mins + let startTime = new Date(Date.now() - 60 * 1000 * 10); + return sensorpush.promise.samples({ limit, startTime, accessToken }); + }) + .then(resp => { + console.log("Samples response:", resp); + }) + .catch(err => { + console.error(err) + }) + } else { + // step 1: get an authorization code + sensorpush.api.oauth.authorize(credentials, function (err1, res1) { - // step 2: get an access token - sensorpush.api.oauth.accesstoken({ authorization: res1.authorization }, function (err2, res2) { + // step 2: get an access token + sensorpush.api.oauth.accesstoken({ authorization: res1.authorization }, function (err2, res2) { - let accesstoken = res2.accesstoken; + let accesstoken = res2.accesstoken; - // steps 3-5: get data, using the access token - sensorpush.api.devices.sensors({ accesstoken: accesstoken }, function (err3, res3) { - console.log("Sensor response:", res3); - }); + // steps 3-5: get data, using the access token + sensorpush.api.devices.sensors({ accesstoken: accesstoken }, function (err3, res3) { + console.log("Sensor response:", res3); + }); - sensorpush.api.devices.gateways({ accesstoken: accesstoken }, function (err4, res4) { - console.log("Gateways response:", res4); - }); + sensorpush.api.devices.gateways({ accesstoken: accesstoken }, function (err4, res4) { + console.log("Gateways response:", res4); + }); - // get any readings from the last 10 mins - let startTime = new Date(Date.now() - 60 * 1000 * 10); - sensorpush.api.samples({ limit: 10, startTime: startTime, accesstoken: accesstoken }, function (err5, res5) { - console.log("Samples response:", res5); + // get any readings from the last 10 mins + let startTime = new Date(Date.now() - 60 * 1000 * 10); + sensorpush.api.samples({ limit: 10, startTime: startTime, accesstoken: accesstoken }, function (err5, res5) { + console.log("Samples response:", res5); + }); + }); }); - }); -}); + } +} + +init(true) \ No newline at end of file diff --git a/index.js b/index.js index 276a431..91e5cd1 100644 --- a/index.js +++ b/index.js @@ -1,6 +1,7 @@ const https = require('https'); exports.api = { oauth: {}, devices: {} }; +exports.promise = { oauth: {}, devices: {} }; // --------------------------------------------------------------------- @@ -17,7 +18,7 @@ function postToSensorPush(opts, cb) { }; if (accesstoken) { headers.Authorization = accesstoken; - }; + } let options = { hostname: "api.sensorpush.com", port: 443, @@ -46,7 +47,10 @@ function postToSensorPush(opts, cb) { cb(err, body, response); }); }); - req.on('error', function (e) { err = e }); + req.on('error', function (e) { + err = e + } + ); req.write(postData); req.end() } @@ -99,7 +103,7 @@ exports.api.samples = function (opts, cb) { if (startTime && startTime instanceof Date) { startTime = startTime.toISOString() } - if (startTime && !(/\d{4}\-\d{2}\-\d{2}T\d{2}\:\d{2}\:\d{2}\.\d{3}Z/).test(startTime)) { + if (startTime && !(/\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z/).test(startTime)) { throw new Error('Bad `startTime` value. Please provide a Date object or string formatted with Date::toISOString()'); } postToSensorPush({ @@ -111,3 +115,100 @@ exports.api.samples = function (opts, cb) { } }, cb); }; + +// Promise based functions +// --------------------------------------------------------------------- + +exports.promise.oauth.authorize = opts => { + return new Promise((resolve, reject) => { + return postToSensorPush({ + path: "/api/v1/oauth/authorize", + params: { + email: opts.email, + password: opts.password + } + }, function callback (err, data) { + if (err) { + reject(err) + } + resolve(data) + }) + }) +} + +// --------------------------------------------------------------------- + +exports.promise.oauth.accesstoken = function (opts) { + return new Promise((resolve, reject) => { + return postToSensorPush({ + path: "/api/v1/oauth/accesstoken", + params: { + authorization: opts.authorization + } + }, function callback (err, data) { + if (err) { + reject(err) + } + resolve(data) + }) + }) +} + +// --------------------------------------------------------------------- + +exports.promise.devices.gateways = function (opts) { + return new Promise((resolve, reject) => { + return postToSensorPush({ + path: "/api/v1/devices/gateways", + accesstoken: opts.accesstoken + }, function callback (err, data) { + if (err) { + reject(err) + } + resolve(data) + }) + }) +} + +// --------------------------------------------------------------------- + +exports.promise.devices.sensors = function (opts) { + return new Promise((resolve, reject) => { + return postToSensorPush({ + path: "/api/v1/devices/sensors", + accesstoken: opts.accesstoken + }, function callback (err, data) { + if (err) { + reject(err) + } + resolve(data) + }) + }) +} + +// --------------------------------------------------------------------- + +exports.promise.samples = function (opts) { + let startTime = opts.startTime + if (startTime && startTime instanceof Date) { + startTime = startTime.toISOString() + } + if (startTime && !(/\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z/).test(startTime)) { + throw new Error('Bad `startTime` value. Please provide a Date object or string formatted with Date::toISOString()'); + } + return new Promise((resolve, reject) => { + return postToSensorPush({ + path: "/api/v1/samples", + accesstoken: opts.accesstoken, + params: { + limit: opts.limit, + startTime: startTime + } + }, function callback (err, data) { + if (err) { + reject(err) + } + resolve(data) + }) + }) +} \ No newline at end of file From ccbf212e9db7676935caced0e5e36cd31f0186bc Mon Sep 17 00:00:00 2001 From: Tom Wallace Date: Tue, 25 Feb 2020 11:50:03 -0800 Subject: [PATCH 2/7] Get email/password from env vars --- demo.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/demo.js b/demo.js index ee1a175..fbfc6b1 100644 --- a/demo.js +++ b/demo.js @@ -7,8 +7,8 @@ const sensorpush = require('./index.js'); const limit = 10 let credentials = { - email: "tomwallace75@hotmail.com", - password: "6#3H#577RjEW2S@ymC*W" + email: process.env.SENSOR_PUSH_EMAIL, + password: process.env.SENSOR_PUSH_PASSWORD }; function init (isPromise) { From b5d35a3048668a32126f41b5c998e57b36f9fd04 Mon Sep 17 00:00:00 2001 From: Tom Wallace Date: Tue, 25 Feb 2020 12:11:37 -0800 Subject: [PATCH 3/7] Updated casing of accessToken. Stringified response when logging. --- demo.js | 21 +++++++++++---------- index.js | 22 +++++++++++----------- 2 files changed, 22 insertions(+), 21 deletions(-) diff --git a/demo.js b/demo.js index fbfc6b1..f5523f9 100644 --- a/demo.js +++ b/demo.js @@ -18,7 +18,7 @@ function init (isPromise) { return sensorpush.promise.oauth.authorize(credentials) .then(resp => { // step 2: get an access token - return sensorpush.promise.oauth.accesstoken({ authorization: resp.authorization }) + return sensorpush.promise.oauth.accessToken({ authorization: resp.authorization }) }) .then(resp => { accessToken = resp.accesstoken; @@ -26,17 +26,17 @@ function init (isPromise) { return sensorpush.promise.devices.sensors({ accessToken }) }) .then(resp => { - console.log("Sensor response:", resp); + console.log("Sensor response:", JSON.stringify(resp)); return sensorpush.promise.devices.gateways({ accessToken }) }) .then(resp => { - console.log("Gateways response:", resp); + console.log("Gateways response:", JSON.stringify(resp)); // get any readings from the last 10 mins let startTime = new Date(Date.now() - 60 * 1000 * 10); return sensorpush.promise.samples({ limit, startTime, accessToken }); }) .then(resp => { - console.log("Samples response:", resp); + console.log("Samples response:", JSON.stringify(resp)); }) .catch(err => { console.error(err) @@ -46,22 +46,22 @@ function init (isPromise) { sensorpush.api.oauth.authorize(credentials, function (err1, res1) { // step 2: get an access token - sensorpush.api.oauth.accesstoken({ authorization: res1.authorization }, function (err2, res2) { + sensorpush.api.oauth.accessToken({ authorization: res1.authorization }, function (err2, res2) { - let accesstoken = res2.accesstoken; + let accessToken = res2.accesstoken; // steps 3-5: get data, using the access token - sensorpush.api.devices.sensors({ accesstoken: accesstoken }, function (err3, res3) { + sensorpush.api.devices.sensors({ accessToken: accessToken }, function (err3, res3) { console.log("Sensor response:", res3); }); - sensorpush.api.devices.gateways({ accesstoken: accesstoken }, function (err4, res4) { + sensorpush.api.devices.gateways({ accessToken: accessToken }, function (err4, res4) { console.log("Gateways response:", res4); }); // get any readings from the last 10 mins let startTime = new Date(Date.now() - 60 * 1000 * 10); - sensorpush.api.samples({ limit: 10, startTime: startTime, accesstoken: accesstoken }, function (err5, res5) { + sensorpush.api.samples({ limit: 10, startTime: startTime, accessToken: accessToken }, function (err5, res5) { console.log("Samples response:", res5); }); }); @@ -69,4 +69,5 @@ function init (isPromise) { } } -init(true) \ No newline at end of file +// pass "false" to init function if you'd prefer to use callbacks instead of promises +init(true) diff --git a/index.js b/index.js index 91e5cd1..0c87c8f 100644 --- a/index.js +++ b/index.js @@ -8,7 +8,7 @@ exports.promise = { oauth: {}, devices: {} }; function postToSensorPush(opts, cb) { let params = opts.params || {}; let path = opts.path; - let accesstoken = opts.accesstoken; // possibly undefined + let accessToken = opts.accessToken; // possibly undefined let postData = JSON.stringify(params) let headers = { @@ -16,8 +16,8 @@ function postToSensorPush(opts, cb) { 'Content-Type': 'application/json', 'Content-Length': postData.length }; - if (accesstoken) { - headers.Authorization = accesstoken; + if (accessToken) { + headers.Authorization = accessToken; } let options = { hostname: "api.sensorpush.com", @@ -69,7 +69,7 @@ exports.api.oauth.authorize = function (opts, cb) { // --------------------------------------------------------------------- -exports.api.oauth.accesstoken = function (opts, cb) { +exports.api.oauth.accessToken = function (opts, cb) { postToSensorPush({ path: "/api/v1/oauth/accesstoken", params: { @@ -83,7 +83,7 @@ exports.api.oauth.accesstoken = function (opts, cb) { exports.api.devices.gateways = function (opts, cb) { postToSensorPush({ path: "/api/v1/devices/gateways", - accesstoken: opts.accesstoken + accessToken: opts.accessToken }, cb); }; @@ -92,7 +92,7 @@ exports.api.devices.gateways = function (opts, cb) { exports.api.devices.sensors = function (opts, cb) { postToSensorPush({ path: "/api/v1/devices/sensors", - accesstoken: opts.accesstoken + accessToken: opts.accessToken }, cb); }; @@ -108,7 +108,7 @@ exports.api.samples = function (opts, cb) { } postToSensorPush({ path: "/api/v1/samples", - accesstoken: opts.accesstoken, + accessToken: opts.accessToken, params: { limit: opts.limit, startTime: startTime @@ -138,7 +138,7 @@ exports.promise.oauth.authorize = opts => { // --------------------------------------------------------------------- -exports.promise.oauth.accesstoken = function (opts) { +exports.promise.oauth.accessToken = function (opts) { return new Promise((resolve, reject) => { return postToSensorPush({ path: "/api/v1/oauth/accesstoken", @@ -160,7 +160,7 @@ exports.promise.devices.gateways = function (opts) { return new Promise((resolve, reject) => { return postToSensorPush({ path: "/api/v1/devices/gateways", - accesstoken: opts.accesstoken + accessToken: opts.accessToken }, function callback (err, data) { if (err) { reject(err) @@ -176,7 +176,7 @@ exports.promise.devices.sensors = function (opts) { return new Promise((resolve, reject) => { return postToSensorPush({ path: "/api/v1/devices/sensors", - accesstoken: opts.accesstoken + accessToken: opts.accessToken }, function callback (err, data) { if (err) { reject(err) @@ -199,7 +199,7 @@ exports.promise.samples = function (opts) { return new Promise((resolve, reject) => { return postToSensorPush({ path: "/api/v1/samples", - accesstoken: opts.accesstoken, + accessToken: opts.accessToken, params: { limit: opts.limit, startTime: startTime From 90777c08e1a2391fe97185d3a45087f93ccd77e9 Mon Sep 17 00:00:00 2001 From: Tom Wallace Date: Tue, 25 Feb 2020 12:16:14 -0800 Subject: [PATCH 4/7] Updated code comment in demo.js --- demo.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/demo.js b/demo.js index f5523f9..553f6c6 100644 --- a/demo.js +++ b/demo.js @@ -1,7 +1,7 @@ // // To try this demo, just change the email and password below -// to match your sensorpush credentials -// +// to match your sensorpush credentials. +// Or add your sensorpush email/password to environment variables and use code as is. const sensorpush = require('./index.js'); const limit = 10 From 158c836916beab85a43705a1e7a263fb2f6e6e4a Mon Sep 17 00:00:00 2001 From: Tom Wallace Date: Tue, 25 Feb 2020 12:16:54 -0800 Subject: [PATCH 5/7] Reverted to importing sensorpush from npm instead of local file system in demo.js --- demo.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demo.js b/demo.js index 553f6c6..6290a0b 100644 --- a/demo.js +++ b/demo.js @@ -3,7 +3,7 @@ // to match your sensorpush credentials. // Or add your sensorpush email/password to environment variables and use code as is. -const sensorpush = require('./index.js'); +const sensorpush = require('sensorpush'); const limit = 10 let credentials = { From bf2ba43f149ffe58fe66818ebbedb76c979e58ee Mon Sep 17 00:00:00 2001 From: Tom Wallace Date: Tue, 25 Feb 2020 12:23:26 -0800 Subject: [PATCH 6/7] Added common function to validate start time and defined regex for startTime outside function so it only needs to initialize it once rather than in each call. --- index.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/index.js b/index.js index 0c87c8f..fbae8b3 100644 --- a/index.js +++ b/index.js @@ -3,6 +3,12 @@ const https = require('https'); exports.api = { oauth: {}, devices: {} }; exports.promise = { oauth: {}, devices: {} }; +const START_TIME_REGEX = /\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z/ + +function validateStartTime (startTime) { + return startTime && START_TIME_REGEX.test(startTime) +} + // --------------------------------------------------------------------- function postToSensorPush(opts, cb) { @@ -103,7 +109,7 @@ exports.api.samples = function (opts, cb) { if (startTime && startTime instanceof Date) { startTime = startTime.toISOString() } - if (startTime && !(/\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z/).test(startTime)) { + if (!validateStartTime(startTime)) { throw new Error('Bad `startTime` value. Please provide a Date object or string formatted with Date::toISOString()'); } postToSensorPush({ @@ -193,7 +199,7 @@ exports.promise.samples = function (opts) { if (startTime && startTime instanceof Date) { startTime = startTime.toISOString() } - if (startTime && !(/\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z/).test(startTime)) { + if (!validateStartTime(startTime)) { throw new Error('Bad `startTime` value. Please provide a Date object or string formatted with Date::toISOString()'); } return new Promise((resolve, reject) => { From 86aa54efab908b46daa065a2db46504fc10b4695 Mon Sep 17 00:00:00 2001 From: Tom Wallace Date: Tue, 25 Feb 2020 12:24:32 -0800 Subject: [PATCH 7/7] Reverted some code formatting --- index.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/index.js b/index.js index fbae8b3..e210ba1 100644 --- a/index.js +++ b/index.js @@ -53,10 +53,7 @@ function postToSensorPush(opts, cb) { cb(err, body, response); }); }); - req.on('error', function (e) { - err = e - } - ); + req.on('error', function (e) { err = e }); req.write(postData); req.end() }