
In this topic I will try to talk about working with the VKontakte API from the extension for Google Chrome.
In fact, the most difficult part is getting a token to access the vkontakte API, but first things first. For clarity, I will give an example of a minimally useful extension (so that it does at least something useful, but in general it was made for convenient rehosting of gifs). And so the expansion will be simple, but working.
What this extension does:
')
1. It is registered in the context menu of the browser.
2. Gets the URL of the image where we clicked and selected the menu item of our extension.
3. Authorized via OAuth 2.0 protocol and gets access to the VKontakte API (if it is not already there), and also saves the token in the google chrome repository.
4. Uploads the image from the browser cache to blob using XMLHttpRequest.
5. It performs several requests to the VKontakte API and saves the image in the Documents section (on the VKontakte site). At the same time showing the result of the work at the end.
Why section documents? Very simple, the limit is 200 MB per file and unlimited space for documents, plus an excellent download speed.
I believe that you already have basic knowledge of google chrome extensions, otherwise you should
read the documentation - everything is very simple. And here
on Habré there were enough posts even for the most beginners. Just look at
how to register applications for VKontakte, everything is also very simple there. You still have to read it, so do not delay. Quickly register the application for VKontakte
by this link .
All source code extensions are available on
github . I bring here pieces of code from this extension for clarity. The extension itself (already assembled, approved and ready for use) is located
here .
Let's start with a brief description of the components of our extension:
manifest.json - manifest, the main file extension. Description of our extension with all options and access rights.
background.js is the main script that registers and receives notifications about a click on a picture, as well as receives a token to access the VKontakte API.
upload.html - a stub page showing that the extension is busy with something (an animated gif is displayed) while upload.js is running.
upload.js is a script that directly uploads a picture to the server on VKontakte.
wait.gif - gif itself - progress bar.
imageinfo-128.png - the application icon is large.
imageinfo-16.png - application icon is small.
imageinfo-48.png - application icon is mediocre.
Now in more detail about important things:
In the manifest, the extensions indicate the components we need to work:
"permissions": [ "contextMenus", "tabs", "storage" , "http://*/*", "https://*/*" ]
We get access to the browser context menu, tabs, browser storage and the extension will be active on all opened pages.
Further, in our main script, described in the manifest as:
"background": { "scripts": [ "background.js" ]}
Add our
item to the browser context menu :
chrome.contextMenus.create( { "title": "Rehost on vk.com", "type": "normal", "contexts": ["image"], "onclick": getClickHandler() });
Accordingly, by clicking on our item in the context menu, the getClickHandler () function will be called. Further, in getClickHandler () interesting begins already. To begin with, we check the token to access the VKontakte API in
the google chrome storage , all of a sudden we have already received it.
chrome.storage.local.get({'vkaccess_token': {}}, function(items) { ...
The storage API in google chrome is asynchronous, so you have to work with it that way. In this extension, I use local storage, although nothing prevents you from using a special, sync storage, which will be synchronized with all your browsers (google chrome) via a google account. Very convenient for many things, but there is no point specifically for this extension. The main thing is not to forget that the sync storage is limited in the number of stored items and their size. Local storage on the contrary, allows you to store a generally unlimited amount of information.
And so, we checked and found out that there is no token in the repository. You need to log in and get a token to access the
VKontakte API using OAuth 2.0 protocol . To do this, we will open a tab with a special address on the server of VKontakte and transmit to it:
oauth.vk.com/authorize?client_id=3315996&scope=docs,offline&redirect_uri=http%3A%2F%2Foauth.vk.com%2Fblank.html&display=page&response_type=token
1.
client_id = 3315996 - this is your application id, which you will get on VKontakte. You need
to register your application
at this address . To register the application and get your id, just write the name and select the Standalone application. Do not use my id for your applications, it will not lead to anything good. For each application, you must register your client_id.
2.
scope = docs, offline - these are the requested
api to which your application
will have access . Since we do not need anything but documents, we only request access to them. Access offline - gives us a token that will not expire after a certain time. Otherwise, it will be necessary to receive the token from time to time again.
3.
redirect_uri = since we have a separate application and do not have any own server, we select a special uri on the VKontakte server, to which the browser will receive the received token (well, or not received). The token will be in the parameters of this uri (All these are parts of the authorization standard using the OAuth 2.0 protocol. Very simple and convenient).
4.
display = page - authorization window appearance
5.
response_type = token - that would be requested from the server vkontakte.
All these options are clearly written on
the developers page of VKontakte .
And so, as is the authorization of VKontakte. Our extension opens a tab in the browser on a specially created uri on the VKontakte server, where in the parameters it requests the necessary access.
var authUrl = 'https://oauth.vk.com/authorize?client_id=3315996&scope=docs,offline&redirect_uri=http%3A%2F%2Foauth.vk.com%2Fblank.html&display=page&response_type=token'; chrome.tabs.create({url: authUrl,selected: true}, function(tab) {...
The VKontakte server checks whether the user is authorized on the site (if not, you will first need to enter a password and login)
(these are pictures from VKontakte documentation, given for example)

and then asks if your application is allowed to what it requests.

If you answer - allow, then go to the page specified in
redirect_uri and in the parameters of this uri will be the access_token requested by us to access the VKontakte API. If you do not allow, then the parameters will be
error = access_denied and nothing will come of it.
Of course, we will allow access and in the tab that we open, we will redirect to the
oauth.vk.com/blank.html page with the token we need in the parameters. To get a token, after opening a tab, we install a tab update handler.
authTabId = tab.id; chrome.tabs.onUpdated.addListener(function tabUpdateListener(tabId, changeInfo) { if(tabId == authTabId && changeInfo.url != undefined && changeInfo.status == "loading") { if ( changeInfo.url.indexOf('oauth.vk.com/blank.html') > -1 ) { ...
Save the Id of our tab and wait until the user allows us access and access_token appears in the uri tab. As soon as we find the access_token when updating the tab data, we retrieve it and store it in our storage:
chrome.storage.local.set({'vkaccess_token': accToken}, function() { ...
And then immediately proceed to the second part of our expansion. Namely, receiving pictures and downloading pictures to the server vkontakte.
To do this, we will redirect our tab (the same) to the pre-prepared page in our extension -
upload.html . In the parameters we will give everything that we need for work. These are access tokens and uri images. This page is only needed to show the user that something is happening. Suddenly, the page will take a lot of time, and our page may at this time show an animated progress bar. Something is moving - the user is calm.
Here we go if the token has already been received and stored in storage.
chrome.tabs.update(tabId,{'url': 'upload.html#' + imgSrc + '&' + accToken,'active': true}, function(tab){});
On our
upload.html page
, everything is simple. By default, it shows the progress bar - gif. And in the background, the
upload.js script
works .
There is nothing especially there: in the beginning you get our picture from the browser cache as a blob, by performing a GET request.
var x = new XMLHttpRequest(); x.onload = function() { .. } x.responseType = 'blob'; x.open('GET', imageUrl); x.send();
The picture is already downloaded by the browser itself and it will be fast. At the same time, we go around all sorts of clever hosting of pictures that show a picture upon arrival from Google, and as soon as the referrer becomes not Google, an advertisement of the resource appears under the picture. As a result, we have a clean picture of what we saw it.
Next comes a series of requests to the API vkontakte strictly in accordance with the documentation. We get the address of the server to load the image (
docs.getUploadServer ), create the form using FormData () and add the resulting blob with the image, assigning it the name of the image. We send the picture with the POST on the server, save the picture on the server (
docs.save ) and receive the uri pictures in the answer, go over it to show the user in our tab a freshly loaded picture already on the VKontakte server.
That's all. I am not a JavaScript specialist, so do not blame me for the quality of the code.