Dropbox integrated Chrome Extension - javascript

I'm attempting to upload files from a chrome extension to dropbox using the saver api. When the saver window loads however, no files are displayed in the GUI.
Clicking save or cancel does nothing. More importantly (I think), in the background the console throws the following message:
Unable to post message to
chrome-extension://[chrome extension ID]. Recipient has
origin https://www.dropbox.com.
I've read the cross-origin extension documentation, and I believe I have my manifest file configured correctly. It is as follows:
{
"name": "Pic Grabber",
"version": "2.0",
"permissions": [
"activeTab",
"tabs", "<all_urls>", "background",
"http://*/*",
"https://*/*",
"http://*",
"https://*"
],
"content_scripts": [{
"js": ["grabber.js"],
"matches": ["http://*/*", "https://*/*"]
}],
"background": {
"scripts": ["background.js"],
"persistent": false
},
"browser_action": {
"default_title": "Download pictures from this page.",
"default_icon": "icon.png",
"default_popup": "popup.html"
},
"manifest_version": 2,
"content_security_policy": "script-src 'self' https://www.dropbox.com/static/api/1/dropins.js; object-src 'self'"
}
I've verified the dropin works on some test code on a server I have access to. Relevent results of diff of the server (which works) and extension GET requests are as follows:
Server:
Request URL:https://www.dropbox.com/saver?origin=[SERVER'S ORIGIN]&app_key=[APP KEY]
Extension:
Request URL:https://www.dropbox.com/saver?origin=chrome-extension[CHROME EXTENSION ID]&app_key=[SAME APP KEY]
Server:
referer:[PATH TO TEST HTML FILE ON SERVER]
(No referer on Extension)
Server:
url:/saver?origin=http%3A%2F%2Fwww.uvm.edu&app_key=7tvbf4mpgd2v56z
Extension:
url:/saver?origin=chrome-extension[CHROME EXTENSION ID]&app_key=[APP KEY]
Server:
origin:[SERVER DOMAIN]
Extension:
origin:chrome-extension://[CHROME EXTENSION ID]
The html of my extension popup is as follows:
<!doctype html>
<!-- used to display the images found by the scripts and offer a save to dropbox button -->
<html>
<head>
<title>PicGrabber</title>
</head>
<body>
<h3>Download the following pictures:</h1>
<hr>
<div id="btn-container"></div>
<script type="text/javascript" src="https://www.dropbox.com/static/api/1/dropins.js" id="dropboxjs" data-app-key="[KEY]"></script>
<script type="text/javascript" src="popup.js"></script>
</body>
</html>
(popup.js is the source of my content-script that performs the bulk of the work of the extension. This script appears to be working correctly, but if I would help I'd be happy to post it as well).
I'm afraid I'm not sure exactly where the error lies. It seems that somehow, the dropbox API is unable to communicate properly with the extension, resulting in a malformed popup that cannot communicate with the Dropbox server.
Any tips/pointers in the right direction would be really appreciated. Thanks!
Edit: I've added the popup.js code to this post in the hope it will help-
/**
This is the popup.js file, used to receive the list of urls that the grabber content script has found and expose them to the popup.html file.
**/
function get_urls() {
var picUrls = chrome.extension.getBackgroundPage().IMAGE_URLS;
if (picUrls){
console.log("The popup.js is working")
// create a container object for the list
var listContainer = document.createElement("div");
// add it to the DOm
document.getElementsByTagName("body")[0].appendChild(listContainer);
// create a ul object for the list items
var listElement = document.createElement("ul");
// add that to the DOm
listContainer.appendChild(listElement);
saveThese = []
// loop through the urls, and append them to the ul object
for (var i = picUrls.length - 1; i >= 0; i--) {
var listItem = document.createElement("li");
// listItem.innerHTML = "<a href='" + picUrls[i].src +"'>" + picUrls[i].name + "</a><img src='" + picUrls[i].src + "'width=25%, height=25%></img>";
listItem.innerHTML = "<img src='" + picUrls[i].src + "'width=25%, height=25%></img>";
listElement.appendChild(listItem);
saveThese.push({
'url':picUrls[i].src,
'filename':picUrls[i].name
});
}
// create dropbox saver dropin
options = {
files: saveThese,
success: function() {},
progress: function(progress) {},
cancel: function() {},
error: function(errmsg) {}
} // end options
}
Dropbox.createSaveButton(options);
var btn = Dropbox.createSaveButton(options);
document.getElementById('btn-container').appendChild(btn);
}
window.onload = get_urls();

Related

chrome.runtime.OnMessage.addListener returns duplicate messages

I am building a simple page-scraping chrome extension to get a page's title and the contents of a shopping cart. I am getting the shopping cart contents twice but not the tittle page. The chrome.runtime.onMessage.addListener() function is returning the same message twice to popup.html and getting a duplicate of the shopping cart's content and no page title. I have tried to construct the chrome.runtime.onMessage.addListener()in different ways, to no avail. Please advise on where I went wrong or suggest a better approach?
manifest.json
(permissions are allowed on all urls but I'm currently testing the extension on the checkout page of an ecommerce website)
"manifest_version": 2,
"name": "Webscraper Extension",
"description": "Webscraper extension for Chrome",
"version": "1.0",
"background": {
"scripts": ["popup.js"],
"persistent": true
},
"permissions": [
"tabs",
"http://*/",
"https://*/"
],
"browser_action": {
"default_icon": "logo.png",
"default_popup": "popup.html"
}
poppup.html
<!doctype html>
<html>
<head>
<title>Webscraping Extension</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<h3>Checkout</h1>
<p id='pagetitle'>This should change to the scraped title!</p>
<div id='cart'>Cart here!</div>
<button id="checkout" class "button">Checkout</button>
</body>
<script src="popup.js"></script>
</html>
popup.js
// Inject the payload.js script into the current tab after the popout has loaded
window.addEventListener('load', function (evt) {
chrome.extension.getBackgroundPage().chrome.tabs.executeScript(null, {
file: 'payload.js'
});;
});
// Listen to messages from the payload.js script and write to popout.html
chrome.runtime.onMessage.addListener(function (message) {
document.getElementById('pagetitle').textContent = message;
document.getElementById('cart').textContent = message;
});
payload.js
// send the page title as a chrome message
chrome.runtime.sendMessage(document.title);
//send the cart as chrome message
var result = "";
var cartitems = document.getElementsByClassName("item-list");
for (var i = 0; i < cartItems.length; i++) {
result += cartItems[i].textContent;
}
chrome.runtime.sendMessage(result);
You have only one message listener that overwrites the textContent of both pagetitle and cart with whatever message it receives. Therefore, both are overwritten with result, which is the latest message received.
Try discriminating the messages with something like:
popup.js
chrome.runtime.onMessage.addListener(function (message) {
if (message.title) document.getElementById('pagetitle').textContent = message.title;
if (message.cart) document.getElementById('cart').textContent = message.cart;
});
payload.js
// send the page title as a chrome message
chrome.runtime.sendMessage({title:document.title});
//send the cart as chrome message
var result = "";
var cartitems = document.getElementsByClassName("item-list");
for (var i = 0; i < cartItems.length; i++) {
result += cartItems[i].textContent;
}
chrome.runtime.sendMessage({cart:result});

How to send data entered in the extension menu to another file

I'm writing an extension, I made a menu to it in which the user enters some data. It is necessary to make so that on a click on the button (in the menu of expansion) these data.
Here is how it must works: background.js is the file that is responsible for js in the extension menu. content.js is the file that is responsible for making changes to the DOM on the sites.
document.getElementById('btn').onclick = function() {
var first = document.getElementById('first').value;
var second = document.getElementById('second').value;
//sending in content.js
chrome.extension.sendMessage('hello');
}
<head>
<script type="text/javascript" src="content.js"></script>
<script type="text/javascript" src="background.js"></script>
</head>
<input type="text" id="first">
<input type="text" id="second">
<input type="button" id="btn" value="send">
content.js Getting data:
chrome.extension.onMessage.addListener(function(request){
if(request=='hello'){
console.log('1. Get: ', request);
}
});
But from background.js i get nothing.
Here is manifest.json
{
"manifest_version": 2,
"version": "1.3",
"description": "name",
"browser_action":{
"default_popup": "content/popup.html"
},
"background": {
"persistent": false,
"scripts": ["content/background.js"]
},
"content_scripts": [
{
"matches": [ "https://google.com/*" ],
"js": ["content/content.js"],
"css": ["content/qq.css"],
"run_at": "document_end"
}
]
}
It turns out that I need to send the entered data in the field with the button send to a file that will insert this data into the page I need. How to do it?
Help, because if I put the code that it does in my js file, then it tries to take this data frominput on the page, and not from the extension menu.
Here is the structure:
Ok, there seems to be a couple of n00b issues here:
background.js is a script that runs in the background of all tabs/pages. (The "background" section in the manifest.json specifies this).
PS: The way to debug the background.js is to open chrome's extension page (chrome://extensions/) and click on "Inspect Views: background page" from there. Typically, this is where most of your code would be.
content.js will automatically be inserted into all google.com pages, according to your manifest.
popup.html and it's code only exists as long as the popup is visible. It's typically very light, with little code. So, in your popup.html, remove the two existing <script> entries you have, and just use a single script, (typically popup.js):
<script type="text/javascript" src="popup.js"></script>
When sending info from the popup (or background) to the current tab (in your case it's going to be google.com only) you use the general code:
// Get the current tab & tell it to do something
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
var currentTab = tabs[0];
var id = currentTab.id;
chrome.tabs.sendMessage(id,
{ action: 'foo', data:... },
response => { console.log('some response from content.js is:' + response); });
});
but to send a message to the background (from a page or your content script inside google.com), you'd just use this chrome.runtime.sendMessage({action:'foo', data:...});
So, your code should probably be something like:
popup.html
<head>
<script type="text/javascript" src="popup.js"></script>
</head>
<body>...
popup.js:
document.getElementById('btn').onclick = function() {
var first = document.getElementById('first').value;
var second = document.getElementById('second').value;
//sending in content.js
var foo_data="I am foo";
// Get the current tab & tell it to do something
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
var currentTab = tabs[0];
var id = currentTab.id;
chrome.tabs.sendMessage(id,
{ action: 'hello', foo:foo_data, first:first, second:second },
response => { console.log(response); });
});
}
background.js
(nothing)
content.js
chrome.runtime.onMessage.addListener(function(request,sender, sendResponse){
if(request.action=='hello'){
console.log(request.foo + ' ' request.first + ' ' + request.second);
sendResponse('I got foo!');
}
});
If it's any help, I've a tiny project that I use to get started on webextension projects here: https://github.com/cmroanirgo/webextension-template. It's got some code to help with making it work cross browser (Firefox, Opera & maybe Edge)
I hope this helps.

create chrome extension to send data into localhost server

i want to create a google chrome extension to send data from a a popup form into localhost server. i created below files. Everything works fine but data does not send to localhost server.
could anyone please help me where is my mistake?
thanks.
manifest.json
{
"manifest_version": 2,
"name": "server Plug-ins",
"description": "Send data to database",
"version": "1.0",
"icons": {
"48": "icon.png"
},
"permissions": [
"history",
"browsingData",
"tabs",
"<all_urls>",
"http://192.168.1.222/*",
"storage"
],
"browser_action": {
"default_icon": "icon.png",
"default_popup": "popup.html",
"default_title": "Send data to server!"
}
}
alert.js
document.write(" i am here . . .");
// Create our XMLHttpRequest object
var hr = new XMLHttpRequest();
// Create some variables we need to send to our PHP file
var url = "http://192.168.1.222/my_parse_file.php";
var fn = document.getElementById("name").value;
var ln = document.getElementById("details").value;
var vars = "name="+fn+"&details="+ln;
hr.open("POST", url, true);
// Set content type header information for sending url encoded variables in the request
hr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
// Send the data to PHP now... and wait for response to update the status div
hr.send(vars); // Actually execute the request
popup.html
<body>
<label for="">Name</label><br><input type="text" id="name"> <br>
<label for="">Details</label><textarea id="details"></textarea>
<input id="clickme" name="myBtn" type="submit" value="click me">
<script type="text/javascript" src="popup.js"></script>
</body>
popup.js
function hello() {
chrome.tabs.executeScript({
file: 'alert.js'
});
}
document.getElementById('clickme').addEventListener('click', hello);
I think that the problem is that your popup input elements cannot be accessed in the context were the alert.js script is running.
In the alert.js's context, document refers to the document of the tab in which you've inject the script.
You can do something like this to make it work, replace the content of your popup.js file with this:
function hello() {
function contentScript(fn, ln){
document.write(" i am here . . .");
var hr = new XMLHttpRequest();
var url = "http://192.168.1.222/my_parse_file.php";
var vars = "name="+fn+"&details="+ln;
hr.open("POST", url, true);
hr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
hr.send(vars);
}
var fn = document.getElementById("name").value;
var ln = document.getElementById("details").value;
chrome.tabs.executeScript({
code: (contentScript.toString() + "\ncontentScript('" + fn + "', '" + ln + "');")
});
}
document.getElementById('clickme').addEventListener('click', hello);
You can remove your alert.js file because now, the extension will inject JavaScript code directly instead of injecting a file.

Chrome Ext. OAuth 2.0 with Youtube API v3

I'm building a Chrome Extension with Youtube API access. But I don't get an authentification against Youtube. It looks like there is no up-to-date source or sample. The Tutorial here uses some chrome-oauth lib from 2010, the other Source here uses a different lib, I guess its useful for browser based Auth & API access.
I have a Dev Key, a client id for installed apps (type: Chrome), YT API Key (Simple API Access).
My Chrome App uses following manifest:
{
"name": "Youtube Chrome Ext",
"version": "1.0",
"manifest_version": 2,
"description": "Youtube Chrome Ext",
"app": {
"launch": {
"local_path": "main.html",
"container":"tab"
}
},
"options_page": "settings.html",
"background": {
"page": "background.html"
},
"permissions": [
"tabs",
"http://gdata.youtube.com/",
"https://www.google.com/accounts/OAuthGetRequestToken",
"https://www.google.com/accounts/OAuthAuthorizeToken",
"https://www.google.com/accounts/OAuthGetAccessToken",
"https://www.googleapis.com/auth/youtube"
]
}
with following backgroundHandler.js file for authentification with Youtube over oAuth2.0:
(function(global){
global.backgroundHandler = {
initBackground : function(){
var self = this;
var oauth = ChromeExOAuth.initBackgroundPage({
'request_url' : 'https://www.google.com/accounts/OAuthGetRequestToken',
'authorize_url' : 'https://www.google.com/accounts/OAuthAuthorizeToken',
'access_url' : 'https://www.google.com/accounts/OAuthGetAccessToken',
'consumer_key' : 'anonymous',
'consumer_secret' : 'anonymous',
'scope' : 'http://gdata.youtube.com',
'app_name' : 'YouTube Ext'
});
oauth.authorize(this.onAuthorized());
},
onAuthorized : function() {
//I'm not authorized - no window with grant access was displayed ...
}
};
})(window);
document.addEventListener('DOMContentLoaded', function () {
backgroundHandler.initBackground();
});
Note Youtube don't uses consumer key & secret.
background.html:
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="js/oAuth/chrome_ex_oauthsimple.js"></script>
<script type="text/javascript" src="js/oAuth/chrome_ex_oauth.js"></script>
<script type="text/javascript" src="js/handler/backgroundHandler.js"></script>
</head>
<body>
</body>
</html>
My biggest problem is to get somehow the OAuth done and do authentificated requests against Youtube. It looks like for me, that there exists no source on the whole www which is up-to-date.
I would be glad if someone could help me.
BR,
mybecks
I did a little experiment and I tested this library:
https://github.com/borismus/oauth2-extensions
I followed the steps indicated by the author and I changed the popup.html and popup.js files, trying show the YouTube video recommendations for the current user
popup.html:
<head>
<title>YouTube Recommendations</title>
<script src="oauth2/oauth2.js"></script>
<script src="popup.js"></script>
<style>
#success { display: none; }
</style>
</head>
<div id="loading">
Loading...
</div>
<div id="success">
<ul id="activities"></ul>
</div>
popup.js:
var google = new OAuth2('google', {
client_id: '{YOUR_CLIENT_ID}',
client_secret: '{YOUR_CLIENT_SECRET}',
api_scope: 'https://www.googleapis.com/auth/youtube'
});
google.authorize(function() {
var YOUTUBE_ACTIVITIES_URL = 'https://www.googleapis.com/youtube/v3/activities?part=id%2Csnippet%2CcontentDetails&home=true&maxResults=50&key=AIzaSyCx1xab1VHU7NdT6d2_x8i3p9RIZrtgR8k';
var loading = document.getElementById('loading');
var success = document.getElementById('success');
var activities = document.getElementById('activities');
// Make an XHR that retrieve activities with YouTube Data API
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(event) {
if (xhr.readyState == 4) {
if(xhr.status == 200) {
// Great success: parse response with JSON
var activitiesResponse = JSON.parse(xhr.responseText);
var items = activitiesResponse.items;
for (var i=0; i<items.length; i++) {
// Iterates over activities
var activity = items[i];
if ((activity.snippet.type == 'recommendation')&&(activity.contentDetails.recommendation.resourceId.videoId)){
activities.innerHTML += '<li>' + activity.snippet.title + '</li>';
}
}
loading.style.display = 'none';
success.style.display = 'block';
} else {
// Request failure: something bad happened
}
}
};
xhr.open('GET', YOUTUBE_ACTIVITIES_URL, true);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.setRequestHeader('Authorization', 'OAuth ' + google.getAccessToken());
xhr.send();
});

Develop a Google Chrome extension using Google Translate

Hi, I am developing a Google Chrome extension:
It is a dictionary that uses the Google translate API,When the user selects a text on the page I would like a popup to appear and show the selected text definition,
I have this code in my js file :
var req = new XMLHttpRequest();
req.open(
"GET",
"https://www.googleapis.com/language/translate/v2?" +
"format=html" +
"q=" + get_text_selection() + // Source Text
"source=en&" + // Source Language
"target=fa&" + // Target Language
true);
req.send(null);
function get_text_selection() {
if (window.getSelection)
return window.getSelection();
if (document.getSelection)
return document.getSelection();
if (document.selection)
return document.selection.createRange().text;
return '';
}
and this code in my Manifest.json file :
{
"name": "Google Translator",
"version": "1.0",
"manifest_version": 2,
"description": "This Extention helps you to translate text in your page",
"browser_action": {
"default_icon": "Dictionary-Book-icon.png",
"default_popup": "popup.html"
},
"permissions": [ "http://*/*", "https://*/*", "tabs" ]
}
and this code in my html file :
<!doctype html>
<html>
<head>
<title>Getting Started Extension's Popup</title>
<style>
body {
min-width:357px;
overflow-x:hidden;
}
</style>
<!-- JavaScript and HTML must be in separate files for security. -->
<script src="popup.js"></script>
</head>
<body>
</body>
</html>
but it's not working?
Where is my problem?
Thanks for your advice.
First of all Google Translate API is a paid service now. To use Google Translate API you need to get an API key from Google, you can get more information from here. After you get an API key your url should be like
"https://www.googleapis.com/language/translate/v2?key=INSERT-YOUR-KEY&source=en&target=fa&q=Hello%20world" // "Hello world" is query here
Which is in your case
"https://www.googleapis.com/language/translate/v2?key=INSERT-YOUR-KEY" + "&format=html" + "&source=en" +"&target=fa" + "&q=" + get_text_selection()
Using following request (using my valid key from the browser address bar)
"https://www.googleapis.com/language/translate/v2?key=my_valid_key&format=html&q=home&source=en&target=fa" // I've replaced my key with my_valid_key
I've got this result
{ "error": { "errors": [ {
"domain": "usageLimits",
"reason": "dailyLimitExceeded",
"message": "Daily Limit Exceeded" } ],
"code": 403,
"message": "Daily Limit Exceeded"
}
}
Google Translate API no longer free and Translate API FAQ.

Categories

Resources