Call WebService with verification - google-apps-script

I created this web service:
function doPost(e) {
if(typeof e !== 'undefined');
var doc = DocumentApp.create(e.parameter.name);
var body = doc.getBody();
body.appendParagraph(e.parameter.text);
return ContentService.createTextOutput(doc.getId());
}
Deploy as web app: Anyone within my domain
How can I now call this service using another apps script?
I can use UrlFetchApp?
How to add verification to a call?
Thank you in advance for your help!

How about following sample script? Data of name and text is sent to the URL using the POST method. The URL can be retrieved when the script with doPost() is deployed as Web Apps.
Sample script :
var url = "https://script.google.com/macros/s/#####/exec";
var res = UrlFetchApp.fetch(url, {
method: "post",
payload: {
name: "samplename",
text: "sampletext",
}
});
Logger.log(res)
By this request, name and text can be used as e.parameter.name and e.parameter.text at doPost(e), respectively.
If I misunderstand your question, I'm sorry.

Related

Adding a doPost and doGet into google app script ("GAS") code

I am a total newbie when it comes to programming.
I have put a very simple switchbot script into google app script ("GAS") to make the switchbot bot do a press. While it can run when clicking on the "run" button in GAS, when sending a http post (i.e. via android's HTTP Shortcut app) to GAS, it connects but the action fails.
I do understand later that a doPost or doGet is required to run it when sending a post to the script from an external source, but after trying various methods with doPost and doGet, I still have no idea how to integrate it or where to put it into the code.
The code is below:
function main() {
var headers = {
"Authorization" : "SWITCHBOT_TOKEN_KEY",
"Content-type" : "application/json; charset=utf-8"
};
var data = {
"command" : "press",
"parameter" : "default",
"commandType": "command"
};
var options = {
'method' : 'post',
"headers" : headers,
muteHttpExceptions : true,
"payload" : JSON.stringify(data)
};
var deviceid = "INSERT_SWITCHBOT_DEVICEID";
var url1 = https://api.switch-bot.com/v1.0/devices/${deviceid}/commands;
var response = UrlFetchApp.fetch( url1, options );
var json = JSON.parse( response.getContentText() );
console.log( json )
}
Any assistance or lesson on how to do / understand this would be great!
Tried checking and looking at various codes with dePost and doGet and integrating it into the code but all seems not work.
While it connects to GAS via the deployed web app link, I am not able to get the actual script running. It simply logs it as failed in the GAS.

doPost not running for other users in google appscript

I have deployed my appscript as a form addon and as a web app both.
Everything seems to be working fine in the container form. But now I'm facing this issue where doPost function is not running as I have to run the function as other user. I tried this code from this answer, but this is also giving same authorization error.
function merry2script() {
var url = 'https://script.google.com/macros/s/AKfycbzM97wKyc0en6UrqXnVZuR9KLCf-UZAEpzfzZogbYApD9KChnnM/exec';
var payload = {payloadToSend : 'string to send'};
var method = 'post'
var headers: {"Authorization": "Bearer " + ScriptApp.getOAuthToken()}
var response = UrlFetchApp.fetch(url, {method : method, payload: payload, headers: headers}).getContentText();
Logger.log(response);
return;
}
Is this the correct way to post to appscript with oauth token?
If not how can I send a post request ?
I deployed the web app with these settings
I'm getting this error
I've been stuck for 3 days any help is appreciated
Thank you
UPDATED QUESTION:
APPSCRIPT DOPOST
function doPost(e) {
var data = JSON.stringify(e);
var jsonData = JSON.parse(data);
let query = jsonData.queryString;
let params = query.split("&");
let destinationId = params[0].split("=")[1];
// code is breaking here saying "you don't have access to the document"
let ss = SpreadsheetApp.openById(destinationId);
let sheetName = ss.getActiveSheet().getSheetName();
let dataSheet = ss.getSheetByName(sheetName);
var uniqueIdCol = dataSheet.getRange("A1:A").getValues();
let rowToUpdate;
// code to update row...
}
BACKEND CODE
// call appscript to update status sheet
const data = {
comment
};
let scriptId = process.env.DEPLOYMENT_SCRIPT_ID;
const config = {
method: "post",
url: `https://script.google.com/macros/s/${scriptId}/exec?destinationId=${destinationId}&uniqueId=${uniqueId}&status=${status}`,
data,
headers: {
Authorization: `Bearer ${respondent.form.oAuthToken}`,
},
};
await axios(config);
These are the scopes which I requested to user
"https://www.googleapis.com/auth/script.container.ui",
"https://www.googleapis.com/auth/forms.currentonly",
"https://www.googleapis.com/auth/script.external_request",
"https://www.googleapis.com/auth/userinfo.email",
"https://www.googleapis.com/auth/spreadsheets",
"https://www.googleapis.com/auth/script.send_mail",
"https://www.googleapis.com/auth/forms",
"https://www.googleapis.com/auth/script.scriptapp",
"https://www.googleapis.com/auth/drive"
UPDATED QUESTION 2
I had made a script which can write to google sheet with some extra data which I send from my node backend.
So my script has doPost function which is invoked from backend. I send destinationId of the sheet to know in which sheet to write as in the code above.
I have deployed the webapp as Execute as: Me and Who has access to the app: Anyone.
I'm able to run the doPost function but not able to write to sheet.
Hope my question is clear
So after struggling for 4 days I was able to send email and write to spreadsheet with users OAuth token by directly interacting with Sheets API and Gmail API instead of doing it through ScriptApp doPost method

Google Apps Script XMLHttpRequest not showing parameters

I am able to make the POST request to my google apps script web app, but I can't access my e.parameters when I log them.
HTML CODE:
<form onsubmit="submitForm(event)">
<input type="text" name="fname" required>
<button type="submit">Submit</button>
</form>
JS CODE:
function submitForm(e){
e.preventDefault()
var url = "https://xxxxxxxxxxxxxxxxxxxxxx/exec"
var params = "employeeStatus='Active'&name='Henry'";
var xhr = new XMLHttpRequest()
xhr.open("POST",url,true)
xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded")
xhr.onreadystatechange = ()=>{
var readyState = xhr.readyState
var status = xhr.status
if(readyState == 4 && status == 200){
var response = JSON.parse(xhr.responseText)
console.log(response)
}
}
xhr.send(params)
}
APPS SCRIPT CODE:
function doPost(e){
var values = e.parameters;
Logger.log(values)
return ContentService.createTextOutput(JSON.stringify({"a":5,"b":2}))
}
Can anyone please tell me what I'm doing wrong here? I've iterated the apps script code to try and log the e.parameters but I'm unable to get anything to work.
***NOTES:
I'm aware that the "params" value is NOT the same as the form input value
I return the JSON string just to ensure that the code is running all the way through and I can practice JSON.parse/JSON.stringify on the client-side.
When I saw your script, I think that your value of e.parameters is {"employeeStatus":["'Active'"],"name":["'Henry'"]}.
About I've iterated the apps script code to try and log the e.parameters but I'm unable to get anything to work., I think that the reason for your issue is due to that your request of "XMLHttpRequest" include no access token. From your request, I thought that the settings of Web Apps might be Execute as: Me and Who has access to the app: Anyone with V8 runtime. If my understanding is correct, the reason for your issue is due to that.
If you want to show Logger.log(values) in the log, please include the access token to the request header as follows.
Modified script:
function submitForm(e) {
e.preventDefault();
var url = "https://script.google.com/macros/s/###/exec"; // Your web apps URL.
url += "?access_token=###your access token###";
var params = "employeeStatus=Active&name=Henry";
var xhr = new XMLHttpRequest();
xhr.open("POST", url, true);
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhr.onreadystatechange = () => {
var readyState = xhr.readyState;
var status = xhr.status;
if (readyState == 4 && status == 200) {
var response = JSON.parse(xhr.responseText);
console.log(response);
}
}
xhr.send(params);
}
In this case, as a test, you can simply retrieve your access token by the following Google Apps Script. // DriveApp.getFiles() is put for automatically detecting the scope of Drive API for accessing Web Apps. The expiration time of this access token is 1 hour. Please be careful about this. When the expiry time is over, please retrieve the access token again.
const sample = _ => {
console.log(ScriptApp.getOAuthToken());
// DriveApp.getFiles()
}
When the above script is run, the following value is shown in the log by Logger.log(values).
{access_token=[###], employeeStatus=[Active], name=[Henry]} : This is due to Logger.log.
When console.log(values) is used, { access_token: [ '###' ], employeeStatus: [ 'Active' ], name: [ 'Henry' ]} is shown.
Note:
As another approach, for example, when you want to check the value of e of doPost, I think that you can store the value in a Spreadsheet as a log as follows. By this, when doPost is run, the value of e is stored in the Spreadsheet as a log. In this case, the access token is not required to be used.
function doPost(e) {
SpreadsheetApp.openById("###spreadsheetId###").getSheets()[0].appendRow([new Date(), JSON.stringify(e)]);
return ContentService.createTextOutput(JSON.stringify({ "a": 5, "b": 2 }))
}
Note
When you modified the Google Apps Script, please modify the deployment as a new version. By this, the modified script is reflected in Web Apps. Please be careful this.
You can see the detail of this in the report of "Redeploying Web Apps without Changing URL of Web Apps for new IDE".
Reference:
Taking advantage of Web Apps with Google Apps Script

Fetch JSON object from GAS WebApp from another development GAS WebApp?

I have two different GAS projects Script1 and Script2.
Script1:
It is a development project with doPost() function. It uses the e.parameter or e.postData.contents to do something.
Script2:
It is a test script. It has also doPost() function. I want to transfer the doPost() e.parameter to Script1 by a post request. But the URLFetchApp success when I use the Current web app URL and ends in /exec. But I want to use the latest code and ends in /dev. Because of the Script1 is a development project and I can't update its version for a small change.
I tried this code. It not working
function myFunction() {
//var URL = "https://script.google.com/macros/s/xxxxxxxxxxxxxxxxxxxxxxxxxxx/exec";
var URL = "https://script.google.com/macros/s/xxxxxxxxxxxxxxxxxxxxxxxxxxxx/dev";
var data = {
'message' : "This is working"
}
var options = {
'method' : 'post',
'contentType': 'application/json',
'payload' : JSON.stringify(data)
};
var response = UrlFetchApp.fetch(URL, options);
}
I believe your goal as follows.
You want to access to Web Apps with the dev mode using Google Apps Script.
For this, How about this answer?
Modification points:
In order to access to the Web Apps with the dev mode, please use the access token. And in this sample, the scope of https://www.googleapis.com/auth/drive.readonly is used for the access token.
Modified script:
When your script is modified, please modify as follows.
function myFunction() {
//var URL = "https://script.google.com/macros/s/xxxxxxxxxxxxxxxxxxxxxxxxxxx/exec";
var URL = "https://script.google.com/macros/s/xxxxxxxxxxxxxxxxxxxxxxxxxxxx/dev";
var data = {
'message' : "This is working"
}
var options = {
'method' : 'post',
'contentType': 'application/json',
'payload' : JSON.stringify(data),
'headers': {'authorization': 'Bearer ' + ScriptApp.getOAuthToken()} // Added
};
var response = UrlFetchApp.fetch(URL, options);
}
// DriveApp.getFiles() // Added
Note:
The comment line of // DriveApp.getFiles() is used for automatically detecting the scope of https://www.googleapis.com/auth/drive.readonly by the script editor.
When the access token is used, even when Who has access to the app: is Only myself, the script works.
References:
Web Apps
Taking advantage of Web Apps with Google Apps Script

How do I create a doPost(e) function in Apps Script project to capture HTTP POST data from web service?

I'm trying to create a script to capture data via HTTP POST from Ejunkie. When someone makes a purchase on ejunkie, they can transmit all the order data via HTTP POST to a common notification url (documentation). I want to capture that data so I can get it into a Google Sheet.
So I've setup a sheet with a doPost(e) function like so:
// attempt 1
function doPost(e) {
if(typeof e !== 'undefined')
Logger.log(e.parameters);
}
// attempt 2
function doPost(e) {
var data = JSON.stringify(e);
Logger.log(data);
}
which I've published as a Web App with access to anyone, and then entered this script URL as the common notification URL in ejunkie.
I've tried a couple of test transactions, but I'm getting nothing in the Logs.
Any ideas? Thanks in advance for any help.
Here's the ejunkie documentation on this subject.
This is the code I used to post the data to my sheet:
function doPost(e) {
Logger.log("I was called")
if(typeof e !== 'undefined')
Logger.log(e.parameter);
var ss= SpreadsheetApp.openById("ID here")
var sheet = ss.getSheetByName("Sheet2")
sheet.getRange(1, 1).setValue(JSON.stringify(e))
return ContentService.createTextOutput(JSON.stringify(e))
}
Used curl to make a post request and got echo of the data sent!
Instead of using Logger.log() as a way to notify yourself if your calls made it through, try sending an email to yourself instead. This is the snippet:
function doPost(e) {
if(typeof e !== 'undefined')
MailApp.sendEmail({
to: "youremail#gmail.com",
subject: "Call Sucessful",
htmlBody: "I am your <br>" +
"DATA"
});
}
Just allow the necessary permission if asked. If I'm not mistaken Logger.log is for script editor only and not for your production web apps.
Could try something like this? Also you might look # this thread: doPost(e) does not return parameters but doGet(e) does?
function doPost(e) {
if(typeof e !== 'undefined')
return ContentService.createTextOutput(JSON.stringify(e.parameter));
}