Labels

Learn the powerful enterprise adaptable database:

Getting Started With ADABAS & Natural

Monday, February 1, 2016

1003 Handle REST Service


.
1003 Handle REST Service
How to write Google App Script to handle REST Service

Objective

1. Create generic record utility functions
        addRecord()
        editRecord()
        deleteRecord()
        selectRecord()
        selectRecords()
2. Create record utility manager ie manageRecord()

1) Create a spreadsheet

eg HandleRestService.
Create  a sheet “persons”.
Set the first row…

tid
timestamp
name
pid
age
Set the field format for the fields especially tid field...

2) Open Code Editor within the spreadsheet

eg HandleRestService.

3) Edit the Script

We write few functions to perform specific tasks:

logGlobalVar()
Log the global var
doGet() and doPost()
To handle Get and Post request
handleResponse()
Read action value and respond
manageRecords
Handle record management request and return TextOutput
findInArray
Find string in the array
addRecords(), editRecords(), deleteRecords(), selectRecord(), selectRecords()
Record management functions
Test functions
To test for expected results

/*global var*/
var SCPID=ScriptApp.getScriptId(); /*script id*/
var SST=SpreadsheetApp.getActiveSpreadsheet(); /*active spreadsheet */
var SSTID=SpreadsheetApp.getActiveSpreadsheet().getId(); /*spreadsheet id*/
var SSTFILE=DriveApp.getFileById(SSTID); /*get file*/
var Folders = SSTFILE.getParents(); /*get parent collection*/
 while (Folders.hasNext()) {
   var Folder = Folders.next();
   Logger.log(Folder.getName());
   var FOLID = Folder.getId(); /*get id for first parent item*/
 }
/*log the global var*/
function logGlobalVar(){
  Logger.log("script id:"+SCPID);
  Logger.log("sheet id:"+SSTID);
  Logger.log("folder id:"+FOLID);
  Logger.log("SST:"+SST.getName());  
}
/* web request listeners */
function doGet(e) {return handleResponse(e);}
function doPost(e) {return handleResponse(e);}
/* handle action request */
function handleResponse(e) {
 var lock = LockService.getPublicLock();
 lock.waitLock(30000); // wait 30 seconds before conceding defeat.
  try {
    var action = e.parameter.action;
    if (action == 'test') {
      return getTest(e);
    }else if (action == 'addperson') {
      return manageRecords("addperson",e); //records command,parameter
    }else if (action == 'editperson') {
      return manageRecords("editperson",e);
    }else if (action == 'deleteperson') {
      return manageRecords("deleteperson",e);
    }else if (action == 'selectperson') {
      return manageRecords("selectperson",e);
    }else if (action == 'selectpersons') {
      return manageRecords("selectpersons",e);
    }
  }
 catch (e) {/*if error return this*/return ContentService.createTextOutput(JSON.stringify({"result": "error","error": e})).setMimeType(ContentService.MimeType.JSON);}
 finally { /*release lock*/ lock.releaseLock();}
}
/* handle records management */
function manageRecords(command,e){
  var output;  
  switch (command){
    case "addperson":
      output=addRecord("persons",e);
      break;
    case "editperson":
      output=editRecord("persons",e);
      break;
    case "deleteperson":
      output=deleteRecord("persons",e);
      break;
    case "selectperson":
      output=selectRecord("persons",e);
      break;      
    case "selectpersons":
      output=selectRecords("persons",e);
      break;      
  }
  return ContentService
  .createTextOutput(JSON.stringify(output))
  .setMimeType(ContentService.MimeType.JSON);
}
/* findInArray(array,colno,searchvalue){} */
/* find a string in array row and columns */
/* if colnos is null then concat all cols */
function findInArray(array,colnos,searchvalue){
  output=[];
  for (var rowno in array){
      if (colnos==null){ /*concat cols*/
        //Logger.log(array[rowno]);
        var strtest=JSON.stringify(array[rowno]);
        var n = strtest.search(searchvalue);
        if (n>=0){
          array[rowno].unshift(rowno);
          output.push(array[rowno]);
        }
      }/*if (colnos==null)*/
        else{
          var strtest='';
          for(var colno in colnos){
            strtest=strtest.concat((strtest==''?'':','),array[rowno][colnos[colno]]);
          }
          //Logger.log(strtest);          
          var n = strtest.search(searchvalue);
          if (n>=0){
           array[rowno].unshift(rowno);
           output.push(array[rowno]);
          }/*if*/    
        }/*else*/
  }/*row*/
  return output;
}/*function findInArray*/
function testFindInArray(){
  var array=[['dadu','0','badi'],['didi','1','bada'],['dida','2','bidi'],['didu','3','bidu']];
  //output=findInArray(array,null,"da");
  //Logger.log(output);
  //output=findInArray(array,[2],"da");
  //Logger.log(output);
  output=findInArray(array,[0,2],"da");
  Logger.log(output);  
}
/* ref: https://github.com/AishwaryT/Google-app-script-crud/blob/master */
/* add record */
function addRecord(recordsname, e) {
  var Sheet = SST.getSheetByName(recordsname);
  try {
    // we'll assume header is in row 1 but you can override with header_row in GET/POST data
    var headRow = e.parameter.header_row || 1;
    var headers = Sheet.getRange(headRow, 1, 1, Sheet.getLastColumn()).getValues()[0];
    var rownum = Sheet.getLastRow() + 1; // get next row
    var row = [];
    var d = new Date();
    // loop through the header columns
    for (colno in headers) {
      if (headers[colno] == "tid") { // special case if you include a 'timestamp' column
        row.push(d.getTime());
        } else if (headers[colno] == "timestamp") { // special case if you include a 'timestamp' column
          row.push(d);
          } else { // else use header name to get data
            row.push(e.parameter[headers[colno]]);
            }
      }
    // more efficient to set values as [][] array than individually
    Sheet.getRange(rownum, 1, 1, row.length).setValues([row]);
    // return json success results with the row number of the newly added record
    return rownum
    } catch (e) {
      // if error return this
      return 0
      }
}
/* edit record */
function editRecord(recordsname, e) {
  var Sheet = SST.getSheetByName(recordsname);
  try {
    // we'll assume header is in row 1 but you can override with header_row in GET/POST data
    var headRow = e.parameter.header_row || 1;
    var headers = Sheet.getRange(headRow, 1, 1, Sheet.getLastColumn()).getValues()[0];
    var array =Sheet.getRange(2, 1, Sheet.getLastRow()-1, Sheet.getLastColumn()).getValues();
    var found=findInArray(array,[0],e.parameter['tid']);/*found is array*/
    if (found.length>0){
      var rownum=Number(found[0][0]);/*pickup the first item of the first row ie the array row num*/
      rownum+=2;/*change from zero-based to one-based and add the headRow*/
    }
    //Logger.log(e.parameter['tid']);
    //Logger.log(rownum);
    if (rownum == undefined) {
      //row not found
      return -1
      }
    var row = [];
    var d = new Date();
    // loop through the header columns
    for (i in headers) {
      if (headers[i] == "tid") { // special case if you include a 'tid' column
        row.push(e.parameter['tid']);
        } else if (headers[i] == "timestamp") { // special case if you include a 'timestamp' column
          row.push(d);
          } else { // else use header name to get data
            row.push(e.parameter[headers[i]]);
            }
      }
    Sheet.getRange(rownum, 1, 1, row.length).setValues([row]);
    // return json success results with the row number of the newly added record
    return rownum;
    } catch (e) {
      // if error return this
      return 0
      }
}
/* test edit record */
function testEditRecord(){
  var parameter={action:'editrecord',tid:'1499613316279',name:'vovoi',pid:'7474',age:'44'};
  var e={parameter:parameter};
  Logger.log(editRecord('persons', e));      
}
/* delete record */
function deleteRecord(recordsname, e) {
  var Sheet = SST.getSheetByName(recordsname);
  try {
    // we'll assume header is in row 1 but you can override with header_row in GET/POST data
    var headRow = e.parameter.header_row || 1;
    var headers = Sheet.getRange(headRow, 1, 1, Sheet.getLastColumn()).getValues()[0];
    var array =Sheet.getRange(2, 1, Sheet.getLastRow()-1, Sheet.getLastColumn()).getValues();
    var found=findInArray(array,[0],e.parameter['tid']);/*found is array*/
    if (found.length>0){
      var rownum=Number(found[0][0]);/*pickup the first item of the first row ie the array row num*/
      rownum+=2;/*change from zero-based to one-based and add the headRow*/
    }
    //Logger.log(e.parameter['tid']);
    //Logger.log(rownum);
    if (rownum == undefined) {
      //row not found
      return -1
      }
    // delete row by rownum
    Sheet.deleteRow(rownum);
    return rownum
  } catch (e) {
    // if error return this
    return 0
  }
}
/* test delete record */
function testDeleteRecord(){
  var parameter={action:'deleterecord',tid:'1499613316279'};
  var e={parameter:parameter};
  Logger.log(deleteRecord('persons', e));      
}
/* select record */
function selectRecord(recordsname, e) {
  var Sheet = SST.getSheetByName(recordsname);
  try {
    // we'll assume header is in row 1 but you can override with header_row in GET/POST data
    var headRow = e.parameter.header_row || 1;
    var headers = Sheet.getRange(headRow, 1, 1, Sheet.getLastColumn()).getValues()[0];
    var array =Sheet.getRange(2, 1, Sheet.getLastRow()-1, Sheet.getLastColumn()).getValues();
    var found=findInArray(array,[0],e.parameter['tid']);/*found is array*/
    if (found.length>0){
      var rownum=Number(found[0][0]);/*pickup the first item of the first row ie the array row num*/
      rownum+=2;/*change from zero-based to one-based and add the headRow*/
    }
    //Logger.log(e.parameter['tid']);
    //Logger.log(rownum);
    if (rownum == undefined) {
      //row not found
      return -1
      }
    var row = {};
    row['_row']=rownum;    
    var values = Sheet.getRange(rownum, 1, 1, Sheet.getLastColumn()).getValues()[0];
    for (i in headers) {
      row[headers[i]] = values[i];
      }
    // return json success results with the row
    return row;
    } catch (e) {
      // if error return this
      return e;
      }
}
/* test select record */
function testSelectRecord(){
  var parameter={action:'selectrecord',tid:'1498794221687'};
  var e={parameter:parameter};
  Logger.log(selectRecord('persons', e));      
}
/* get all records */
function selectRecords(recordsname, e) {
  var Sheet = SST.getSheetByName(recordsname);
  try {  
  // we'll assume header is in row 1 but you can override with header_row in GET/POST data
  var headRow = e.parameter.header_row || 1;
  var headers = Sheet.getRange(headRow, 1, 1, Sheet.getLastColumn()).getValues()[0];
  var rownum = Sheet.getLastRow()-1;
  //Logger.log(e.parameter['tid']);
  //Logger.log(rownum);
  if (rownum == undefined||rownum==1) {
    //row not found
    return -1
  }
  var rows = [];
  var values = Sheet.getRange(2, 1, Sheet.getLastRow(), Sheet.getLastColumn()).getValues();
  for (var i = 0; i < values.length - 1; i++) {
    var row = {};
    row['_row']=i+2;/*change from zero-based to one-based and add the headRow*/    
    for (j in headers) {
      row[headers[j]] = values[i][j];
      }
    rows.push(row);
    }
  return rows;
} catch (e) {
  return e;
  }
}
/* test select records */
function testSelectRecords(){
  var parameter={action:'selectrecords'};
  var e={parameter:parameter};
  Logger.log(selectRecords('persons', e));      
}

4) Publish as Web App

Deploy

Execute the app using your account (because the app needs to access the spreadsheet that is privately accessible by your account only) but allow anyone to access the apps.

5) Test

You can test by entering the URL request with parameters eg
Or, you can use REST tool such as postman or https://resttesttest.com/ .

COPY:

REFS:



.

1002 Handle Web Requests


.
1002 Handle Web Requests

How to write Google App Script to handle Web Requests

1) Create a spreadsheet

eg HandleWebRequest.

2) Open Code Editor within the spreadsheet

eg HandleWebRequest.

3) Edit the script

/*global var*/
var SCPID=ScriptApp.getScriptId(); /*script id*/
var SSTID=SpreadsheetApp.getActiveSpreadsheet().getId(); /*spreadsheet id*/
/*var DOCID=DocumentApp.getActiveDocument().getId();*/ /*document id*/
/*var FRMID=FormApp.getActiveForm().getId();*/ /*form id*/
var SSTFILE=DriveApp.getFileById(SSTID); /*get file*/
var Folders = SSTFILE.getParents(); /*get parent collection*/
var Folder = Folders.next(); /*get first parent item*/
var FOLID = Folder.getId(); /*get id for first parent item*/
/*log the global var*/
function logGlobalVar(){
Logger.log("script id:"+SCPID);
Logger.log("sheet id:"+SSTID);
Logger.log("folder id:"+FOLID);
}
/* web request listeners */
function doGet(e) {return handleResponse(e);}
function doPost(e) {return handleResponse(e);}
/* web request handler */
function handleResponse(e) {
  var lock = LockService.getPublicLock();
  lock.waitLock(30000); // wait 30 seconds before conceding defeat.
  try {
    var action = e.parameter.action;
    if (action == 'test') {
      return getTest(e);
    }      
  }
  catch (e) {/*if error return this*/return ContentService.createTextOutput(JSON.stringify({"result": "error","error": e})).setMimeType(ContentService.MimeType.JSON);}
  finally { /*release lock*/ lock.releaseLock();}  
}
/* test function */
function getTest(e){
  rows={a:1,b:2};
  var output = JSON.stringify({"result":"success", "value": rows});
    if (e.parameter.callback){
      // if error return this, again, in jsonp
      return ContentService
          .createTextOutput(e.parameter.callback+"("+ output + ");")
          .setMimeType(ContentService.MimeType.JAVASCRIPT);
    }
    else{
      return ContentService
          .createTextOutput(output)
          .setMimeType(ContentService.MimeType.JSON);
    }  
}

4) Publish as Web App

5) Access the URL

COPY:


.

1001 Apps Script Web App URL Fetch


.

1001 Apps Script Web App URL Fetch
How to access other resources on the web by fetching URLs

Objective

1. Create doGet and doPost Method
2. Create testGet and testPost Method.
3. Create getRequest Method.

1. Create a stand-alone script

eg UrlFetchApp

2. Edit the script

The following codes were modified from the original codes published at: https://ctrlq.org/code/19871-get-post-requests-google-script 
function doGet(e) {

 if(typeof e !== 'undefined')
   return ContentService.createTextOutput(JSON.stringify(e.parameter));

}

function doPost(e) {

 if(typeof e !== 'undefined')
   return ContentService.createTextOutput(JSON.stringify(e.parameter));

}

function testPOST() {

 var url = ScriptApp.getService().getUrl();

 var payload =
     {
       "name" : "a",
       "blog" : "a.com",
       "type" : "post",
     };

 var options =
     {
       "method"  : "POST",
       "payload" : payload,  
       "followRedirects" : true,
       "muteHttpExceptions": true
     };

 var result = UrlFetchApp.fetch(url, options);

 if (result.getResponseCode() == 200) {
 
   var params = JSON.parse(result.getContentText());
 
   Logger.log(params.name);
   Logger.log(params.blog);
 
 }

}

function testGET() {

 var queryString = "?name=a&blog=a.com&type=get";

 var url = ScriptApp.getService().getUrl() + queryString;

 var options =
     {
       "method"  : "GET",  
       "followRedirects" : true,
       "muteHttpExceptions": true
     };
 
 var result = UrlFetchApp.fetch(url, options);

 if (result.getResponseCode() == 200) {
 
   var params = JSON.parse(result.getContentText());
 
   Logger.log(params.name);
   Logger.log(params.blog);
 
 }
}
function testGetRequest(){

  var url = ScriptApp.getService().getUrl();
  var payload =
      {
        "name" : "a",
        "blog" : "a.com",
        "type" : "get",
      };

  var params =
      {
        "method"  : "GET",
        "payload" : payload,  
        "followRedirects" : true,
        "muteHttpExceptions": true
      };  

 var response = UrlFetchApp.getRequest(url,params);
 for(i in response) {
   Logger.log(i + ": " + response[i]);
 }
}

3) Test

3.1) Potential Errors

You may get two potential errors if you do not set the following properties correctly.

1. Deploy the script as web app.

Otherwise you will get the following error messages.

DNS error: http://null?name=a&blog=a.com&type=get (line 60, file "Code")
testGet error messages
Attribute provided with no value: url (line 34, file "Code")
testPost error messages

2. Allow everyone to run the script.

Otherwise you will get the following error messages.

SyntaxError: Unexpected token: < (line 64, file "Code")
testGet error messages

3.2) Get Request Method

This method returns the request that would be made if the operation were invoked.

Copy:

REFERENCES:



.

1000 Apps Script As Web App


.
1000 Apps Script As Web App
1. Goto menu and select Publish/Deploy as web app...
2. Click Deploy.
3. Copy the URL and access it via Web Browser.

1) Return Plain Text

function doGet(){
 textOutput = ContentService.createTextOutput("Hello World! Welcome to the web app.")
 return textOutput
}

2) Return JSON

function doGet(){
 var appData = {
 "heading": "Hello World!",
 "body": "Welcome to the web app."
 };
 var JSONString = JSON.stringify(appData);
 var JSONOutput = ContentService.createTextOutput(JSONString);
 JSONOutput.setMimeType(ContentService.MimeType.JSON);
 return JSONOutput
}

3) Return HTML

function doGet(){

var HTMLString = "<style> h1,p {font-family: 'Helvitica', 'Arial'}</style>"
+ "<h1>Hello World!</h1>"
+ "<p>Welcome to the Web App";

HTMLOutput = HtmlService.createHtmlOutput(HTMLString);
return HTMLOutput
}

4) Return Dynamic HTML

function doGet(e){
  // use an externally hosted stylesheet
 var style = '<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">';
 // get the query "greeting" parameter and set the default to "Hello"
 var greeting = e.parameter.greeting || "Hello";
 // get the query "name" parameter and set the default to "World!"
 var name = e.parameter.name || "World";
 // create and use a template
 var heading = HtmlService.createTemplate('<h1><?= greeting ?> <?= name ?>!</h1>')
 // set the template variables
 heading.greeting = greeting;
 heading.name = name;
 var content = "<p>Welcome to the web app.</p>";
 var HTMLOutput = HtmlService.createHtmlOutput();
 HTMLOutput.append(style);
 HTMLOutput.append(heading.evaluate().getContent());
 HTMLOutput.append(content);
 return HTMLOutput
}

5) doPost processing

function doPost(e){
 // Get the "text" query string value
 // eg. &text=Your%20Name
 var name = e.parameter.text
 // Get the Chuck Norris Joke
 var chuckQuote = postChuckNorris(name);
 // Return plain text Output
 return ContentService.createTextOutput(chuckQuote);
}
// Make a call to the Chuck Norris joke API
// parse the JSON and return only the joke
function postChuckNorris(name){
 var queryString = makeQueryString(name)
 var chuckData = UrlFetchApp.fetch("http://api.icndb.com/jokes/random/" + queryString);
 var chuckJSON = JSON.parse(chuckData.getContentText());
 var chuckQuote = chuckJSON.value.joke;
 return chuckQuote
}
// Helper function to assemble the query string for
// calling the Chuck Norris API from a given name
function makeQueryString(name){
 var query = ""
 if (name !== undefined){
  var names = name.split(" ");
  query = "?firstName=" + names[0];
  if (names[1] !== undefined){
   query += '&lastName=' + names[1];
  }
 }
 return query
}

6) Create and Save PDF Document

function doGet(e){
 // get the query "greeting" parameter and set a default to "Hello"
 var greeting = e.parameter.greeting || "Hello";
 // get the query "name" parameter and set a default to "World!"
 var name = e.parameter.name || "World";
 // create the PDF
 var pdf = makePDF(greeting,name)
 // save the PDF to Drive
 var driveFile = DriveApp.createFile(pdf).setName("greetings.pdf");
 // tell the user how to access it
 var fileURL = driveFile.getUrl();
 var fileName = driveFile.getName();
 var HTMLOutput = HtmlService.createHtmlOutput("<p>Your made a PDF.</p>"
 + "<p> You can download it here: "
 + '<a target="blank" href="' + fileURL + '">' + fileName + '</a></p>');
 return HTMLOutput
}
function makePDF(greeting, name){
 // use an externally hosted stylesheet
 var style = '<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">';
 // create and use a template
 var heading = HtmlService.createTemplate('<h1><?= greeting ?> <?= name ?>!</h1>')
 // set the template variables
 heading.greeting = greeting;
 heading.name = name;
 var content = "<p>Here is your PDF.</p>";
 var PDFOutput = HtmlService.createHtmlOutput('<div class="container">');
 PDFOutput.append(style);
 PDFOutput.append(heading.evaluate().getContent());
 PDFOutput.append(content);
 PDFOutput.append('</div>');
 var blob = Utilities.newBlob(PDFOutput.getContent(), "text/html", "text.html");
 var pdf = blob.getAs("application/pdf");
 return pdf
}

REFERENCES:

https://developers.google.com/apps-script/guides/web 

.