This question already has an answer here:
After successful tweet, execute the callback + Twitter
(1 answer)
Closed 4 years ago.
I am posting messgae to twiter via link:
http://twitter.com/intent/tweet?source=webclient&text=Hello
I am interested in if it is possible to be redirected to some url after posting message? For example Facebook has "redirect_uri" parameter added to the URL. User is redirected to this URL after the meesage is posted on the wall.
You can use events binding for Web Intents to redirect to a url after tweeting.
window.twttr = (function (d,s,id) {
var t, js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) return; js=d.createElement(s); js.id=id;
js.src="https://platform.twitter.com/widgets.js"; fjs.parentNode.insertBefore(js, fjs);
return window.twttr || (t = { _e: [], ready: function(f){ t._e.push(f) } });
}(document, "script", "twitter-wjs"));
twttr.ready(function (twttr) {
twttr.events.bind('tweet', function (event) { //redirect to your url } );
});
Following links might help :
https://dev.twitter.com/docs/intents/events#events
https://dev.twitter.com/discussions/671
According to the documentation, the tweet web intent does not have a parameter that allows the user to return to your website after the tweet is posted.
Most websites that I've seen present the web intent in a popup instead of sending the user away from their site.
Related
Is there a way to close a Twitter tab/window after a successful tweet on mobile? I need it to close a) to go back to my site b) to record the callback
When I use the following it works perfectly on a desktop device, the Twitter window closes when tweet is sent, but on mobile it does not.
I will add that I do a similar thing for Facebook and it works perfectly and closes itself after a successful post.
Here's what I'm using:
Tweet
// twitter set up
window.twttr = (function (d,s,id) {
var t, js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) return; js=d.createElement(s); js.id=id;
js.src="https://platform.twitter.com/widgets.js"; fjs.parentNode.insertBefore(js, fjs);
return window.twttr || (t = { _e: [], ready: function(f){ t._e.push(f) } });
}(document, "script", "twitter-wjs"));
// twitter callback
twttr.ready(function (twttr) {
twttr.events.bind('tweet', function (event) {
console.log("Tweet successful");
});
});
I've found an answer to this so posting in case anyone has same problem.
The answer is you can't (as of 24th March 2015), it's a few different forces at work preventing it apparently.
More information here from Twitter
I'm fetching google contacts in a webapp using the Google JavaScript API and I'd like to retrieve their pictures.
I'm doing something like this (heavily simplified):
var token; // let's admit this is available already
function getPhotoUrl(entry, cb) {
var link = entry.link.filter(function(link) {
return link.type.indexOf("image") === 0;
}).shift();
if (!link)
return cb(null);
var request = new XMLHttpRequest();
request.open("GET", link.href + "?v=3.0&access_token=" + token, true);
request.responseType = "blob";
request.onload = cb;
request.send();
}
function onContactsLoad(responseText) {
var data = JSON.parse(responseText);
(data.feed.entry || []).forEach(function(entry) {
getPhotoUrl(e, function(a, b, c) {
console.log("pic", a, b, c);
});
});
}
But I'm getting this error both in Chrome and Firefox:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://www.google.com/m8/feeds/photos/media/<user_email>/<some_contact_id>?v=3.0&access_token=<obfuscated>. This can be fixed by moving the resource to the same domain or enabling CORS.
When looking at the response headers from the feeds/photos endpoint, I can see that Access-Control-Allow-Origin: * is not sent, hence the CORS error I get.
Note that Access-Control-Allow-Origin: * is sent when reaching the feeds/contacts endpoint, hence allowing cross-domain requests.
Is this a bug, or did I miss something from their docs?
Assuming you only need the "profile picture", try actually moving the request for that image directly into HTML, by setting a full URL as the src element of an <img> tag (with a ?access_token=<youknowit> at the end).
E.g. using Angular.js
<img ng-src="{{contact.link[1].href + tokenForImages}}" alt="photo" />
With regard to CORS in general, there seem to be quite a few places where accessing the API from JS is not working as expected.
Hope this helps.
Not able to comment yet, hence this answer…
Obviously you have already set up the proper client ID and JavaScript origins in the Google developers console.
It seems that the domain shared contacts API does not work as advertised and only abides by its CORS promise when you request JSONP data (your code indicates that you got your entry data using JSON). For JSON format, the API sets the access-control-allow-origin to * instead of the JavaScript origins you list for your project.
But as of today (2015-06-16), if you try to issue a GET, POST… with a different data type (e.g. atom/xml), the Google API will not set the access-control-allow-origin at all, hence your browser will deny your request to access the data (error 405).
This is clearly a bug, that prevents any programmatic use of the shared contacts API but for simple listing of entries: one can no longer create, update, delete entries nor access photos.
Please correct me if I'm mistaken (I wish I am); please comment or edit if you know the best way to file this bug with Google.
Note, for the sake of completeness, here's the code skeleton I use to access contacts (requires jQuery).
<button id="authorize-button" style="visibility: hidden">Authorize</button>
<script type="text/javascript">
var clientId = 'TAKE-THIS-FROM-CONSOLE.apps.googleusercontent.com',
apiKey = 'TAKE-THAT-FROM-GOOGLE-DEVELOPPERS-CONSOLE',
scopes = 'https://www.google.com/m8/feeds';
// Use a button to handle authentication the first time.
function handleClientLoad () {
gapi.client.setApiKey ( apiKey );
window.setTimeout ( checkAuth, 1 );
}
function checkAuth() {
gapi.auth.authorize({client_id: clientId, scope: scopes, immediate: true}, handleAuthResult);
}
function handleAuthResult ( authResult ) {
var authorizeButton = document.getElementById ( 'authorize-button' );
if ( authResult && !authResult.error ) {
authorizeButton.style.visibility = 'hidden';
var cif = {
method: 'GET',
url: 'https://www.google.com/m8/feeds/contacts/mydomain.com/full/',
data: {
"access_token": authResult.access_token,
"alt": "json",
"max-results": "10"
},
headers: {
"Gdata-Version": "3.0"
},
xhrFields: {
withCredentials: true
},
dataType: "jsonp"
};
$.ajax ( cif ).done ( function ( result ) {
$ ( '#gcontacts' ).html ( JSON.stringify ( result, null, 3 ) );
} );
} else {
authorizeButton.style.visibility = '';
authorizeButton.onclick = handleAuthClick;
}
}
function handleAuthClick ( event ) {
gapi.auth.authorize ( { client_id: clientId, scope: scopes, immediate: false }, handleAuthResult );
return false;
}
</script>
<script src="https://apis.google.com/js/client.js?onload=handleClientLoad"></script>
<pre id="gcontacts"></pre>
If you replace cif.data.alt by atom and/or cif.dataType by xml, you get the infamous error 405.
ps: cif is of course related to ajax ;-)
When I use the built-in Google+ sign-in button, everything works as expected. The OAuth call to Google is made in the popup, the user accepts or cancels, then the callback is called.
When I try to customize my button using the example gapi.signin.render method, the Google call is made but the callback is called immediately.
I am a server-side developer trying to provide a POC for the front-end developers. I only know enough Javascript to be dangerous. Can someone tell me why the gapi.signin.render method is making an asynchronous call to the authorization, which makes the callback get called before the user has clicked anything in the popup? In the alternative, please help me correct the code in the 2nd example below to effect the callback being called only after the user clicks Accept/Cancel in the OAuth Google window. In the second alternative, please tell me how I can change the text of the built-in Google+ sign-in button.
The code that works (built-in, non-customizable Google+ sign-in button):
<SCRIPT TYPE="text/javascript">
/**
* Asynchronously load the Google Javascript file.
*/
(
function() {
var po = document.createElement( 'script' );
po.type = 'text/javascript';
po.async = true;
po.src = 'https://apis.google.com/js/client:plusone.js?onload=googleLoginCallback';
var s = document.getElementsByTagName('script')[ 0 ];
s.parentNode.insertBefore( po, s );
}
)();
function googleLoginCallback( authResult ) {
alert( "googleLoginCallback(authResult): Inside." );
}
</SCRIPT>
<DIV ID="googleLoginButton" CLASS="show">
<DIV
CLASS="g-signin"
data-accesstype="online"
data-approvalprompt="auto"
data-callback="googleLoginCallback"
data-clientid="[Google Client Id].apps.googleusercontent.com"
data-cookiepolicy="single_host_origin"
data-height="tall"
data-requestvisibleactions="http://schemas.google.com/AddActivity"
data-scope="https://www.googleapis.com/auth/userinfo.email"
data-theme="dark"
data-width="standard">
</DIV>
</DIV>
The gapi.signin.render code that does not work:
<SCRIPT TYPE="text/javascript">
/**
* Asynchronously load the Google Javascript file.
*/
(
function() {
var po = document.createElement( 'script' );
po.type = 'text/javascript';
po.async = true;
po.src = 'https://apis.google.com/js/client:plusone.js?onload=myGoogleButtonRender';
var s = document.getElementsByTagName('script')[ 0 ];
s.parentNode.insertBefore( po, s );
}
)();
function myGoogleButtonRender( authResult ) {
gapi.signin.render( 'myGoogleButton', {
'accesstype': 'online',
'approvalprompt': 'auto',
'callback': 'googleLoginCallback',
'clientid': '[Google Client Id].apps.googleusercontent.com',
'cookiepolicy': 'single_host_origin',
'height': 'tall',
'requestvisibleactions': 'http://schemas.google.com/AddActivity',
'scope': 'https://www.googleapis.com/auth/userinfo.email',
'theme': 'dark',
'width': 'standard'
});
}
function googleLoginCallback( authResult ) {
alert( "googleLoginCallback(authResult): Inside." );
}
</SCRIPT>
<button id="myGoogleButton">Register with Google+</button>
I figured out why the code was not working for a custom button. I had the button defined within a Struts 2 form. Apparently, in lieu of the traditional Chain of Responsibility pattern, where the click event is handled by one processor, both the Struts form and the Google API were processing the click. So, what I thought was a failure of the Google gapi.signin.render call making an asynchronous call to the callback, it was the Struts form trying to submit.
To fix it, you can:
Move the button outside of the Struts form (not very elegant)
Add "onclick="return false;" clause to the button
<button id="myGoogleButton" onclick="return false;">Register with Google+</button>
Wrap the "button" in a DIV like:
<DIV ID="myGoogleButton">
<SPAN CLASS="zocial googleplus">Register with Google+</SPAN>
</DIV>
I hope this fixes someone else's problem. I spent 9 days trying to figure this out.
When I press the login button I get the facebook page where I have to give permission to use my facebook account.
After I give permission, it redirects to https://www.facebook.com/dialog/permissions.request and a blank page is shown. On Android the "window.FB.login" callback is called (see code below) where I can get the info and redirect the user but on Windows Phone it only shows that blank page. When I go to my facebook page, my site is registered in the app list. So the registration did work correctly.
This error has been caused due to unsafe loading of facebook js file.
For integrating Facebook app in your application you have to follow the steps instructed in Facebook app documentation.
var fbApi = {
init: function () {
$.getScript(document.location.protocol + '//connect.facebook.net/en_US/all.js', function () {
if (window.FB) {
window.FB.init({
appId: MY_APP_ID,
status: true,
cookie: true,
xfbml: false,
oauth: true,
channelUrl: 'http://www.yourdomain.com/channel.html'
});
}
});
},
login: function () {
/// <summary>
/// Login facebook button clicked
/// </summary>
log("login facebook button clicked");
if (window.FB) {
//Windows phone does not enter this method, Android and Iphone do
window.FB.login(function (response) {
if (response.status) {
log('it means the user has allowed to communicate with facebook');
fbAccessToken = response.authResponse.accessToken;
window.FB.api('/me', function (response) {
//get information of the facebook user.
loginService.subscribeSocialUser(response.id, response.first_name, response.last_name, fbAccessToken, "", "FaceBook", fbSucces, fbFail);
});
} else {
log('User cancelled login or did not fully authorize.');
}
},
{ scope: 'email'
});
}
}
};
channel URL is added so as to resolve any cross browser issues.
It should point to an html file which refers to the js as follows:
<script src="//connect.facebook.net/en_US/all.js"></script>
If once an error has been hit while initializing Facebook.js, you will not be able to login successfully.
You can load java script either synchronously or asynchronously.
(function(d, debug){
var js, id = 'facebook-jssdk', ref = d.getElementsByTagName('script')[0];
if (d.getElementById(id)) {return;}
js = d.createElement('script'); js.id = id; js.async = true;
js.src = "//connect.facebook.net/en_US/all" + (debug ? "/debug" : "") + ".js";
ref.parentNode.insertBefore(js, ref);
}(document, /*debug*/ false));
I'm trying to create a facebook service for Angular so I can more easily test code that needs to use the Facebook JS SDK and Graph API for stuff.
Here's what I have so far:
app.factory('facebook', function() {
return FB;
});
window.fbAsyncInit = function () {
FB.init({
appId: 'SOME_APP_ID_HERE', // App ID
status: true, // check login status
cookie: true, // enable cookies to allow the server to access the session
xfbml: true, // parse XFBML
oauth: true
});
};
// Load the SDK Asynchronously
(function (d) {
var js, id = 'facebook-jssdk', ref = d.getElementsByTagName('script')[0];
if (d.getElementById(id)) { return; }
js = d.createElement('script'); js.id = id; js.async = true;
js.src = "//connect.facebook.net/en_US/all.js";
ref.parentNode.insertBefore(js, ref);
})(document);
Now, I know that the actual Facebook SDK part is working... but in my controller the reference is always null.
in my controller I just have something like this:
function FooCtrl($scope, facebook) {
facebook.getLoginStatus(function(response) {
if (response.status === 'connected') {
var uid = response.authResponse.userID;
var accessToken = response.authResponse.accessToken;
// do something
} else if (response.status === 'not_authorized') {
// the user is logged in to Facebook,
// but has not authenticated your app
} else {
// the user isn't logged in to Facebook.
}
});
}
Angular then gripes that it can't find a facebookProvider. Any ideas on how I can accomplish this?
Enclose your factory function with array brackets like below
app.factory('facebook', [function() {
return FB;
}]);
API docs are not clear enough. Point of having array brackets is that you can specify dependencies. It will be injected on creation of your service with AUTO.$inject. But since you don't have dependencies it will skip that task :)
Anyway, if you need dependencies you can request them like this
app.factory('facebook', ["$log", function($someCrazyLoggerService){
$someCrazyLoggerService.log("I'm Auto Injected crazy Logger");
}]);
you should take a look at this Facebook module I wrote.
First use the FacebookProvider on your app config call, something as FacebookProvider.init('yourFacebookAppIdHere');, you could also configure other settings too, and then on your controllers use the Facebook service and register to events and call methods asyncrhonously ;)
https://github.com/ciul/angularjs-facebook