Related
The gist of the project is: I have Google Form answers that get populated on a Google doc, let's call this doc the template. The template is copied so I never overwrite the original. That copy is converted to PDF, sent to email, and moved to a specific folder on my Drive. This function happens flawlessly with every Form submission and gets triggered on submit. My next function is supposed to send that copied doc to my Google Cloud Print, but I'm having trouble writing the code for that. I have it to the point where it will print the doc on Form submit, but I have to specifically define the doc's ID. Unfortunately the ID is not static since a new doc is made with every submission. Here's my full code minus any sensitive information:
// Work Order
// Get template from Google Docs and name it
var docTemplate = ""; // *** replace with your template ID ***
var docName = "Work Order";
function addDates() {
var date = new Date(); // your form date
var holiday = ["09/04/2017", "10/09/2017", "11/23/2017", "12/24/2017", "12/25/2017", "01/01/2018"]; //Define holiday dates in MM/dd/yyyy
var days = 5; //No of days you want to add
date.setDate(date.getDate());
var counter = 0;
if (days > 0) {
while (counter < days) {
date.setDate(date.getDate() + 1);
var check = date.getDay();
var holidayCheck = holiday.indexOf(Utilities.formatDate(date, "EDT", "MM/dd/yyyy"));
if (check != 0 && check != 6 && holidayCheck == -1) {
counter++;
}
}
}
Logger.log(date) //for this example will give 08/16/2017
return date;
}
function createNewDoc(values) {
//Get information from form and set as variables
var email_address = "";
var job_name = values[1];
var ship_to = values[11];
var address = values[12];
var order_count = values[7];
var program = values[2];
var workspace = values[3];
var offer = values[4];
var sort_1 = values[5];
var sort_2 = values[6];
var image_services = values[9];
var print_services = values[10];
var priority = values[13];
var notes = values[14];
var formattedDate = Utilities.formatDate(new Date(), "EDT", "MM/dd/yyyy");
var expirationDate = Utilities.formatDate(addDates(), "EDT", "MM/dd/yyyy");
// Get document template, copy it as a new temp doc, and save the Doc's id
var copyId = DriveApp.getFileById(docTemplate)
.makeCopy(docName + ' for ' + job_name)
.getId();
// Open the temporary document
var copyDoc = DocumentApp.openById(copyId);
// Get the document's body section
var copyBody = copyDoc.getActiveSection();
// Replace place holder keys,in our google doc template
copyBody.replaceText('keyJobName', job_name);
copyBody.replaceText('keyShipTo', ship_to);
copyBody.replaceText('keyAddress', address);
copyBody.replaceText('keyOrderCount', order_count);
copyBody.replaceText('keyProgram', program);
copyBody.replaceText('keyWorkspace', workspace);
copyBody.replaceText('keyOffer', offer);
copyBody.replaceText('keySort1', sort_1);
copyBody.replaceText('keySort2', sort_2);
copyBody.replaceText('keyImageServices', image_services);
copyBody.replaceText('keyPrintServices', print_services);
copyBody.replaceText('keyPriority', priority);
copyBody.replaceText('keyNotes', notes);
copyBody.replaceText('keyDate', formattedDate);
copyBody.replaceText('keyDue', expirationDate);
// Save and close the temporary document
copyDoc.saveAndClose();
// Convert temporary document to PDF by using the getAs blob conversion
var pdf = DriveApp.getFileById(copyId).getAs("application/pdf");
// Attach PDF and send the email
var subject = "New Job Submission";
var body = "Here is the work order for " + job_name + "";
MailApp.sendEmail(email_address, subject, body, {
htmlBody: body,
attachments: pdf
});
// Move file to folder
var file = DriveApp.getFileById(copyId);
DriveApp.getFolderById("").addFile(file);
file.getParents().next().removeFile(file);
}
function printGoogleDocument(copyId, docName) {
// For notes on ticket options see https://developers.google.com/cloud-print/docs/cdd?hl=en
var ticket = {
version: "1.0",
print: {
color: {
type: "STANDARD_COLOR"
},
duplex: {
type: "NO_DUPLEX"
},
}
};
var payload = {
"printerid": "",
"content": copyId,
"title": docName,
"contentType": "google.kix", // allows you to print google docs
"ticket": JSON.stringify(ticket),
};
var response = UrlFetchApp.fetch('https://www.google.com/cloudprint/submit', {
method: "POST",
payload: payload,
headers: {
Authorization: 'Bearer ' + GoogleCloudPrint.getCloudPrintService().getAccessToken()
},
"muteHttpExceptions": true
});
// If successful, should show a job here: https://www.google.com/cloudprint/#jobs
response = JSON.parse(response);
if (response.success) {
Logger.log("%s", response.message);
} else {
Logger.log("Error Code: %s %s", response.errorCode, response.message);
}
return response;
}
// When Form Gets submitted
function onFormSubmit(e) {
var values = e.values;
createNewDoc(values);
printGoogleDocument(copyId, docName);
}
Return the new document from the 'createNewDoc(values);' function by changing by adding this to the end of the createNewDoc() function, right before the closing bracket:
//Starting at the code here
// Move file to folder
var file = DriveApp.getFileById(copyId);
DriveApp.getFolderById("").addFile(file);
file.getParents().next().removeFile(file);
//Add this
var newDocName = docName + ' for ' + job_name;
return [file, newDocName];
//To this point
}
Then change the onFormSubmit() function as shown below:
// When Form Gets submitted
function onFormSubmit(e) {
var values = e.values;
var returnedDocValues = createNewDoc(values);
var file = returnedDocValues[0];
var docName= returnedDocValues[1];
printGoogleDocument(file, docName);
}
Let me know if there are errors as I have not tested this code myself.
I'm having a few problems with this, so I'll try to keep it simple. What's happening in the first script is a new Google doc file gets made from a copy of a "master" doc I've defined, which gets its data populated from Form submissions, and that new copy is ultimately moved to a Folder on my Drive. The second script is supposed to send that copied file to the Google Cloud Print. The first script works perfect; I have it triggered on a form submit. The second script works by itself, but only when I explicitly define the master doc ID in the "content" section. Because with each Form submission a new doc gets made, I was having trouble integrating the new doc's ID with the second script. Right now, I tried pulling from the var file, but that's not working. I might have a syntax issue.
My other problem is I need to merge my second script with the first, in a way that gets triggered on the same Form Submit and probably execute after the PDF creation and Email send, but before it gets moved to the folder.
Any help or advice would be greatly appreciated.
And I've removed some of my IDs and sensitive information where you only see double quotes.
// Work Order
// Get template from Google Docs and name it
var docTemplate = ""; // *** replace with your template ID ***
var docName = "Work Order";
function addDates() {
var date = new Date(); // your form date
var holiday = ["09/04/2017", "10/09/2017", "11/23/2017", "12/24/2017", "12/25/2017", "01/01/2018"]; //Define holiday dates in MM/dd/yyyy
var days = 5; //No of days you want to add
date.setDate(date.getDate());
var counter = 0;
if (days > 0) {
while (counter < days) {
date.setDate(date.getDate() + 1);
var check = date.getDay();
var holidayCheck = holiday.indexOf(Utilities.formatDate(date, "EDT", "MM/dd/yyyy"));
if (check != 0 && check != 6 && holidayCheck == -1) {
counter++;
}
}
}
Logger.log(date) //for this example will give 08/16/2017
return date;
}
// When Form Gets submitted
function onFormSubmit(e) {
//Get information from form and set as variables
var email_address = "";
var job_name = e.values[1];
var ship_to = e.values[11];
var address = e.values[12];
var order_count = e.values[7];
var program = e.values[2];
var workspace = e.values[3];
var offer = e.values[4];
var sort_1 = e.values[5];
var sort_2 = e.values[6];
var image_services = e.values[9];
var print_services = e.values[10];
var priority = e.values[13];
var notes = e.values[14];
var formattedDate = Utilities.formatDate(new Date(), "EDT", "MM/dd/yyyy");
var expirationDate = Utilities.formatDate(addDates(), "EDT", "MM/dd/yyyy");
// Get document template, copy it as a new temp doc, and save the Doc's id
var copyId = DriveApp.getFileById(docTemplate)
.makeCopy(docName + ' for ' + job_name)
.getId();
// Open the temporary document
var copyDoc = DocumentApp.openById(copyId);
// Get the document's body section
var copyBody = copyDoc.getActiveSection();
// Replace place holder keys,in our google doc template
copyBody.replaceText('keyJobName', job_name);
copyBody.replaceText('keyShipTo', ship_to);
copyBody.replaceText('keyAddress', address);
copyBody.replaceText('keyOrderCount', order_count);
copyBody.replaceText('keyProgram', program);
copyBody.replaceText('keyWorkspace', workspace);
copyBody.replaceText('keyOffer', offer);
copyBody.replaceText('keySort1', sort_1);
copyBody.replaceText('keySort2', sort_2);
copyBody.replaceText('keyImageServices', image_services);
copyBody.replaceText('keyPrintServices', print_services);
copyBody.replaceText('keyPriority', priority);
copyBody.replaceText('keyNotes', notes);
copyBody.replaceText('keyDate', formattedDate);
copyBody.replaceText('keyDue', expirationDate);
// Save and close the temporary document
copyDoc.saveAndClose();
// Convert temporary document to PDF by using the getAs blob conversion
var pdf = DriveApp.getFileById(copyId).getAs("application/pdf");
// Attach PDF and send the email
var subject = "New Job Submission";
var body = "Here is the work order for " + job_name + "";
MailApp.sendEmail(email_address, subject, body, {
htmlBody: body,
attachments: pdf
});
// Move file to folder
var file = DriveApp.getFileById(copyId);
DriveApp.getFolderById("").addFile(file);
file.getParents().next().removeFile(file);
}
function printGoogleDocument(file, docName) {
// For notes on ticket options see https://developers.google.com/cloud-print/docs/cdd?hl=en
var ticket = {
version: "1.0",
print: {
color: {
type: "STANDARD_COLOR"
},
duplex: {
type: "NO_DUPLEX"
},
}
};
var payload = {
"printerid": "",
"content": file,
"title": docName,
"contentType": "google.kix", // allows you to print google docs
"ticket": JSON.stringify(ticket),
};
var response = UrlFetchApp.fetch('https://www.google.com/cloudprint/submit', {
method: "POST",
payload: payload,
headers: {
Authorization: 'Bearer ' + GoogleCloudPrint.getCloudPrintService().getAccessToken()
},
"muteHttpExceptions": true
});
// If successful, should show a job here: https://www.google.com/cloudprint/#jobs
response = JSON.parse(response);
if (response.success) {
Logger.log("%s", response.message);
} else {
Logger.log("Error Code: %s %s", response.errorCode, response.message);
}
return response;
}
**
Update 8/14 with Sandy Good's suggestion:
**
I've attempted to do what you suggested, but now it's not creating the doc or sending to the cloud print. Any thoughts?
// Work Order
// Get template from Google Docs and name it
var docTemplate = ""; // *** replace with your template ID ***
var docName = "Work Order";
function addDates() {
var date = new Date(); // your form date
var holiday = ["09/04/2017", "10/09/2017", "11/23/2017", "12/24/2017", "12/25/2017", "01/01/2018"]; //Define holiday dates in MM/dd/yyyy
var days = 5; //No of days you want to add
date.setDate(date.getDate());
var counter = 0;
if (days > 0) {
while (counter < days) {
date.setDate(date.getDate() + 1);
var check = date.getDay();
var holidayCheck = holiday.indexOf(Utilities.formatDate(date, "EDT", "MM/dd/yyyy"));
if (check != 0 && check != 6 && holidayCheck == -1) {
counter++;
}
}
}
Logger.log(date) //for this example will give 08/16/2017
return date;
}
function createNewDoc(values) {
var email_address = "";
var job_name = e.values[1];
var ship_to = e.values[11];
var address = e.values[12];
var order_count = e.values[7];
var program = e.values[2];
var workspace = e.values[3];
var offer = e.values[4];
var sort_1 = e.values[5];
var sort_2 = e.values[6];
var image_services = e.values[9];
var print_services = e.values[10];
var priority = e.values[13];
var notes = e.values[14];
var formattedDate = Utilities.formatDate(new Date(), "EDT", "MM/dd/yyyy");
var expirationDate = Utilities.formatDate(addDates(), "EDT", "MM/dd/yyyy");
// Get document template, copy it as a new temp doc, and save the Doc's id
var copyId = DriveApp.getFileById(docTemplate)
.makeCopy(docName + ' for ' + job_name)
.getId();
// Open the temporary document
var copyDoc = DocumentApp.openById(copyId);
// Get the document's body section
var copyBody = copyDoc.getActiveSection();
// Replace place holder keys,in our google doc template
copyBody.replaceText('keyJobName', job_name);
copyBody.replaceText('keyShipTo', ship_to);
copyBody.replaceText('keyAddress', address);
copyBody.replaceText('keyOrderCount', order_count);
copyBody.replaceText('keyProgram', program);
copyBody.replaceText('keyWorkspace', workspace);
copyBody.replaceText('keyOffer', offer);
copyBody.replaceText('keySort1', sort_1);
copyBody.replaceText('keySort2', sort_2);
copyBody.replaceText('keyImageServices', image_services);
copyBody.replaceText('keyPrintServices', print_services);
copyBody.replaceText('keyPriority', priority);
copyBody.replaceText('keyNotes', notes);
copyBody.replaceText('keyDate', formattedDate);
copyBody.replaceText('keyDue', expirationDate);
// Save and close the temporary document
copyDoc.saveAndClose();
// Convert temporary document to PDF by using the getAs blob conversion
var pdf = DriveApp.getFileById(copyId).getAs("application/pdf");
// Attach PDF and send the email
var subject = "New Job Submission";
var body = "Here is the work order for " + job_name + "";
MailApp.sendEmail(email_address, subject, body, {
htmlBody: body,
attachments: pdf
});
// Move file to folder
var file = DriveApp.getFileById(copyId);
DriveApp.getFolderById("").addFile(file);
file.getParents().next().removeFile(file);
}
function printGoogleDocument(file, docName) {
// For notes on ticket options see https://developers.google.com/cloud-print/docs/cdd?hl=en
var ticket = {
version: "1.0",
print: {
color: {
type: "STANDARD_COLOR"
},
duplex: {
type: "NO_DUPLEX"
},
}
};
var payload = {
"printerid": "",
"content": file,
"title": docName,
"contentType": "google.kix", // allows you to print google docs
"ticket": JSON.stringify(ticket),
};
var response = UrlFetchApp.fetch('https://www.google.com/cloudprint/submit', {
method: "POST",
payload: payload,
headers: {
Authorization: 'Bearer ' + GoogleCloudPrint.getCloudPrintService().getAccessToken()
},
"muteHttpExceptions": true
});
// If successful, should show a job here: https://www.google.com/cloudprint/#jobs
response = JSON.parse(response);
if (response.success) {
Logger.log("%s", response.message);
} else {
Logger.log("Error Code: %s %s", response.errorCode, response.message);
}
return response;
}
// When Form Gets submitted
function onFormSubmit(e) {
//Get information from form and set as variables
var values = e.values;
createNewDoc(values);
printGoogleDocument(file, docName);
}
Not sure if that is what you are after, but the easiest way to execute functions consecutively is to pass a callback function as an argument to your function.
Here's the list of simple functions assigned to variables.
var addFive = function(number, callback){
number += 5;
if (callback) {
return callback(number);
}
return number;
}
var multiplyByFive = function(number, callback){
number *= 5;
if (callback) {
return callback(number);
}
return number;
}
var subtractFive = function(number, callback){
number -= 5;
if (callback) {
return callback(number);
}
return number;
}
You can then just chain call them like this.
function test() {
var result = addFive(7, function(number) {
return multiplyByFive(number, function(number){
return subtractFive(number);
});
});
Logger.log(result); //logs (7 + 5) * 5 - 5 = 55
}
Of course, if your functions only perform operations like creating files and don't return values, feel free to omit the 'return' statement.
I have more questions in regards to this project, but I think this specific question has been answered, so here's the final code for future reference.
// Work Order
// Get template from Google Docs and name it
var docTemplate = ""; // *** replace with your template ID ***
var docName = "Work Order";
function addDates() {
var date = new Date(); // your form date
var holiday = ["09/04/2017", "10/09/2017", "11/23/2017", "12/24/2017", "12/25/2017", "01/01/2018"]; //Define holiday dates in MM/dd/yyyy
var days = 5; //No of days you want to add
date.setDate(date.getDate());
var counter = 0;
if (days > 0) {
while (counter < days) {
date.setDate(date.getDate() + 1);
var check = date.getDay();
var holidayCheck = holiday.indexOf(Utilities.formatDate(date, "EDT", "MM/dd/yyyy"));
if (check != 0 && check != 6 && holidayCheck == -1) {
counter++;
}
}
}
Logger.log(date) //for this example will give 08/16/2017
return date;
}
function createNewDoc(values) {
//Get information from form and set as variables
var email_address = "";
var job_name = values[1];
var ship_to = values[11];
var address = values[12];
var order_count = values[7];
var program = values[2];
var workspace = values[3];
var offer = values[4];
var sort_1 = values[5];
var sort_2 = values[6];
var image_services = values[9];
var print_services = values[10];
var priority = values[13];
var notes = values[14];
var formattedDate = Utilities.formatDate(new Date(), "EDT", "MM/dd/yyyy");
var expirationDate = Utilities.formatDate(addDates(), "EDT", "MM/dd/yyyy");
// Get document template, copy it as a new temp doc, and save the Doc's id
var copyId = DriveApp.getFileById(docTemplate)
.makeCopy(docName + ' for ' + job_name)
.getId();
// Open the temporary document
var copyDoc = DocumentApp.openById(copyId);
// Get the document's body section
var copyBody = copyDoc.getActiveSection();
// Replace place holder keys,in our google doc template
copyBody.replaceText('keyJobName', job_name);
copyBody.replaceText('keyShipTo', ship_to);
copyBody.replaceText('keyAddress', address);
copyBody.replaceText('keyOrderCount', order_count);
copyBody.replaceText('keyProgram', program);
copyBody.replaceText('keyWorkspace', workspace);
copyBody.replaceText('keyOffer', offer);
copyBody.replaceText('keySort1', sort_1);
copyBody.replaceText('keySort2', sort_2);
copyBody.replaceText('keyImageServices', image_services);
copyBody.replaceText('keyPrintServices', print_services);
copyBody.replaceText('keyPriority', priority);
copyBody.replaceText('keyNotes', notes);
copyBody.replaceText('keyDate', formattedDate);
copyBody.replaceText('keyDue', expirationDate);
// Save and close the temporary document
copyDoc.saveAndClose();
// Convert temporary document to PDF by using the getAs blob conversion
var pdf = DriveApp.getFileById(copyId).getAs("application/pdf");
// Attach PDF and send the email
var subject = "New Job Submission";
var body = "Here is the work order for " + job_name + "";
MailApp.sendEmail(email_address, subject, body, {
htmlBody: body,
attachments: pdf
});
// Move file to folder
var file = DriveApp.getFileById(copyId);
DriveApp.getFolderById("").addFile(file);
file.getParents().next().removeFile(file);
}
function printGoogleDocument(file, docName) {
// For notes on ticket options see https://developers.google.com/cloud-print/docs/cdd?hl=en
var ticket = {
version: "1.0",
print: {
color: {
type: "STANDARD_COLOR"
},
duplex: {
type: "NO_DUPLEX"
},
}
};
var payload = {
"printerid": "",
"content": file,
"title": docName,
"contentType": "google.kix", // allows you to print google docs
"ticket": JSON.stringify(ticket),
};
var response = UrlFetchApp.fetch('https://www.google.com/cloudprint/submit', {
method: "POST",
payload: payload,
headers: {
Authorization: 'Bearer ' + GoogleCloudPrint.getCloudPrintService().getAccessToken()
},
"muteHttpExceptions": true
});
// If successful, should show a job here: https://www.google.com/cloudprint/#jobs
response = JSON.parse(response);
if (response.success) {
Logger.log("%s", response.message);
} else {
Logger.log("Error Code: %s %s", response.errorCode, response.message);
}
return response;
}
// When Form Gets submitted
function onFormSubmit(e) {
var values = e.values;
createNewDoc(values);
printGoogleDocument(file, docName);
}
I have just started learning to code about 5 days ago and what I'm struggling to achieve, is to have an rssfeed-to-twitter script that posts a shortened url instead of a full website/article feed url. I found a node.js module called TinyURL that could do that but i struggle to get it to work. Here's the full script:
var simpleTwitter = require('simple-twitter');
var fs = require('fs');
var http = require('http');
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type' : 'text/plain'});
res.end('RSS Twitter Bot\n');
}).listen(5693);
var timeInterval = 300000; // run every 30m
var timerVar = setInterval (function () {runBot()}, timeInterval);
function runBot(){
var lastCompleted = Date.parse(new Date(0));
console.log(lastCompleted);
try {
var lastcompletedData = fs.readFileSync('./lastCompleted.json', 'utf8');
var timeData = JSON.parse(lastcompletedData);
var lastCompletedFromFile = Date.parse(new Date(timeData.lastCompleted));
if ( isNaN(lastCompletedFromFile) == false ) {
lastCompleted = lastCompletedFromFile;
}
} catch (e) {
console.log(e);
}
fs.readFile('./config.json', 'utf8', function (err, data) {
if (err) console.log(err); // we'll not consider error handling for now
var configData = JSON.parse(data);
console.log(configData);
var twitter = new simpleTwitter( configData.consumerKey //consumer key from twitter api
, configData.consumerSecret //consumer secret key from twitter api
, configData.accessToken //access token from twitter api
, configData.accessTokenSecret //access token secret from twitter api
, 3600);
var dateNow = Date.parse(new Date());
var FeedParser = require('feedparser');
var request = require('request');
var req = request(configData.feedUrl);
var feedparser = new FeedParser();
req.on('error', function (error) {
console.log(error);
});
req.on('response', function (res){
var stream = this;
if (res.statusCode != 200 ) return this.emit('error', new Error('Bad status code'));
stream.pipe(feedparser);
});
feedparser.on('error', function(error) {
console.log(error);
});
feedparser.on('readable', function() {
var stream = this;
var meta = this.meta;
var item;
while (item = stream.read()) {
var itemDate = Date.parse(item.date);
//check to not publish older articles
if (itemDate > lastCompleted){
var titleLength = item.title.length;
var itemTitle = item.title;
var itemLink = item.link;
if (titleLength > 100) {
itemTitle = itemTitle.substring(0, 100);
}
twitter.post('statuses/update'
, {'status' : itemTitle + ' ' + itemLink + " " + configData.tags}
, function (error, data) {
console.dir(data);
});
console.log(itemTitle + ' ' + item.link + configData.tags);
}
}
//TO KNOW WHEN FROM TO START POSTING
var dateCompleted = new Date();
console.log('loop completed at ' + dateCompleted);
var outputData = {
lastCompleted : dateCompleted
}
var outputFilename = './lastCompleted.json';
fs.writeFile(outputFilename, JSON.stringify(outputData, null, 4), function(err) {
if(err) {
console.log(err);
} else {
console.log("JSON saved to " + outputFilename);
}
});
});
});
}
And this is the TinyURL node.js module
var TinyURL = require('tinyurl');
TinyURL.shorten('http://google.com', function(res) {
console.log(res); //Returns a tinyurl
});
Changing the 'http://google.com' string to itemLink var works just fine and prints it in the terminal as expected.
TinyURL.shorten(itemLink, function(res) {
console.log(res); //Returns a tinyurl
});
What i'm trying to achieve is:
twitter.post('statuses/update', {'status' : itemTitle + ' ' + tinyurlLink + " " + configData.tags}
How can i get the response turned into a e.g var tinyurlLink to replace the itemLink var? Any help would be much appreciated!
As suggested by #zerkms sending a tweet from inside the TinyURL.shorten worked!
Hello all I have to need to add two field values {type:Number} of one collection from MongoDB using node js
and store the result in the same collection of MongoDB
1st node js query fetching the data value from MongoDB inside my controller.
2nd trying to add the fetched value.
3rd store the result in the same collection of MongoDB using node js.
1). Node js
var levelScoreQuiz = require('../models/levelscoreSchema.js');
try{
var queryObj = {};
var projection = '-id child.quiz_level.score_pre';
var projection2 = '-id child.quiz_level.score_curr';
var a = levelScoreQuiz.findOne(queryObj,projection);
var b = levelScoreQuiz.findOne(queryObj,projection2);
//console.log(a);
//console.log(b);
var add = a + b;
//console.log(add);
res.send(add);
var userObj = {
level_pre:req.params.add
};
var user = new levelScoreQuiz(userObj);
user.save(function(err, result){
if (err) {
console.log('Error While Saving the reuslt ' +err)}
else{
//console.log("User score saved successfully");
console.log("User Previous score saved successfully");
res.json(result);
}
});
}catch(err){
console.log('Error While Saving the reuslt ' +err);
return next(err);
}
2). MongoDB Schema
var userScore = new Schema({
child: {
quiz_level:{
current_level:{type:Number},
score_pre:{type:Number},
score_curr:{type:Number}
}
}
});
3). Result: it shows me object in my browser
"[object Object][object Object]"
var levelScoreQuiz = require('../models/levelscoreSchema.js');
try{
var queryObj = {};
var projection = {id: 0, 'child.quiz_level.score_pre': 1};
var projection2 = {id: 0, 'child.quiz_level.score_curr': 1};
var a = levelScoreQuiz.findOne(queryObj,projection);
var b = levelScoreQuiz.findOne(queryObj,projection2);
//console.log(a);
//console.log(b);
var add = a.child.quiz_level.score_pre +
b.child.quiz_level.score_curr;
//console.log(add);
res.send(add);
var userObj = {
child: {quiz_level: { score_pre: req.params.add}}
};
var user = new levelScoreQuiz(userObj);
user.save(function(err, result){
if (err) {
console.log('Error While Saving the reuslt ' +err)}
else{
//console.log("User score saved successfully");
console.log("User Previous score saved successfully");
res.json(result);
}
});
}catch(err){
console.log('Error While Saving the reuslt ' +err);
return next(err);
}
I am trying to learn node JS and am currently attempting to extend this article.
http://www.gianlucaguarini.com/blog/push-notification-server-streaming-on-a-mysql-database/
I am having major issue because I am getting multiple updates in the SQL query.
I only want to send one socket update.
This issue is in the transactions loop I get multiple socket updates.
I have been struggling with this for over a month and can't seem to figure it out on my own (or with google searches)
Can someone please tell me how I can make this work so I only get one socket update per client.
What I would like to happen is when there is a change in one of the transactions that the two parties (buyer and seller) are the only ones that get the socket update.
How can I make this work? It is so close to what I want it do but I can't get over this last challenge.
Please help.
Thank you in advance.
<html>
<head>
<title>GAT UPDATER</title>
<script src="/socket.io/socket.io.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
<script src = "http://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js"></script>
<script type="text/javascript" src="http://board.gameassettrading.com/js/jquery.cookie.js"></script>
</head>
<body>
<script>
var nodeuserid;
function getUserId() {
var url = window.location.href;
var user_id = url.replace('http://heartbeat.gameassettrading.com:4000/id/', '');
return user_id;
}
user_id = getUserId();
$.cookie('useridcookie', user_id, { expires: 1 });
var useridcookie = $.cookie("useridcookie");
// Get Base Url for development between local and dev enviroment
function getBaseURL() {
var url = location.href; // entire url including querystring - also: window.location.href;
var baseURL = url.substring(0, url.indexOf('/', 14));
if (baseURL.indexOf('http://localhost') != -1) {
// Base Url for localhost
var url = location.href; // window.location.href;
var pathname = location.pathname; // window.location.pathname;
var index1 = url.indexOf(pathname);
var index2 = url.indexOf("/", index1 + 1);
var baseLocalUrl = url.substr(0, index2);
return baseLocalUrl + "/";
}
else {
// Root Url for domain name
return baseURL + "/";
}
}
// set the base_url variable
base_url = getBaseURL();
document.domain = "transactionsserver.com"
// create a new websocket
var socket = io.connect('http://heartbeat.transactionsserver.com:4000');
socket.on('connect',function() {
var data = {
url: window.location.href,
};
socket.emit('client-data', data);
});
// this is always open you have to filter out the data you want
socket.on('notification', function (data) {
if(data.hasOwnProperty("data")) {
if(data.data[0]['seller_id'] != ''){
$('#StatusUpdate', window.parent.document).text( data.data[0]['seller_id']+ ':' + data.data[0]['seller_status'] +':'+ data.data[0]['buyer_id']+':'+ data.data[0]['buyer_status']).click();
}
}
window.parent.checkData(data,user_id);
if(data.hasOwnProperty("changed_user_id")) {
$('#StatusUpdate', window.parent.document).text( data.changed_user_id+ ':' + data.changed_user_status +':'+ data.changed_user_id).click();
}
});
</script>
</body>
</html>
Server . js
var app = require("express")();
var path = require('path');
var mysql = require("mysql");
var http = require('http').Server(app);
var io = require("socket.io")(http);
var sockets = {};
var mysql = require('mysql'),
connectionsArray = [],
connection = mysql.createConnection({
multipleStatements: true,
host: 'localhost',
user: '*****',
password: '******',
database: 'transactionsdb',
port: 3306
}),
POLLING_INTERVAL = 1000,
pollingTimer;
// Add Redis For Comparing SQL Results againts Cache
var redis = require('redis');
var client = redis.createClient();
var express = require('express');
/* Creating POOL MySQL connection.*/
var pool = mysql.createPool({
connectionLimit: 100,
host: 'localhost',
user: '*****',
password: '*****',
database: 'transactionsdb',
debug: false
});
var count = 0;
var clients = [];
function processAllTransactions(sellsreply) {
pool.query('SELECT t.id,t.status,t.original_status, t.active, t.buyer_id, t.seller_id, t.seller_acked, t.seller_complete, t.buyer_complete, b.user_status as buyer_status,t.chat_ended, s.user_status as seller_status FROM transaction t LEFT JOIN sf_guard_user_profile s ON s.user_id = t.seller_id LEFT JOIN sf_guard_user_profile b ON b.user_id = t.buyer_id WHERE active = 1 LIMIT 1', [sellsreply], function (err, sells) {
if (sells != '') {
// attempt to stop the updates if it's not the the active transaction
client.get('active transaction id:'+sellsreply, function (err, active_transaction_id) {
passed_active_transaction_id = active_transaction_id;
});
// is there a trasnaction with status defined and transation id does not equal the active transaction id
if(sells[0].status !== undefined && sells[0].id !== passed_active_transaction_id )
{
client.get('active transaction:'+sellsreply, function (err, data1) {
if(JSON.stringify(sells) != data1){
client.set('active transaction id:'+sellsreply,sells[0]["id"]);
client.set('active transaction:'+sellsreply,JSON.stringify(sells));
console.log(JSON.stringify(sells));
updateSockets({
data: sells // pass the database result
});
}
});
}
}
});
}
// Method
function getUserInfo(user_id, callback) {
var query = connection.query('SELECT user_status from sf_guard_user_profile WHERE user_id = ' + connection.escape(user_id));
query.on('result', function (row) {
callback(null, row.user_status);
});
}
var updateSockets = function (data) {
// adding the time of the last update
data.time = new Date();
console.log('Pushing new data to the clients connected ( connections amount = %s ) - %s', connectionsArray.length , data.time);
// sending new data to all the sockets connected
connectionsArray.forEach(function (tmpSocket) {
console.log(tmpSocket);
tmpSocket.volatile.emit('notification', data);
});
};
var pollingLoop = function () {
var socket;
for (var id in sockets) {
socket = sockets[id];
client.get("uuid:" + socket.id, function (err, useridreply) {
processAllTransactions(useridreply);
});
}
connection.query('SELECT * FROM sf_guard_user_profile; select * FROM transaction', function (err, result) {
// error check
if (err) {
console.log(err);
updateSockets(err);
throw err;
} else {
// loop through the queries
var element =
// compare the cache results againt the database query for users
result[0].forEach(function (element, index, array) {
client.get('logged_in:' + element.user_id, function (err, reply) {
if (reply === null) {
// console.log( element.user_id + ' is disconnected');
}
else {
// console.log(reply);
}
});
client.get("user:" + element.user_id, function (err, userreply) {
if (element.user_status != userreply) {
client.set('user:' + element.user_id, +element.user_status);
changed_users.push(element);
console.log(element.user_id + " is now set to: " + element.user_status);
updateSockets({
changed_user_id: element.user_id,
changed_user_status: element.user_status
});
}
});
});
}
// loop on itself only if there are sockets still connected
if (connectionsArray.length) {
pollingTimer = setTimeout(pollingLoop, POLLING_INTERVAL);
// reset changed users and changed transactions arrays
changed_users = [];
changed_transactions = [];
} else {
console.log('The server timer was stopped because there are no more socket connections on the app');
}
});
};
// count the connections array
Array.prototype.contains = function (k, callback) {
var self = this;
return (function check(i) {
if (i >= self.length) {
return callback(false);
}
if (self[i] === k) {
return callback(true);
}
return process.nextTick(check.bind(null, i + 1));
}(0));
};
io.sockets.on('connection', function (socket) {
// runs for every connection
sockets[socket.id] = socket;
socket.on('client-data', function (data) {
// get the user id from the url that is passed onload
var user_id = data.url.replace('http://servernameremoved.com:4000/id/', '');
console.log('user id ' + user_id + ' is connected with session id ' + socket.id);
client.set('uuid:' + socket.id, +user_id);
});
console.log('Number of connections:' + (connectionsArray.length));
// starting the loop only if at least there is one user connected
if (!connectionsArray.length) {
pollingLoop();
}
socket.on('disconnect', function (socketIndex) {
delete sockets[socket.id];
client.get("uuid:" + socket.id, function (err, userreply) {
console.log('user id ' + userreply + ' got redis disconnected');
});
socketIndex = connectionsArray.indexOf(socket);
console.log('socketID = %s got disconnected', socketIndex);
if (~socketIndex) {
connectionsArray.splice(socketIndex, 1);
}
});
connectionsArray.push(socket);
});
// express js route
app.get('/id/:id', function (req, res) {
clients.contains(req.params.id, function (found) {
if (found) {
console.log("Found");
} else {
client.set('logged_in:' + req.params.id, +req.params.id + 'is logged in');
}
});
res.sendFile(__dirname + '/client.html');
});
// build the server
http.listen(4000, function () {
console.log("Server Started");
});
Here is the console log results
Pushing new data to the clients connected ( connections amount = 2 ) - Sat May 30 2015 21:16:23 GMT-0700 (PDT)
30 2015 21:15:15 GMT-0700 (PDT)
user id 3 is connected with session id CRTtkRIl7ihQ2yaEAAAA
user id 2 is connected with session id wNG7XDcEDjhYKBEIAAAB
***********************************************
[{"id":1,"status":20,"original_status":15,"active":1,"buyer_id":2,"seller_id":1,"seller_acked":1,"seller_complete":0,"buyer_complete":1,"buyer_status":4,"chat_ended":"2015-05-31T03:58:40.000Z","seller_status":4}]
***********************************************
Pushing new data to the clients connected ( connections amount = 2 ) - Sat May 30 2015 21:16:23 GMT-0700 (PDT)
***********************************************
[{"id":1,"status":20,"original_status":15,"active":1,"buyer_id":2,"seller_id":1,"seller_acked":1,"seller_complete":0,"buyer_complete":1,"buyer_status":4,"chat_ended":"2015-05-31T03:58:40.000Z","seller_status":4}]
***********************************************
Pushing new data to the clients connected ( connections amount = 2 ) - Sat May 30 2015 21:16:23 GMT-0700 (PDT)