This article explains how to Integrated Google sheet with your Nodejs Application. There are several use-cases where integrating google sheet with your application is crucial.
Demo
Recent Articles
Kubernetes for Nodejs Developers
Building a Production-grade Nodejs,GraphQL and TypeScript Server - Testing and Docker
Consider that you are building a coach booking application where you need to send the total bookings for a specific month to the sales team periodically. you can achieve this using,
- There can be a button on the CRM dashboard where Salespeople can go and export the booking data from the database to Google Sheet or as PDF.
Even though it works, it still involves some manual process of going to the dashboard and export it to the google sheet. I would say, we can still automate this process and make it easier.
Here's the updated workflow,
Setup and Install
Let's install the dependencies for our project here,
npm install express body-parser ejs express-ejs-layouts node-fetch
- express - library for http webserver to handle the request and response.
- body-parser - it is used to parse the POST request body.
- ejs - it is a template engine used to handle the views in our express application.
- express-ejs-layouts - mapper library between expressjs and ejs template engine.
- node-fetch - fetch library used to make htttp request from nodejs to external url.
After that, create a file app.js and add the basic express setup inside that file.
constexpress=require("express")constapp=express()// Express body parserapp.use(express.urlencoded({extended:true}))app.get("/",(req,res)=>{res.send("dashboard")})app.listen(3005,()=>{console.log("Server is running on PORT 3005")})
Now, let's add the template engine into our express application.
constexpressLayouts=require("express-ejs-layouts")app.use(expressLayouts)app.set("view engine","ejs")
our views folder will look like,
Inside the dashboard, we will have a form that sends us the form data to our express application. let's create a POST route to handle it inside our express application.
app.post("/save",(req,res)=>{constusername=req.body.usernameconstemail=req.body.emailconstphone=req.body.phoneconstfromdate=req.body.fromdateconsttodate=req.body.todate// GOOGLE SHEET LOGIC COMES HEREres.render("success")})
Now, it is time to integrate google sheet into our application. There are several ways to do it. Here, we are going to use a simple and quick solution that solves our problem.
Let's create a google sheet first
Here, you have a tab called Tools
. Click on that, you can see Script editor
where we can write our script for this sheet.
Here, we are going to write a script that adds the data based on the Column Name inside our sheet. let's add field name from our application as a column name in the sheet.
Once we add that, we can write a script to add the value respective the column name that comes from the nodejs application.
Check out the script from the source here
// original from: http://mashe.hawksey.info/2014/07/google-sheets-as-a-database-insert-with-apps-script-using-postget-methods-with-ajax-example/functiondoGet(e){returnhandleResponse(e)}// Usage// 1. Enter sheet name where data is to be written belowvarSHEET_NAME="Sheet1"// 2. Run > setup//// 3. Publish > Deploy as web app// - enter Project Version name and click 'Save New Version'// - set security level and enable service (most likely execute as 'me' and access 'anyone, even anonymously)//// 4. Copy the 'Current web app URL' and post this in your form/script action//// 5. Insert column names on your destination sheet matching the parameter names of the data you are passing in (exactly matching case)varSCRIPT_PROP=PropertiesService.getScriptProperties()// new property service// If you don't want to expose either GET or POST methods you can comment out the appropriate functionfunctiondoPost(e){returnhandleResponse(e)}functionhandleResponse(e){// shortly after my original solution Google announced the LockService[1]// this prevents concurrent access overwritting data// [1] http://googleappsdeveloper.blogspot.co.uk/2011/10/concurrency-and-google-apps-script.html// we want a public lock, one that locks for all invocationsvarlock=LockService.getPublicLock()lock.waitLock(30000)// wait 30 seconds before conceding defeat.try{// next set where we write the data - you could write to multiple/alternate destinationsvardoc=SpreadsheetApp.openById(SCRIPT_PROP.getProperty("key"))varsheet=doc.getSheetByName(SHEET_NAME)// we'll assume header is in row 1 but you can override with header_row in GET/POST datavarheadRow=e.parameter.header_row||1varheaders=sheet.getRange(1,1,1,sheet.getLastColumn()).getValues()[0]varnextRow=sheet.getLastRow()+1// get next rowvarrow=[]// loop through the header columnsfor(iinheaders){if(headers[i]=="Timestamp"){// special case if you include a 'Timestamp' columnrow.push(newDate())}else{// else use header name to get datarow.push(e.parameter[headers[i]])}}// more efficient to set values as [][] array than individuallysheet.getRange(nextRow,1,1,row.length).setValues([row])// return json success resultsreturnContentService.createTextOutput(JSON.stringify({result:"success",row:nextRow})).setMimeType(ContentService.MimeType.JSON)}catch(e){// if error return thisreturnContentService.createTextOutput(JSON.stringify({result:"error",error:e})).setMimeType(ContentService.MimeType.JSON)}finally{//release locklock.releaseLock()}}functionsetup(){vardoc=SpreadsheetApp.getActiveSpreadsheet()SCRIPT_PROP.setProperty("key",doc.getId())}
Note: Don't forget to change the sheet name in the script before deploy.
After that, save the script, run the function setup
from the script, and deploy it as a web app by clicking the Publish
tab.
Once you click the Deploy, you need to make sure that you configure it correctly. select the Execute the app as
→ Me and Access Level as Anyone
Now, it will give you a web app URL. copy and store it inside your nodejs application.
Now, coming back to our application, we just need to run GET request on the URL to save the data to google sheet.
app.post("/save",(req,res)=>{constusername=req.body.usernameconstemail=req.body.emailconstphone=req.body.phoneconstfromdate=req.body.fromdateconsttodate=req.body.todateconsturl=`${GOOGLE_SHEET_URL}?Name=${encodeURIComponent(username)}&Email=${encodeURIComponent(email)}&Phone=${encodeURIComponent(phone)}&FromDate=${encodeURIComponent(fromdate)}&ToDate=${encodeURIComponent(todate)}`fetch(url).then(res=>{returnres.json()}).then(res=>console.log("google sheet res",{res})).catch(error=>console.error(error))res.render("success")})
Here, we pass all the data as a query parameter. make sure the name matches with a column name that we have given in the google sheet.