How to get a direct download URL from Google Picker JavaScript API? - javascript

I'm trying to get a direct download URL for a file using Google's Picker API so that I can choose a file and pass this URL to server side code to download and store a copy of the item on the server.
I'm able to authorize through the picker API and get info of a picked file including the file name and preview URL (which is confusingly referred to as simply "A URL to this item" in the JSON response docs: https://developers.google.com/picker/docs/results)
I noticed that there is a post about using the Drive API to get a direct download URL here: Get google drive file download URL
However when I do this in my picker callback function (based on the docs here: https://developers.google.com/picker/docs/)
I get an error of:
"Project [number here] is not found and cannot be used for API calls. If it is recently created, enable Drive API by visiting https://console.developers.google.com/apis/api/drive.googleapis.com/overview?project=[project number here] then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry."
I have the API enabled in my developer console and the URL added to the JS allowed origins.
The documentation is very confusing and there seems to be 3 versions of the REST API to use with Drive which is based on an gapi.auth2 object whereas the picker api uses gapi.auth object.
I'm not sure if I need to authenticate again using the Google Drive API before performing the GET request. This all seems very messy and I believe there must be an easier approach for what is a simple request!
My picker callback function:
pickerCallback: function(data) {
if (data[google.picker.Response.ACTION] == google.picker.Action.PICKED) {
var doc = data[google.picker.Response.DOCUMENTS][0];
var fileName = doc[google.picker.Document.NAME];
var url = doc[google.picker.Document.URL];
var docId = doc[google.picker.Document.ID];
var request = null;
gapi.client.load('drive', 'v2', function() {
request = gapi.client.drive.files.get({
'fileId': docId
});
request.execute(function(resp){
console.log(resp);
});
});
//Write upload details to page
//Populate hidden field
}
Developer console screen - The first app is the picker API the second is for the Drive API:

You may want to try the simple callback implementation shown in this documentation. Notice that url was initialized before the if statement:
function pickerCallback(data) {
var url = 'nothing';
if (data[google.picker.Response.ACTION] == google.picker.Action.PICKED) {
var doc = data[google.picker.Response.DOCUMENTS][0];
url = doc[google.picker.Document.URL];
}
var message = 'You picked: ' + url;
document.getElementById('result').innerHTML = message;
}
Also, in authorizing, set the AppId value and choose the user account with the app's current OAuth 2.0 token. Note that the AppId set and the client ID used for authorizing access to a user's files must be contained in the same app. Then, after successfully obtaining the fileId, you can then send request using files.get. By default, this responds with a Files resource in the response body which includes downloadUrl.
For additional insights, see this related SO post.

Related

Trying to post url segment to firebase

I am running a script on a public webpage and i want to post part of the url into firebase.
I can insert a button that retrieves the url segment as a string variable but I can't post automatically to firebase from the open page because of permissions. Is there any way to do this other than creating an external page and posting the variable manually? Here is the Script I am using. This runs fine in external pages but i want to run it from the public page.
function pushit() {
firebase.initializeApp(config);
var url = location.href;
var filename = url.substr(38, 8);
console.log("Push Successfull!!!");
var database = firebase.database();
var ref = database.ref('url/data'); var data = {url: filename }
ref.push(data);
}
The error get is:
Uncaught ReferenceError: pushit is not defined
at HTMLButtonElement.onclick (index.html)
I created a popup window instead, which sends the data to the Firebase. I realized that running this sort of code in other websites was not possible.

Why isn't my json data displaying with JsonView?

I'm trying to display this code with JSONView but won't display when calling the data from inside the api callback function, but will display non api data when placed outside the callback.
// Call FreeGeoIP API to get browser IP address
$.getJSON('https://freegeoip.net/json/', function(data) {
var ipaddress = data.ip;
// Get browser language
var language = window.navigator.language;
// Get software
var software = window.navigator.appVersion;
var regExp = /\(([^)]+)\)/;
software = regExp.exec(software)[1];
// Add data to obj
var obj = {
'ipaddress': ipaddress,
'language': language,
'software': software
};
// Write obj to document
$('body').html(JSON.stringify(obj));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
JSONView extension or any other extensions in the Chrome browser needs permission to access file URLs if it is accessing files from your local system.
To allow:-
Visit chrome://extensions/
Click on Details button of the Extension card
Switch ON the Allow access to file URLs
JSONView or any other json formatter detects if you are viewing json on basis on contentType of the document loaded (as set on http header).
Since you must be running this code on client side (browser) the contentType is set to text/html .
For the plugin to correctly format the json, it must know that what you're looking at is indeed json and it does so by reading contentType header.
That is why fetching json via this script shows json as text in body attribute but not picked up by the plugin.

error 401 : unauthorized, received even after using API key while using www.openweathermap.org

Hi I am buliding my first web app using javascript and fetching data using API from www.openweathermap.org/
I have used the API key as mentioned in the documentation still it is giving an error of unauthorization. Can there be any other reason for this error while calling a function or so . Thank you in advance.
var APPID = "my_secret_key";
var temp;
var loc;
var icon;
var wind;
var humidity;
var direction;
function updateByZip(zip){
var url = "http://api.openweathermap.org/data/2.5/weather?" +
"zip = " + zip +
"&APPID =" + APPID ;
sendRequest(url);
}
function sendRequest(url){
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function(){
if(xmlhttp.readyState == 4 && xmlhttp.status == 200){
var data = JSON.parse(xmlhttp.responseText) ;
var weather = {};
weather.wind = data.wind.speed;
weather.direction = data.wind.deg;
weather.loc = data.name;
weather.temp = data.main.temp;
weather.icon = data.weather[0].id;
weather.humidity=data.main.humidity;
update(weather);
}
};
xmlhttp.open("GET", url, true);
xmlhttp.send();
}
It's the spaces near the equal signs in your URL. It's likely urlencoding the space and sending your parameter as APPID%20 which is not being recognized as valid.
var url = "http://api.openweathermap.org/data/2.5/weather?" +
"zip=" + zip +
"&APPID=" + APPID;
for future users, as i was having 401 error but solved it differently.
Error:
Invalid API key. Please see http://openweathermap.org/faq#error401 for more info
API calls responds with 401 error:
You can get the error 401 in the following cases:
You did not specify your API key in API request.
Your API key is not activated yet. Within the next couple of hours, it will be activated and ready to use.
You are using wrong API key in API request. Please, check your right API key in personal account.
You have free subscription and try to get access to our paid services (for example, 16 days/daily forecast API, any historical weather data, Weather maps 2.0, etc). Please, check your tariff in your [personal account]([price and condition]).
here are some steps to find problem.
1) Check if API key is activated
some API services provide key information in dashboard whether its activated, expired etc. openWeatherMap don't.
to verify whether your key is working 'MAKE API CALL FROM BROWSER'
api.openweathermap.org/data/2.5/weather?q=peshawar&appid=API_key
replace API_key with your own key, if you get data successfully then your key is activated otherwise wait for few hours to get key activated.
2) Check .env for typos & syntax
.env is file which is used to hide credentials such as API_KEY in server side code.
make sure your .env file variables are using correct syntax which is
NAME=VALUE
API_KEY=djgkv43439d90bkckcs
no semicolon, quotes etc
3) Check request URL
check request url where API call will be made , make sure
It doesn't have spaces, braces etc
correct according to URL encoding
correct according to API documentation
4) Debug using dotenv:
to know if you dotenv package is parsing API key correctly use the following code
const result = dotenv.config()
if (result.error) {
throw result.error
}
console.log(result.parsed)
this code checks if .env file variables are being parsed, it will print API_KEY value if its been parsed otherwise will print error which occur while parsing.
Hopefully it helps :)
Others suggestion
5) Check location of .env file
look for location of .env file in your directory, moving it to root directory might help (suggested in comments)
For those who followed the previous answers and are still facing the 401 issue: it seems it is now required to access the the API via HTTPS --- at least that's the case for me. Some older guides and tutorials might continue to use http:// in their code, so you'll have to change it to https://.
As far as I know, there is no mention of this in OpenWeather's official docs, and they don't include the protocol in their examples too.

Google Spreadsheet script, file access in Drive, "You do not have permission to call ..."

I have a Sheet where I need to get the id of a file located in my Google-drive.
I have written the folowing script:
function get_id_pdf() {
var nom='INV432-altaïr-Famille XXX-XXX Marie-03-2016.pdf';
var files = DriveApp.getFilesByName("'"+nom+"'");
while (files.hasNext()) {
var file = files.next();
var name = file.getName();
var type = file.getMimeType();
var url = file.getUrl();
var id = file.getId();
// Logger.log(file.getId());
return file.getId();
}
}
If I execute it in the Script editor (with the run button), it is working well (I get the id the the Log).
But If I call the script from a cell (in the cell: =get_id_pdf()) of my Google-Sheet, I get the error:
"You do not have permission to call getFilesByName" (see image)
I have of course all the authorization to access to this file (it is in my own drive, and the file havs been created by me).
Does somebody have an idea ?
Regards.
You cannot make calls to services that require user authorization as an anonymous user, which is what custom functions execute as. You will need to put the behavior into a custom menu, or a sidebar so that it can be authorized by the user.
Authorization Documentation
Custom Function Documentation
If your custom function throws the error message "You do not have
permission to call X service.", the service requires user authorization
and thus cannot be used in a custom function.

Lotus notes client link and browser link in xpages to download file stored in server directory

I have a Xpage in which there is a link to download the ics file which I have stored on server,As when the user clicks the link, the user is able to download the file name "votes.ics".
Accordingly when it is been accessed from browser, it allows me to download the file but at the same time when I want to download the same file using the link from LOTUS NOTES Client,It throws as an error Resource file not found it means the path in notes client has an issue,
To make it more clear, For example I have a database name "SMP_Intern.nsf" in the folder name "SMP" on the server and the onclick script behind the link is
var docId = getVotingDocumentUID();
if(docId != ""){
if(#ClientType() == "Notes"){
var path_private = "server_name/SMP/SMP_Intern.nsf";
var httpUrl = path_private.split("/")[0];
var databaseUrl = (httpUrl+"!!"+path_private.split("/")[1]+"/"+path_private.split("/")[2]);
var url = "/xsp/"+databaseUrl+"/.ibmmodres/domino/OpenAttachment/"+databaseUrl+"/"+docId+"/ics_file/votes.ics";
return url;
}else{
var url = "/0/"+docId+"/$File/"+"votes"+".ics?OpenElement";
return url;
}
}else return false;
For the notes client it goes to 'if' condition and gives error resource not found,but when it is browser the 'else' condition works perfectly fine.
Both the paths are same basically but could not able to find the mistake.
Any suggestion will be helpful.
You don't need a special treatment for Notes Client (XPiNC) in this case.
Your SSJS code for link value
var url = "/0/"+docId+"/$File/"+"votes"+".ics?OpenElement";
return url;
works for XPiNC too as the attachment is in the current database:
If current database resides on server then the URL points to the attachment on server.
If current database is a local replica then the URL points to the attachment in local database on client.
Have you tried #URLOpen( urlstring )formula for opening from client ?
The url must be a complete url http://DominoServer/DBPath/0/DocUNID/$file/filename
var url = "http://"+path_private +"/0/"+docId+"/$File/"+"votes"+".ics?OpenElement";
#URLOpen( url );

Categories

Resources