How to send tweet from Google Chrome Extension? - google-chrome-extension

I am following Google oAuth tutorial. And I am having some trouble with authorizing user.
I am sending user to twitter for authorization. As this is chrome extension and there is no callback. I dont know how to send tweet on the behalf of that user.
How I am doing things:
I have a background page that has the code of authorizing user from twitter. On the time when user install the extension, background page send that user to twitter for authorization. My authorization method is getting called with their call back. But dont know if I am having everything to make a tweet.
Now when user will click on extension icon, the popup.html will be appear. And on this page I want user to send a tweet. How?
Following is my code:
manifest.json
{
"name": "TweetChrome",
"version": "1.0",
"description": "Tweet from Chrome",
"browser_action": {
"default_icon": "images/share.png",
"popup": "popup.html"
},
"permissions": [
"tabs",
"http://ajax.googleapis.com",
"*://*.twitter.com/*",
"clipboardWrite"
],
"options_page": "options.html",
"background_page": "background.html"
}
background.html
I am getting some html page markup in resp of callback method. I dont know what it is for?
var oauth = ChromeExOAuth.initBackgroundPage({
'request_url': 'https://api.twitter.com/oauth/request_token',
'authorize_url': 'https://api.twitter.com/oauth/authorize',
'access_url': 'https://api.twitter.com/oauth/access_token',
'consumer_key': 'key',
'consumer_secret': 'secret',
'scope': '',
'app_name': 'TweetChrome'
});
oauth.authorize(onAuthorized);
function onAuthorized() {
var url = 'https://api.twitter.com/oauth/authorize';
/*as they are optional, i left empty*/
var request = {
'force_login': '',
'screen_name': ''
};
oauth.sendSignedRequest(url, callback, request);
};
function callback(resp, xhr) { alert('it get called too'); };
popup.html
To tweet I am using a borrowed twitter.js. I didn't wrote it.
Twitter.verify_credentials({install: true});
Twitter.update("test");
My approach of oauth is right on having it in a background page? As my authorization is getting call how much far I am to make a tweet for a user?
Any help will be appreciated. I am hopeful to solve this issue to finish my extension.

You don't need to request https://api.twitter.com/oauth/authorize in onAuthorized - once you get to that function, you already have a key and the user has authenticated.
Try requesting http://api.twitter.com/1/account/verify_credentials.json in onAuthorized instead. You should see a JSON response with the user's information.

Related

How can I modify response headers using webRequest.onHeadersRecieved?

I'm writing an extension that gives a Chrome (and Firefox) user the ability to selectively modify response headers. Mainly it's for QA people to test that the front-end handles error modes properly (e.g. if a given route returns a 500, then the correct dialog displays).
This implementation uses the Chrome webRequest API.I know that the extension is loading, and I can block requests with listener1. However, listener2 does not behave as expected, as it neither modifies the status code nor does it add the josh header. I have verified this in Chrome's network monitor tab. Both filters work, as far as it goes (I was testing with an explicit https filter because I know the webRequest API doesn't work with file:// urls.)
As part of my troubleshooting process, I've disabled all other Chrome extensions, so I'm pretty sure nothing else is modifying headers.
let count = 0;
function listener1(details){
return {cancel: true};
}
function listener2(details){
console.log(count++, details);
if (!details) return;
for (let i = 0; i < details.responseHeaders.length; i++){
if (details.responseHeaders[i].name === 'status'){
details.responseHeaders[i].value = '500';
break;
}
}
details.responseHeaders.push({name: 'josh', value: 'count: ' + count});
// Response is of type "Blocking Response"
return {responseHeaders: details.responseHeaders};
}
const filter1 = '<all_urls>';
const filter2 = 'https://www.google.com/'
chrome.webRequest.onHeadersReceived.addListener(listener2, { urls: [filter2] }, ['blocking', 'responseHeaders']);
Here is my manifest:
{
"name": "Server Error Simulation Extension",
"description" : "Base Level Extension",
"version": "1.0",
"manifest_version": 2,
"browser_action": {
"default_popup": "popup.html",
"default_icon": "logo.png"
},
"background": {
"persistent": true,
"scripts": ["background.js"]
},
"permissions": [
"activeTab",
"storage",
"webRequest",
"webRequestBlocking",
"*://*.com/"
]
}
Note that I'm only wanting to modify headers, so this Chrome bug about modifying response bodies doesn't apply. Also, Firefox copied this API from Chrome so I've tagged Firefox as well.
Partial answer: HTTP status is not a header, according to the RFC 2616 which defines HTTP 1.1. Status is it's own thing, called a Status-Line. And it does look different, textually, since it doesn't have a key: prefix unlike everything else in the header.
As for why my custom header doesn't show up in network monitor, I'm not sure. Maybe it's a bug in the devtools, or something else.
In any event, whether or not its officially a header, the Chrome webRequest API exposes it as a "status" header, and I believe it should support modification in a way consistent with other headers.

chrome-extension: How to detect and retrieve url from tab when redirect happens?

Just started on chrome - extension development. I'm trying to retrieve the url from a newly created tab but my expected url comes from the server as response with 302 status code and browser redirects to it. I tried with chrome.tabs.onUpdated.addListener() but its not detecting the URL with 302. I searched in chrome.tabs API and i don't see any events for redirect. What is the best way to detect if any redirection is happening in the tab and get the url from that object?
My use case is, when user clicks on one button, it opens a new tab with a specific url and since this url is SSO protected which will go through SSO dance and finally goes to target page.During SSO dance there are 3 redirects happening before serving the target page and i'm trying to detect and retrieve one of the url in the redirect process.
P.S: This is my first question and i'm excited to be part of this community. Thanks in advance.
Update1: I tried with chrome.webRequest.onBeforeRedirect.addListener
manifest.json
{
"name": "CatBlock",
"version": "1.0",
"description": "I can't has cheezburger!",
"permissions": ["alarms", "webRequest", "webRequestBlocking", "activeTab", "tabs",
"https://*/*"],
"background": {
"scripts": ["background.js"]
},
"manifest_version": 2
}
background.js
chrome.webRequest.onBeforeRequest.addListener(
function(info) {
console.log("Cat intercepteddd: " + info.url);
});
chrome.webRequest.onBeforeRedirect.addListener(
function(info) {
console.log("Cat intercepteddd: " + info.url);
});
chrome.webRequest.onResponseStarted.addListener(
function(info) {
console.log("Cat intercepteddd: " + info.url);
});
const responseListener = function(details) {
const headers = details.responseHeaders;
for (let i = 0; i < headers.length; i++) {
if (headers[i].name == "location") {
console.log("redirectURL:" + headers[i].value);
}
}
return { responseHeaders: newHeaders};
};
chrome.webRequest.onHeadersReceived.addListener(
responseListener,{urls: [URL_TO_DETECT]}, ["blocking", "responseHeaders"]);
Usually 303 redirects will be caught on the response headers, use the above code to get the redirect url from response header, make sure to have the code in background.js

Slack Interactive Messages: No POST response from Slack

I'm constructing and sending the message attachment:
var zz = {
"text": "Would you like to play a game??",
"attachments": [
{
"text": "Choose a game to play",
"fallback": "You are unable to choose a game",
"callback_id": "wopr_game",
"color": "#3AA3E3",
"attachment_type": "default",
"actions": [
{
"name": "chess",
"text": "Chess",
"type": "button",
"value": "chess"
}
]
}
]
}
web.chat.postMessage(message.source.channel, '', zz);
The message with buttons displays fine on Slack, but when I tap a button there's no POST response from Slack to my local ngrok or express route:
app.post('/slackaction', function(req, res)
While other messages are posting fine to this route.
I'm seeing this error from Slack after I tap a button:
"Oh no, something went wrong. Please try that again"
Slack Interactive Messages request_url set as:
https://xxx.ngrok.io/slackaction
Thanks to comments from Taylor Singletary for pointing me in the right direction.
The test tokens or a bot token for Custom Integrations can post Interactive Messages but you need an App to handle them.
To fix it you need to add a bot to your app here: https://api.slack.com/apps
and then get the access token for that bot.
You can use the Slack button generator here: https://api.slack.com/docs/slack-button# to get the OAuth URL and paste it on a browser.
Then from your app handle the OAuth flow, store the access token and use that with chat.postMessage.
Then you should receive the POST request when clicking on the message buttons.

Message Passing Example From Chrome Extensions

I'm using the example from the Google tutorial and finding it difficult to pass a simple message to the content script from the popup.
Can you provide some suggestions on how to pass a simple message and view it either in the console log or alert?
manifest.json
{
"manifest_version": 2,
"name": "msg-test",
"description": "message test",
"version": "1.0",
"browser_action": {
"default_icon": "icon.png",
"default_popup": "popup.html"
},
"background": {
"scripts": ["background.js"],
"persistent": true
},
"content_scripts": [{
"matches": ["http://*/*","http://www.site.com/*"],
"js": ["content.js"],
"run_at": "document_end"
}],
"permissions": [
"tabs",
"http://*/*"
]
}
background.js
chrome.runtime.onConnect.addListener(function(port){
port.postMessage({greeting:"hello"});
});
content.js
var port = chrome.runtime.connect({name:"content"});
port.onMessage.addListener(function(message,sender){
if(message.greeting === "hello"){
alert(message.greeting);
}
});
popup.js
window.onload = function() {
document.getElementById('btn2').onclick = function() {
alert("button 2 was clicked");
};
document.getElementById('btn1').onclick = function() {
alert("button 1 was clicked");
};
}
*Note: In this example the content script will fire when the page matches manifest.json and the alert box will show.
First, I wouldn't message pass between your popup and your content script. I would message pass between your Background page and your content scripts. Your popup page should only be used to show some ui to interact with your app.
With that being said, I will show you the way to pass messages between your background and your content script.
In your content script:
//This line opens up a long-lived connection to your background page.
var port = chrome.runtime.connect({name:"mycontentscript"});
port.onMessage.addListener(function(message,sender){
if(message.greeting === "hello"){
alert(message.greeting);
}
});
In your background page(possibly your popup? but I don't recommend it)
chrome.runtime.onConnect.addListener(function(port){
port.postMessage({greeting:"hello"});
});
Here is the sequence of events that will take place:
Your application will inject your content script into the page
Your content script will open up a port to communicate with the background script.
Your background script will be notified that a port was open, allowing it to send a message to it, or attach a message listener to it.
In the background script or the content script, you can listen for messages by using port.onMessage.addListener(). provided that port is in scope. Using ports is much easier to grasp and allows for simple, two way communication!
Edit:
If you would like to pass messages to your background page from your popup script, use the exact same method:
var port = chrome.runtime.connect({name: "popup-port"});
port.postMessage({status:"poppedup"});
Edit 2:
To navigate your user to a new page, do this:
function navigateToPage(url){
chrome.tabs.query({url: url}, function(tabs) {
var tab = tabs[0];
return tab ? chrome.tabs.update(tab.id, {active:true}) : chrome.tabs.create({url: url});
});
}
});
What this function does is, it checks to see if there is a tab with the url you want to go to, if there is, switch to it, else, create a tab with that url and navigate to it.

http requests not working chrome extension

I am developing a chrome extension that requires corss domain XHR. So I need to make get requests to a server and get some text out of it. I am currently loading the unpacked extension from my computer. The script doesn't seem to be working.
Here is my manifest.json:
{
"name": "My extension",
"version": "1.1",
"manifest_version": 2,
"description": "Testing http requests",
"browser_action": {
"default_icon": "icon.png",
"default_popup": "popup.html"
},
"permissions": [
"http://*/"
]
}
And here is the script that performs the get request (from this tutorial):
function showresponse(){
var query = document.getElementById("query").value;
var url = "http://blah.com/search.php?term="+query;
var xhr = new XMLHttpRequest();
xhr.open("GET", url, true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
console.log("hello world");
document.getElementById("container").innerHTML = xhr.responseText;
}
}
xhr.send(null);
}
The id's etc are set according to my popup.html file and that's set up correctly and it includes this js file containing the showresponse() function definition.
I also tried packaging my extension to get a myextension.crx file after reading this question and I tried opening the file in my browser, but chrome doesn't allow installing the extension from localhost or unknown servers for security reasons I suppose.
My question is how do I make a cross domain XHR in a chrome extension?
Also the response from the get request to the server is actually an html document and I need to filter some text out of the returned html tags. As I am making a query to a php script, can I receive and therefore play around with the html output if I make a get request in javascript?
How do I go about acheiving this?

Resources