How To Call External API Using Google App Script via URLFetch Class - google-apps-script

function checkACBalance() {
try{
var url ="http://sms.mydomain.com/api/balance.php";
alert(url);
var payload = {authkey:'d5558466554f11aa909d565ede677d40', route:'1'};
alert(payload);
var payload_json = encodeURIComponent(JSON.stringify(payload));
alert(payload_json);
var options = {method:"POST",contentType:"application/json",payload:payload_json,muteHttpExceptions:true};
var result = UrlFetchApp.fetch(url, options);
var response = result.getContentText();
alert(response)
var res_code = result.getResponseCode();
alert(res_code)
}catch(e){
alert(e)
}
}
Now the problem is that when I am using this URLFetch Class for calling external API then this is not working.
In browser console an error has been shown:
Uncaught TypeError: Cannot read property 'fetch' of undefined

To build on what Kriggs is saying in the comments, it looks like you're trying to use UrlFetchApp.fetch in your .js file (the client). You want to make this call in your .gs file (the server).

Related

How to download a binary file from Google Drive using C#

I am using the v3 .Net Google Apis. This seems like it should be a simple task, but nothing I have tried seems to work.
I am able to get the file resource for the file I want by doing this -
var fileRequest = service.Files.Get(fileId);
fileRequest.Fields = "*";
var fileResponse = fileRequest.Execute();
But then I have not been able to actually find a way to download the file. If I use this -
var exportRequest = service.Files.Export(fileResponse.Id, fileResponse.MimeType);
exportRequest.Download(stream);
It returns a 403 Forbidden status with a message stating that Export is only for Google docs.
I've tried this -
var downloadTask = exportRequest.MediaDownloader.DownloadAsync(#"https://docs.google.com/uc?export=download&id=" + fileResponse.Id, file);
downloadTask.Wait();
But that just returns the markup for the page for the user to login. I created the export request using a service account so login should not be required.
Any have a sample of doing this in .Net using the V3 google API?
Ok, I literally got this to work 5 minutes after posting this. Here is what I found works (I know I tried this before and it did not work, but who knows) -
public static async Task DownloadFile(string fileId, DriveService service)
{
var fileRequest = service.Files.Get(fileId);
fileRequest.Fields = "*";
var fileResponse = fileRequest.Execute();
var exportRequest = service.Files.Get(fileResponse.Id);
//you would need to know the file size
var size = fileResponse.Size;
var file = new FileStream(fileResponse.Name, FileMode.OpenOrCreate, FileAccess.ReadWrite);
file.SetLength((long)size);
var response = await fileRequest.DownloadAsync(file);
if (response.Status == Google.Apis.Download.DownloadStatus.Failed)
{
Console.WriteLine("Download failed");
}
}

'Invalid Argument' error with un-gzipping Blob in Apps script

I have a script that receives a gzipped blob from 3rd party API. I'm trying to un-gzip it using Utilities.ungzip() but getting an Invalid Argument error. Here's a sample code:
var liveReportResponse = UrlFetchApp.fetch(url)
var unzipped = Utilities.ungzip(liveReportResponse.getBlob()) // Fails with Invalid Argument error
An odd thing is that I can extract the content using the Drive File as intermediate storage:
var image = liveReportResponse.getBlob()
var file = {
title: 'some_file_.gzip'
};
file = Drive.Files.insert(file, image);
var file = DriveApp.getFileById(file.id)
var blob = file.getBlob()
var someBytes = Utilities.ungzip(blob) // It works
var data = someBytes.getDataAsString()
Would appreciate any help for fixing that.
Eventually, managed to fix that with:
liveReportResponse.getBlob().setContentType('application/x-gzip')
application/x-gzip seems not to be documented anywhere, but I've got it from blob.getContentType()

DriveApp.createFile causes a server error

I got the following error when I tried to download a picture from a URL using Google Apps Script.
We're sorry, a server error occurred. Please wait a bit and try again.
Here is the code.
function TT() {
var response = UrlFetchApp.fetch('https://www.dropbox.com/s/g9jtm390l67uqkb/128.png?dl=1');
var blob = response.getBlob();
Logger.log(blob.getContentType());
var file = DriveApp.createFile(response);
}
Well, should try to create a file from its blob, not from the response it self.
function TT() {
var response = UrlFetchApp.fetch('https://www.dropbox.com/s/g9jtm390l67uqkb/128.png?dl=1');
var blob = response.getBlob();
Logger.log(blob.getContentType());
var file = DriveApp.createFile(blob);
}
I'v runned a test and it works perfectly.

Google Script UrlFetchApp.fetch returns a 404 eventhough the page exist

I am sending automated report with Google spreadsheet and Google script.
So far it was working perfectly. But somehow when I try to create a new report to be emailed, the function "UrlFetchApp.fetch" return a 404. The same situation happened when I tried copying the old report.
The line with "UrlFetchApp.fetch" give me this error:
Request failed for https://docs.google.com/spreadsheets/d/1qm_bCKn4MbLKy7AIuIeu7bTZcTk8ObYBln0GAxwfsX8/pub?gid=195635557&single=true&output=pdf returned code 404. Truncated server response
It seems that I am not the only one having the issue but I cannot find any solution to it.
Here is the code:
function emailSpreadsheetAsCSV() {
var ss = SpreadsheetApp.openById("1qm_bCKn4MbLKy7AIuIeu7bTZcTk8ObYBln0GAxwfsX8");
var url = ss.getUrl();
url = url.replace(/edit$/,'');
var token = ScriptApp.getOAuthToken();
var sheets = ss.getSheets();
//make an empty array to hold your fetched blobs
var blobs = [];
for (var i=0; i<sheets.length; i++) {
var response = UrlFetchApp.fetch("https://docs.google.com/spreadsheets/d/1qm_bCKn4MbLKy7AIuIeu7bTZcTk8ObYBln0GAxwfsX8/pub?gid=195635557&single=true&output=pdf", {
headers: {
'Authorization': 'Bearer ' + token
},
'muteHttpExceptions': false
});
//convert the response to a blob and store in our array
blobs[i] = response.getBlob().setName(sheets[i].getName() + '.csv');
}
//create new blob that is a zip file containing our blob array
var zipBlob = Utilities.zip(blobs).setName(ss.getName() + '.zip');
return blobs[0];
}
Thanks a lot for your help.
Aymeric.
I've gotten this problem too and after some research, Spence Easton (question 34573295) solved my issue. I simply added this bogus call to drive so access is granted, and so the script can now get to your file.
Add this near the top before trying to grab the url:
var bogus = DriveApp.getRootFolder();
Now it runs fine with no 404 errors.
Remove the headers from the request:
var response = UrlFetchApp.fetch("https://docs.google.com/spreadsheets/d/1qm_bCKn4MbLKy7AIuIeu7bTZcTk8ObYBln0GAxwfsX8/pub?gid=195635557&single=true&output=pdf", {
'muteHttpExceptions': false
});
Check if it works for you.
You use the "pub" url so are you sure the spreadsheet is published on the web ? If you get a 404 it means the page is not published.
If file is published the bearer is not necessary as it is public now.
After I don't really understand your code because you iterate all the sheets of your file
for (var i=0; i<sheets.length; i++)
but the param "gid" (pub?gid=195635557&single=true&output=pdf) for the url in your urlfetch is fixed ?
Second point you get the file as pdf and after you create a csv ?
Why not get the file as csv directly : https://docs.google.com/spreadsheets/export?id=TheIdOfTheFile&exportFormat=csv
By adapting this code you can get the csv directly, see : https://stackoverflow.com/a/28503601/3556215
Take care you will get the first page and not others.
Stéphane
Try with:
var response = UrlFetchApp.fetch(url, options);
var result = JSON.parse(res.getContentText());

Upload file to Google Site. Google Apps Script

I try to upload file to my 'mysitename' Google Site. I using this script, but it does not work
function doGet(e) {
var app = UiApp.createApplication().setTitle("Upload");
var formContent = app.createVerticalPanel();
formContent.add(app.createFileUpload().setName('thefile'));
formContent.add(app.createSubmitButton());
var form = app.createFormPanel();
form.add(formContent);
app.add(form);
return app;
}
function doPost(e) {
try{
var fileBlob = e.parameter.thefile;
var pages = SitesApp.getSite('site', 'mysitename').getChildren();
var attachments = pages[0].getAttachments();
attachments[0].setFrom(fileBlob);
}catch(e){
Logger.log(e.message);
}
}
I catch error "Cannot call method "setFrom" of undefined" last modal window "Error encountered: An unexpected error occurred"
It's works! But i do not know, how to use this circular from documentation "Sets the data, content type, and name of this attachment from a Blob. Throws an exception for web attachments." What is mean this "Throws an exception for web attachments"? I'll be forced to use "try-catch-exception"
Pls, help me to do it!
I think the error is in the line
var pages = SitesApp.getSite('sites', 'mysitename').getChildren();
The documentation says
method getSite(domain, name)
Gets the site with the given domain and name.
Use "site" as the domain for consumer sites.
So, if you are within a domain, use the name of your domain, otherwise use 'site' instead of 'sites'