Showing documents from Google Drive on webpage - javascript

Is it possible to show the documents from my drive on a webpage? I want the user to be able to click the document and download it, directly from my drive. How would I go about doing this? Thank you for your suggestions.

The fastest and easiest solution is to embed the folder using an iframe (no javascript needed). Obviously this is also the least flexible solution, although you can use CSS to change the layout of the iframe contents (see below).
Google Drive won't allow embedding of the url you would normally use. It has its X-Frame-Options header set to "SAMEORIGIN", preventing use in an iframe. So you have to use the following link, which will allow embedding:https://drive.google.com/embeddedfolderview?id=DOCUMENT_ID#VIEW_TYPE
DOCUMENT_ID is the id that is mentioned in the normal share link (which looks like https://drive.google.com/folderview?id=DOCUMENT_ID), so you can just copy that from there.
VIEW_TYPE should be either 'grid' or 'list', depending on your preference.
And if you need to change the style of the iframe content, take a look at this solution.

For HTML/JavaScript solution, look at the following links:
https://developers.google.com/drive/quickstart-js
https://www.youtube.com/watch?v=09geUJg11iA
https://developers.google.com/drive/web/auth/web-client
Here's the simplest way using JavaScript, most of the complexity is in
your WebApp authorization. The example below reads files IDs, names and description in a folder you specify.
- go to: https://cloud.google.com/console/project
and create a new project "xyz"
- Select "APIs & auth", disable the ones you don't need, enable "Drive API"
- Select "Credentials",
push "CREATE NEW CLIENT ID" button
x Web Application
Authorized Javascript origins: "https://googledrive.com/"
Authorized redirect URI: "https://googledrive.com/oauth2callback"
it will result in:
Client ID: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com
Email address: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx#developer.gserviceaccount.com
Client secret: xxxxxxxxxxxxxxxxxxxx
Redirect URIs: https://googledrive.com/oauth2callback
Javascript Origins: https://googledrive.com/
- in the code below, replace
CLIENT_ID with xxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com
FOLDER_ID with the ID you see in the folder address line,
https://drive.google.com/?tab=mo&authuser=0#folders/xxxxxxxxxxxxxxxxxxx
- run it, authorize
I don't know if you read JS, the code can be followed from bottom up, I made is as simple as possible.
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script>
var FOLDER_ID = '.xxxxxxxxxxxxxxxxxx'; // the folder files reside in
var CLIENT_ID = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com';
var SCOPE = //'https://www.googleapis.com/auth/drive';
[
'https://www.googleapis.com/auth/drive',
'https://www.googleapis.com/auth/drive.file', // for description,
];
function rsvpCB(resp) {
var picAlbumLst = '<ul>\n';
for (i=0; i<resp.items.length; i++)
picAlbumLst += (
' <li>'+resp.items[i].id+', '+resp.items[i].title+', '+resp.items[i].description+'</li>\n');
picAlbumLst += "</ul>\n";
$('#container').append(picAlbumLst);
}
function rqstCB() { //test # https://developers.google.com/drive/v2/reference/files/list
var rv = gapi.client.drive.files.list({
'q': '"'+FOLDER_ID+'" in parents and trashed = false',
'fields' : 'items(id,title,description)' //'items(id,title,description,indexableText)'
}).execute(rsvpCB);
}
// authorization server reply
function onAuthResult(authResult) {
var authButton = document.getElementById('authorizeButton');
authButton.style.display = 'none';
if (authResult && !authResult.error) { // access token successfully retrieved
gapi.client.load('drive', 'v2', rqstCB);
} else { // no access token retrieved, force the authorization flow.
authButton.style.display = 'block';
authButton.onclick = function() {
checkAuth(false);
}
}
}
// check if the current user has authorized the application.
function checkAuth(bNow) {
gapi.auth.authorize({'client_id':CLIENT_ID, 'scope':SCOPE, 'immediate':bNow}, onAuthResult);
}
// called when the client library is loaded, look below
function onLoadCB() {
checkAuth(true);
}
</script>
<script src="https://apis.google.com/js/client.js?onload=onLoadCB"></script>
<body style="background-color: transparent;">
<input type="button" id="authorizeButton" style="display: none" value="Authorize" />
<div id="container">
</div>
</body>

This should be done with Google API. You can search google drive php api list files on google. And also I found this and this on SO.

Here are some main points:
Do you want anyone with the URL to be able to see your document? You can share a document as public to anyone on the internet. Plus you can set read access to specific folders. Just right click a Google Doc file, and choose 'Share' from the short cut menu.
I'm assuming you want people to download your docs, even when you are not signed in. This is called 'Offline Access', and is one of many terms you'll need to figure out in order to do all of this with a program.
If you only want to give read access to the user, using JavaScript, jQuery, etc on the front end is a viable option. You can also do this in PHP, it's just a matter of personal preference.
To do all of this in code, you need to grant authorization to read your files. The oAuth2 process has multiple steps, and it's good to understand the basic flow. Setting up the code and the webpages to initially grant authorization, then retrieve and store the tokens can get confusing.
Your Google Project has a setting for where the origin of the authorization request is coming from. That is your website. But if you want to develop and test locally, you can set the Javascript Origins to http://localhost
How much time do you have, and how much programming experience? Would it be easier to give the user a few lines of instruction to "Manually" download your file, rather than program the authorization check?
Putting the document into your webpage is the easy part.
In order to embed a Google doc in your website, go to your Google Drive, open a document and choose File then Publish to Web, and you will be given an HTML iFrame Tag that can be embedded into you web page. You can change the height and width of the iFrame to match the document size. iFrame Instructions W3Schools
Downloading your document can be done very easily from the online version of a shared document just by choosing FILE and then DOWNLOAD AS from the menu.
To get up and running fast, just give the user a couple lines of instructions on how to download "Manually", then see if you can program the code.
Provide a link to your shared document instead of programming the button, and then work on the code.
Search Git Hub for Google Drive, you might find something there.
Some of the official Google code examples are way more complicated than you need, and will take a long time to figure out. The code examples in the documentation pages are simpler, but are almost never complete functioning code examples. You'll need to put lots of pieces of the puzzle together to make it work.

Related

Google Apps script get Parent URL to iFrame in Javascript

I've searched many forums and am pretty confident this will be a no, but I thought I would open it up to the community just in case ;)
I've been tasked with creating a tool on our Google Sites pages that records the visit times of our employees after visiting a page. It helps with confirming compliance with document access as well as activity logs. If an iFrame is on the same domain as the page it is hosted on, it's fairly easy to query the URL of the parent page from within the frame, but security limitations restrict this across domains or sub-domains.
I'm hoping that the fact that I am embedding a Google apps script into a Google sites page will give me more options. So far, I have tried the commands document.referrer, parent.document.location, parent.window.document.location, parent.window.location, parent.document.location.href, and the same commands from window and document perspectives. They all respond the same:
https://n-labp6vtqrpsdn12345neycmicqw7krolscvdkda-0lu-script.googleusercontent.com/userCodeAppPanel
When I want:
https://sites.google.com/mysite.com/mysite/test/test3
Do any Google veterans have additional tricks?
Edit: I've just tried to pass variables via an html link the Google image placeholder for Apps Scripts on Google Sites and got a tad bit farther. You see, I can run this url: https://script.google.com/a/macros/coordinationcentric.com/s/AKfycbxDX2OLs4LV3EWmo7F9KuSFRljMcvYz6dF0Nm0A2Q/exec?test=hello&test2=howareyou and get the variables test1 and test2 if I run the url in a separate window. If I try to embed that URL into the HTML page on Google Sites, it throws this mixed-content error:
trog_edit__en.js:1544 Mixed Content: The page at
'https://sites.google.com/a/mysite.com/mysite/test/test3' was loaded over HTTPS, but requested an insecure image 'http://www.google.com/chart?chc=sites&cht=d&chdp=sites&chl=%5B%5BGoogle+Apps+Script%27%3D20%27f%5Cv%27a%5C%3D0%2710%27%3D499%270%27dim%27%5Cbox1%27b%5CF6F6F6%27fC%5CF6F6F6%27eC%5C0%27sk%27%5C%5B%22Apps+Script+Gadget%22%27%5D%27a%5CV%5C%3D12%27f%5C%5DV%5Cta%5C%3D10%27%3D0%27%3D500%27%3D197%27dim%27%5C%3D10%27%3D10%27%3D500%27%3D197%27vdim%27%5Cbox1%27b%5Cva%5CF6F6F6%27fC%5CC8C8C8%27eC%5C%27a%5C%5Do%5CLauto%27f%5C&sig=TbGPi2pnqyuhJ_BfSq_CO5U6FOI'. This content should also be served over HTTPS.
Has someone tried that approach, perhaps?
In short - I understand it's not possible to investigate a parent URL from an iFrame in Google Sites.
The content of iframes/embedded content is hosted all over the place, separate from the site itself. The Same-Origin rules prevent checking as you've found.
Your first URL "https://n-labp...googleusercontent.com..." is where the script itself is hosted. Any output from the script, like HTML, will appear to come from here.
You can embed HTML and javascript directly in Sites using the Embed function. If you investigate that, you'll find that it's hosted at something like "https://1457130292-atari-embeds.googleusercontent.com..."
Calling parent will always give this *-atari-based URL, rather then the actual page it's hosted on.
A fairly lightweight solution is to use a combination of the two.
Use simple doGet pings and handle the work in your Apps Script.
On your Site, use Embed feature to insert:
<!DOCTYPE html>
<html>
<body onbeforeunload="return depart()">
<script>
var page = "testpage"; // manually set a name for each page you paste this code in to
var script = "https://script.google.com/macros/s/... your script, ending with exec ...";
fetch(script+"?page="+page+"&direction=arrive");
function depart(){
fetch(script+"?page="+page+"&direction=depart");
}
</script>
</body>
</html>
Then in your Apps Script:
function doGet(e){
var httpParams = e.parameter ? e.parameter : "";
// params is an object like {"page": "testpage1", "n": "1"}
var getPage = httpParams.page ? httpParams.page : "";
var getDirection = httpParams.direction ? httpParams.direction : "";
/* Handle it as you please, perhaps like: */
var user = Session.getActiveUser().getEmail();
/* maybe use a temporary active key if open to non-Google users */
/* first-time Google users will have to authenticate, so embed one frame somewhere full-size maybe, or just tell users to go to the script's link */
/* hand off to a helper script */
var time = new Date();
var timeUTC = time.toUTCString(); // I like UTC
doSomethingWithThis(user, direction, timeUTC);
/* etc... */
/* Return some blank HTML so it doesn't look too funny */
return HtmlService.createHtmlOutput("<html><body></body></html>");
}
Then publish as a web app. If you'll use temporary active keys instead of Google accounts, you'll have the script run as you and be available to anyone, even anonymous.
You've probably already solved this, but I hope it can be of use to someone else who stumbles across it!

Determine if active tab contains an editable Google Doc

Suppose my extension has obtained the URL for the current active tab using the method suggested in How can I get the current tab URL for chrome extension?, e.g.
chrome.tabs.query({
active: true,
lastFocusedWindow: true
}, function (tabs) {
// use first tab to obtain url
var tab = tabs[0];
var url = tab.url
});
How can I determine if the URL refers to a Google Doc to which I have editing rights? The distinction between ownership and being an invited collaborator is not important for this application. I'm interested only in Docs as opposed to Spreadsheets or Forms.
For context on what I'm trying to develop, see: How to manually generate notifications to a Google Doc collaborator?
Alternate answer, based on the Google Drive API rather than the Google Docs UI.
Before doing any of this, make sure to declare permissions in the manifest (to only match URLs that look like docs.google.com/document/*).
Here is a broad overview of the steps you could follow:
GET a
file,
which will return some metadata. You can use the URL you have to extract the relevant ID which is used in the GET request.
Use this metadata file resource to retrieve a permissions resource
In the permissions resource, look at the role attribute: it will be either owner, reader, or writer. You will not have editing rights if you are a reader, but should have editing rights otherwise.
Here is a side by side view of a google doc, where I created a doc, generated a sharing link, and opened it in a browser where I was not signed in to google. I would suggest using a content script to insert a "find" function which would return either true or false if it can locate the "view only" button in the DOM ("view only" meaning you do not have edit permissions). You could make the content script match URLs that look like docs.google.com/document/* only.
Caution: google changes UI pretty frequently so this may not be future-proof. Try inspecting the source of google docs in both situations to look for more clues.
Side by side view:
Source code in the chrome devtools:

How to solve Facebook Error 191 without having a website?

Me an my team are currently working on a software project at university and my present task is to bind our desktop javafx application with Facebook.
Basically I have an fxml method in a controller that is called when the user hits a "Share" button in my GUI. In the method I'd like to simply open up my .html file using a WebView:
#FXML
public void shareFacebookClicked() throws Exception{
// Setting up the webview
WebView webView = new WebView();
final WebEngine webEngine = webView.getEngine();
webEngine.setJavaScriptEnabled(true);
// Read the html file and let the web engine load it.
File file = new File(getClass().getClassLoader().getResource("facebook.html").toURI().getPath());
webEngine.load(file.toURI().toURL().toString());
Stage stage = new Stage();
stage.initOwner(this.stage);
stage.setScene(new Scene(webView, 1000, 800));
stage.show();
}
There is no problem with it, my "facebook.html" file is loaded and displayed correctly (well, almost correctly) in a web view.
The actual problem is that I'm constantly getting the 191 Facebook error saying that the link is not owned by the application. Since there are tons of posts and questions on this around the Internet (and yes I checked and read all of them) here are the things that I'm already aware of:
I registered my application on the Facebook Developer site. I know about the AppID and Secret
I know that this error mainly comes from the fact that people forget to set their website URL and domain in the Settings. The problem is that I don't have a website. I just have a simple .html file which I'd like to use in a web view inside of javafx. However, I tried all possible combinations advised on stackoverflow, facebook help centre and other forums which include: Setting website URL to http://localhost/, domain to localhost, enabling Embedded browser OAuth Login, setting the redirect URI to localhost too, etc.
I assume that my goal could be achieved by using RESTfb, Facebook4j or Graph API. When I tried those I had to stop because I faced problems with the user authentication plus I thought this current option would be the easiest way (considering this feature has LOW-priority in our software).
None of this solved my problem therefore I've given up researching the answer and decided to post my very own personal question.
In my opinion there must be some error in the .html file and/or I completely misunderstand something in the way this works. The .html file:
<html>
<head>
<title> Share on Facebook </title>
<script src="http://ajax.aspnetcdn.com/ajax/jquery/jquery-1.5.1.js"></script>
<script src="https://connect.facebook.net/en_US/all.js"></script>
<script type="text/javascript">
$(document).ready(function () {
$('#shareonfacebook').click(function (e) {
FB.ui({
appId: 'MY_APP_ID',
display: "popup",
method: "feed",
name: "Test",
link:"",
caption:"Test",
description: "Test",
});
});
});
</script>
</head>
<body>
<div id="fb-root"></div>
<button id="shareonfacebook" >Share</button>
<script>
FB.init({
appId : 'MY_APP_ID'
});
</script>
</body>
</html>
Partially I have this code from a tutorial site. Theoretically it should work. All I want is a dialog to come up where the user can publish the results of the workout he/she completed using our software. Currently when the .html file is opened up there is a simple button to click. This and all the "Test" strings inside of the javascript are only for testing. I just want to achieve that I can post something on my wall. The next step would be of course to somehow set the posting text dynamically etc.
Please tell me what I'm doing wrong or how I should approach the whole thing. Like I said, the task is minimal therefore it shouldn't be that difficult but I've been sitting in front of my laptop for 2 days without any success. I'm ready to post more code or give more information if it's needed.
Thank you for the help in advance!

Get current username on the client side on SharePoint 2007

I need to create a simple static web part - the only dynamic part is the current user login name (needs to be included in a URL parameter in a link).
I'd rather just use a content editor web part instead of a custom web part that I'll need to deploy. In fact, I already did that using JavaScript and ActiveX (WScript.Shell - full code below)
Is there a better, more native way to do it? What I don't like about the ActiveX approach is that it requires more liberal configuration of IE, and even when I enable everything ActiveX-related in the security settings there is still a prompt that needs to be clicked.
Cross-browser support is not a major issue, it's intranet - but will be a nice extra, too.
One way I can think of is to scrape the username from the top-right hand corner with jQuery (or just JavaScript), but is there something even cleaner?
Or maybe someone has already done the scraping and can share the code to save me some time ;-)
Here's my current solution:
<script language="javascript">
function GetUserName()
{
var wshell = new ActiveXObject("WScript.Shell");
var username = wshell.ExpandEnvironmentStrings("%USERNAME%");
var link = document.getElementById('linkId');
link.href = link.href + username.toUpperCase();
}
</script>
<P align=center>
<a id="linkId" onclick="GetUserName();" href="<my_target_URL>?UserID=">open username-based URL</a>
</P>
Include this Web part token in your content editor web part:
_LogonUser_
It outputs the same value as Request.ServerVariables("LOGON_USER")
I've done this before including in a hidden span and plain old document.getElementById to get the innertext.
My conclusion is that there's no better way to do that (which is also sufficiently easy).
I checked the source of the page and the username is not anywhere there, so can't be scraped by JavaScript/jQuery. The browser doesn't seem to be sending it with the request (as it does with your local IP and other client-related information), so can't be obtained from headers either.
The only other approach I can conceive is calling a web service from the client-side that would be an overkill for my scenario.

how can I check what site a javascript badge is embedded on?

I want to allow users to embed badges on their personal site or blogs with a snippet of javascript. The badge is customized on our site based on information in their profiles that at some point is "approved".
Is there a best practice to check what website the javascript is embedded on and if it does not match the website in their "approved" profile display nothing. If it matches inject the html etc.
Thanks
Two methods come to mind immediately:
Configure your server to log the "Referer" header of all requests for the javascript
and even check it against a list of approved urls, and return an error code (403 Forbidden looks like a winner).
Have the Javascript "call home" - reporting where it is - like so:
var etCallHome = new Image();
etCallHome = "http://yoursite.com/logger?url="+document.location.href;
You could also combine both approaches for luck. :-)
You could check the top url using:
var topUrl = top.location.href;

Categories

Resources