My goal is to update an API using Apps Script but I cannot work out how to do it. For simplicity sake here is my code:
let APIkey = "...";
let url = "..."
newData = {"stock_status": "instock"}
//Update API
The problem is I do not know how to get any further. I have read the relevant docs to this API but to no avail and I couldn't find anything about put requests in the Apps Script docs.
Answer:
You need to use UrlFetchApp.
Example:
I don't know how your API accepts authentication, but assuming it accepts the key as a URL parameter then you can do something like:
let APIkey = "..."
let url = "..."
const newData = {
"stock_status": "instock"
}
var options = {
'method' : 'PUT',
'contentType': 'application/json',
'payload' : JSON.stringify(newData)
}
UrlFetchApp.fetch(`${url}?key=${APIkey}`, options);
You can read the full documentation on fetch here
Related
I am attempting to come up with a live leaderboard for my local club using the PDGA's (Professional Disc Golf Association) API. I am writing a Google Apps Script intending to auto populate a Google Sheet with a Club Ranking that can be refreshed as needed.
Right now, all I am trying to do is make pull of data to ensure I am able to begin using the API, but I can't seem to do even that.
For reference, here are the only two resources I have to work with regarding this specific API:
PDGA REST API Authentication
PDGA REST API Services
I have got the original login to work using this code:
function apiLogin() {
var LoginUrl = 'https://api.pdga.com/services/json/user/login';
var LoginDetails = {
'username' : Username,
'password' : Password
};
var LoginRequest = {
'method' : 'post',
'Content-Type' : 'application/json',
'payload' : LoginDetails
};
var LoginResponse = UrlFetchApp.fetch(LoginUrl, LoginRequest);
var json = LoginResponse.getContentText();
var LoginData = JSON.parse(json);
Logger.log(LoginData);
var SessionID = LoginData['sessid'];
var SessionName = LoginData['session_name'];
var Tok = LoginData['token'];
var playerFetchPar = {
'method' : 'get',
'Cookie' : SessionID + '=' + SessionName
};
var PlayerResponse = UrlFetchApp.fetch('https://api.pdga.com/services/json/players?pdga_number=1',playerFetchPar); //ERROR
Logger.log(PlayerResponse);
};
It's the last part when I am trying to call on data from a player that I get the following error message:
Exception: Request failed for https://api.pdga.com returned code 403. Truncated server response: ["Access denied for user anonymous"] (use muteHttpExceptions option to examine full response)
I am guessing that my screw up is in my interpretion of the parameter Cookie from that second link. In the initial response to make sure I was logging in properly, I received a session_name and sessid but I can't seem to figure out what is expected from Cookie. I am sorry if the answer is obvious, but any help would be greatly appreciated!
The documentation says
Cookie: session_name=sessid
You've used
Cookie: sessid=session_name
Reverse it:
'Cookie' : `${SessionName}=${SessionID}`
And you need to send it as a header:
const playerFetchPar = {
method : 'get',
headers: {'Cookie' : `${SessionName}=${SessionID}`}
};
I'm trying to pull an access token from Office365's /token identity platform endpoint via OAuth 2.0 client credentials grant flow. I have my app registered, the client ID & secret, etc...
I can make the POST request in Postman and receive the access token without issue:
However, when I try the POST request via JavaScript (by way of Google Apps Script), I receive an error message: AADSTS900144: The request body must contain the following parameter: 'grant_type'
I've already Google'd this error and found a bunch of different solutions, and have tried implementing them to no avail. I imagine this has to do with the URL encoding, but cannot figure it out.
Code:
function getO365() {
// POST Request (To get Access Token)
var tenantID = 'longstringhere'
var appID = 'longstringhere'
var appSecret = 'longstringhere'
var graphScore = 'https://graph.microsoft.com/.default'
var url = 'https://login.microsoftonline.com/' + tenantID + '/oauth2/v2.0/token'
var data = {
'client_id': appID,
'scope': graphScore,
'client_secret': appSecret,
'grant_type': 'client_credentials'
};
var postOptions = {
'method': 'POST',
'headers': {
'Accept': 'application/json',
'Content-Type': 'application/x-www-form-urlencoded'
},
'body': data,
'redirect': 'follow'
};
var authToken = UrlFetchApp.fetch(url, postOptions);
}
The only real difference between my code and the JavaScript Fetch code I pulled off of Postman is:
var urlencoded = new URLSearchParams();
urlencoded.append("client_id", "longstringhere");
urlencoded.append("scope", "https://graph.microsoft.com/.default");
urlencoded.append("client_secret", "longstringhere");
urlencoded.append("grant_type", "client_credentials");
When I try to use URLSearchParams in Google Apps Script, I keep getting this error: ReferenceError: URLSearchParams is not defined
Any ideas? Thanks in advance!
This was resolved by changing 'body' to 'payload' for UrlFetchApp per the documentation. Edited code to reflect the change. Credit to #TheMaster for pointing out my mistake.
'payload': data,//from 'body': data,
var url = "https://web-site_name/page/?format=json&var_data-organization_dates&xlsexport=true";
var payload =
{
"login" : "login",
"password" : "pass",
};
var options =
{
"method" : "post",
"payload" : payload,
"followRedirects" : false
};
var login = UrlFetchApp.fetch("https://web-site_name/page/" , options);
var sessionDetails = login.getAllHeaders()['Set-Cookie'];
Logger.log(login.getAllHeaders());
here is the part of the code I try to use, to automate export of the data from web-site, i do have proper login and password and able to download file in json (opened in xsl) manually, I've got the address to the downloaded file in network in developer tools, but i have a problem on the first stage - when trying to authorize to the web-site - access denied. I've tried the code, given in answers on stackoverflow, but it still doesn't work.
How to make an url fetch request correctly, depends on the website you want to access and the authentication they uses
In the simplest case, your website requires HTTP basic authentification, in this case the correct syntax would be
var authHeader = 'Basic ' + Utilities.base64Encode(login + ':' + pass);
var options = {
headers: {Authorization: authHeader}
}
If your website uses a different authentication form, you might need to provide an access token.
In any case: the authentication credentials go into headers, not into payload!
payload is the data that you want to post = upload to the website.
If you want export data from the website - that is download data - you do not need a payload and the correct method would be get, not post. Btw., if the method is get, you do not need to specify it.
Please see here for more information and samples.
function topdf() {
var foldersave=DriveApp.getFolderById('0Byy1DdsfdfTQRnVlfb05wOV83T00')
var d= new Date()
var oauthConfig = UrlFetchApp.addOAuthService("google");
var scope = "https://docs.google.com/feeds/";
//make OAuth connection
oauthConfig.setAccessTokenUrl("https://www.google.com/accounts/OAuthGetAccessToken");
oauthConfig.setRequestTokenUrl("https://www.google.com/accounts/OAuthGetRequestToken?scope="+scope);
oauthConfig.setAuthorizationUrl("https://www.google.com/accounts/OAuthAuthorizeToken");
oauthConfig.setConsumerKey("anonymous");
oauthConfig.setConsumerSecret("anonymous");
//get request
var request = {
"method": "GET",
"oAuthServiceName": "google",
"oAuthUseToken": "always",
"muteHttpExceptions": true
};
var key='1QUj_OyHisdfsdfjwfNu1l-JuI528ev6FNRJv-oljIY';
var fetch='https://docs.google.com/spreadsheets/d/'+key+'/export?format=pdf&size=A4&portrait=false'
var name = "Timestamp for: "+ d + ".pdf";
var pdf = UrlFetchApp.fetch(fetch, request);
pdf = pdf.getBlob().setName(name);
var file = foldersave.createFile(pdf)
}
I'm looking for a step by step tutorial to convert the above code using OAuth2 . I'm having some problems migrating. I can find bits of code on OAuth2, but don't know how it ties together. The code was really simple before, now it seems to be much more complicated? Or am I missing something simple?
I've tried to replace the OAuth connection section but having trouble. https://github.com/googlesamples/apps-script-oauth2 it seems like the getDriveService should be used somehow?
You'll find a function that generates and saves PDFs for one or all of your sheets in
Convert all sheets to PDF with Google Apps Script.
For anyone who hadn't seen the notice posted in the cellar of the Local Planning Office 3 years ago, Google has deprecated OAuth1 & OAuth1a authorization for their services.
In their guide, Migrating from OAuthConfig to the OAuth1 library, the Apps Script team describes how to migrate your code from one to the other. What they fail to mention is that you don't need to.
There IS an easier way, at least for accessing Google's services.
You can obtain the OAuth 2.0 access token for the current user with ScriptApp.getOAuthToken(), which means a simplifying change in any script that previously used OAuthConfig.
To convert your script:
Replace
var request = {
"method": "GET",
"oAuthServiceName": "google",
"oAuthUseToken": "always",
"muteHttpExceptions": true
};
with
var request = {
"method": "GET",
headers: {
'Authorization': 'Bearer ' + ScriptApp.getOAuthToken()
},
"muteHttpExceptions": true
};
Delete every remaining reference to the old OAuthConfig class.
...
var oauthConfig = UrlFetchApp.addOAuthService("google");
var scope = "https://docs.google.com/feeds/";
//make OAuth connection
oauthConfig.setAccessTokenUrl("https://www.google.com/accounts/OAuthGetAccessToken");
oauthConfig.setRequestTokenUrl("https://www.google.com/accounts/OAuthGetRequestToken?scope="+scope);
oauthConfig.setAuthorizationUrl("https://www.google.com/accounts/OAuthAuthorizeToken");
oauthConfig.setConsumerKey("anonymous");
oauthConfig.setConsumerSecret("anonymous");
...
That's all there is to it.
Follow the migration guide if you're using an external (non-Google) service that requires OAuth 2.0 authentication.
And yes, even with the library it's more complicated than OAuth1 was - but necessarily so.
Here is the change. Because you are using DriveApp your script already has the authorization to access your files from any source including UrlFetchApp. All you have to do is get the token from the script and pass it in the header of your Fetch request.
function topdf() {
var foldersave=DriveApp.getFolderById('0Byy1DdsfdfTQRnVlfb05wOV83T00');
var d= new Date();
var request = {
"method": "GET",
"headers":{"Authorization": "Bearer "+ScriptApp.getOAuthToken()},
"muteHttpExceptions": true
};
var key='1QUj_OyHisdfsdfjwfNu1l-JuI528ev6FNRJv-oljIY';
var fetch='https://docs.google.com/spreadsheets/d/'+key+'/export?format=pdf&size=A4&portrait=false'
var name = "Timestamp for: "+ d + ".pdf";
var pdf = UrlFetchApp.fetch(fetch, request);
pdf = pdf.getBlob().setName(name);
var file = foldersave.createFile(pdf)
}
Just finished breakfast and already hit a snag. I'm trying to call the salesforce REST api from my google sheets. I've written a working script locally in python, but converting it into JS, something went wrong:
function authenticateSF(){
var url = 'https://login.salesforce.com/services/oauth2/token';
var options = {
grant_type:'password',
client_id:'XXXXXXXXXXX',
client_secret:'111111111111',
username:'ITSME#smee.com',
password:'smee'
};
var results = UrlFetchApp.fetch(url, options);
}
Here is the error response:
Request failed for https://login.salesforce.com/services/oauth2/token
returned code 400. Truncated server response:
{"error_description":"grant type not
supported","error":"unsupported_grant_type"} (use muteHttpExceptions
option to examine full response) (line 12, file "Code")
Mind you, these exact parameters work fine in my local python script (putting the key values inside quotations).
Here are the relevant docs:
Google Script: Connecting to external API's
Salesforce: REST API guide
Thank you all!
Google's UrlFetchApp object automatically defaults to a GET request. To authenticate, you have to explicitly set in the options the method "post":
function authenticateSF(){
var url = 'https://login.salesforce.com/services/oauth2/token';
var payload = {
'grant_type':'password',
'client_id':'XXXXXXXXXXX',
'client_secret':'111111111111',
'username':'ITSME#smee.com',
'password':'smee'
};
var options = {
'method':'post',
'payload':payload
};
var results = UrlFetchApp.fetch(url, options);
}