Hello!
I am still pretty new to MagicMirror and coding, but decided it’d be worth it to attempt to build a custom module since I couldn’t find exactly what I was looking for elsewhere. Which brings me to MMM-GroceryApp; which has been built (to the best of my ability) using Kroger Developer documentation.
I am at the point where I have the main module config.js, node_helper_js, authorize,js, and the CSS file functioning in a way that doesn’t break the MagicMirror. Unfortunately, thats all that is happening - I can’t see this module at all when MagicMirror runs, the location I put it remains blank. So obviously I am missing something, and because of that I can’t login to authorize the application.
I changed my repository to public so the code can be viewed there, but I will also post the main and node_helper code below. My MagicMirror config.js for this module is pretty basic:
{
module: "MMM-GroceryApp",
position: "bottom_right"
},
NOTE: The app is set to be on the bottom_right of my 3rd page.
MMM-Kroger.js
Module.register("MMM-GroceryApp", {
defaults: {
refreshInterval: 1000 * 60 * 5, // refresh every 5 minutes
updateInterval: 1000 * 60 * 5 // update every 5 minutes
},
requiresVersion: "2.1.0", // Required version of MagicMirror
start: function() {
var self = this;
Log.info("Starting module: " + this.name);
//Flag for check if module is loaded
this.loaded = false;
this.sendSocketNotification("CONFIG", this.config);
},
getStyles: function () {
return [
"MMM-GroceryApp.css"
];
},
getScripts: function () {
return [
"moment.js"
];
},
getStats: function () {
this.sendSocketNotification("UPDATE", this.config);
},
processData: function(data) {
var self = this;
this.dataRequest = data;
if (this.loaded === false) { self.updateDom(self.config.animationSpeed) ; }
this.loaded = true;
// the data if load
// send notification to node_helper.js
this.sendSocketNotification("MMM-GroceryApp-NOTIFICATION_TEST", data);
},
// socketNotificationReceived from node_helper.js
socketNotificationReceived: function(notification, payload) {
console.log("socketNotificationReceived");
if (notification === "STARTED") {
this.updateDom();
}
else if (notification === "CART_DATA") {
this.loaded = true;
this.processChargeData(JSON.parse(payload).response);
this.updateDom();
}
else if (notification === "PRODUCT_SEARCH") {
this.loaded = true;
this.processDrivestateData(JSON.parse(payload).response);
this.updateDom();
}
else if (notification === "PRODUCT_DETAILS") {
this.loaded = true;
this.processVehicleData(JSON.parse(payload).response);
this.updateDom();
}
else if (notification === "LOCATION_DATA") {
this.loaded = true;
this.processVehicleData(JSON.parse(payload).response);
this.updateDom();
}
},
getDom: function() {
// create element wrapper for show into the module
var self = this;
// create element wrapper for show into the module
var wrapper = document.createElement("div");
wrapper.style.cssText = "float: right;";
// Data from helper
if (this.dataNotification) {
var wrapperDataNotification = document.createElement("div");
// translations + datanotification
wrapperDataNotification.innerHTML = this.translate("UPDATE") + ": " + this.dataNotification.date;
wrapper.appendChild(wrapperDataNotification);
}
return wrapper;
}
});
node_helper.js
const NodeHelper = require("node_helper");
var request = require("request");
module.exports = NodeHelper.create({
start() {
console.log("Starting node helper for: " + this.name);
},
getToken(config) {
try {
const token = getTokenInternal(config);
return token;
} catch (err) {
console.log(err);
return "abc";
}
},
getTokenInternal(config) {
// Set the configuration settings
const credentials = {
client: {
id: config.client_id,
secret: config.client_secret
},
auth: {
tokenHost: "https://api.kroger.com",
tokenPath: "/v1/connect/oauth2/token"
},
http: {
headers: { "User-Agent": "MMM-GroceryApp" }
}
};
const oauth2 = require("Basic").create(credentials);
const tokenConfig = {
grant_type: config.client_credentials,
client_secret: config.client_secret,
client_id: config.client_id
};
try {
var tokenObject = oauth2.client_secret.getToken(tokenConfig);
return tokenObject.access_token;
} catch (error) {
console.log("Access Token Error", error.message);
}
},
getData: function() {
var self = this;
function getCartData(token) {
request.get({
url: baseUrl + "/v1/cart/add",
headers: {
"Accept": "application/json",
"Authorization": "Bearer {{TOKEN}}"
},
"processData": false,
"data": "{\n \"items\": [\n {\n \"upc\": \"0001200016268\",\n \"quantity\": \2\\n }\n ]\n }"
},
function (error, response) {
if (!error && response.statusCode == 400) {
self.sendSocketNotification("CART_DATA", response);
}
});
}
function getProductSearch(token) {
request.get({
url: baseUrl + "/v1/products?filter.brand={{BRAND}}&filter.term={{TERM}}&filter.locationId={{LOCATION_ID}}",
headers: {
"Accept": "application/json",
"Authorization": "Bearer {{TOKEN}}"
},
function (error, response) {
if (!error && response.statusCode == 400) {
self.sendSocketNotification("PRODUCT_SEARCH", response);
}
}}
);
}
function getProductDetails(token) {
request.get({
url: baseUrl + "/v1/products/{{ID}}?filter.locationId={{LOCATION_ID}}",
headers: {
"Accept": "application/json",
"Authorization": "Bearer {{TOKEN}}"
},
function (error, response) {
if (!error && response.statusCode == 400) {
self.sendSocketNotification("PRODUCT_DETAILS", response);
}
}}
);
}
function getLocationData(token) {
request.get({
url: baseUrl + "/v1/locations",
headers: {
"Accept": "application/json",
"Authorization": "Bearer {{TOKEN}}"
},
function (error, response) {
if (!error && response.statusCode == 400) {
self.sendSocketNotification("LOCATION_DATA", response);
}
}}
);
}
if (accessToken === null ) {
var tempToken = getToken(this.config);
var localToken = tempToken.then(function(accessToken){
return accessToken;
});
localToken.then(function(token) {
accessToken = token;
getCartData(token);
getProductSearch(token);
getProductDetails(token);
getLocationData(token);
});
}
else {
getCartData(accessToken);
getProductSearch(accessToken);
getProductDetails(accessToken);
getLocationData(token);
}
},
socketNotificationReceived: function(notification, payload) {
if (notification === "MMM-GroceryApp") {
this.sendSocketNotification("MMM-GroceryApp");
self.config = payload;
self.sendSocketNotification("STARTED", true);
self.getData();
self.started = true;
} else if (notification == "CONFIG") {
self.sendSocketNotification("CART_DATA", self.cart_data);
self.sendSocketNotification("PRODUCT_SEARCH", self.product_search);
self.sendSocketNotification("PRODUCT_DETAILS", self.product_details);
self.sendSocketNotification("LOCATION_DATA", self.location_data);
}
}
});
I really appreciate any assistance and/or tips you are able to provide :)