- Notifications
You must be signed in to change notification settings - Fork96
A Twitter library in JavaScript.
License
jublo/codebird-js
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
A Twitter library in JavaScript.
Copyright (C) 2010-2018 Jublo Limitedsupport@jublo.net
This program is free software: you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation, either version 3 of the License, or(at your option) any later version.
This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See theGNU General Public License for more details.
You should have received a copy of the GNU General Public Licensealong with this program. If not, seehttp://www.gnu.org/licenses/.
To include Codebird in your code, add its scripts to your markup:
<scripttype="text/javascript"src="codebird.js"></script><scripttype="text/javascript">varcb=newCodebird;cb.setConsumerKey("YOURKEY","YOURSECRET");</script>
You may also use a JavaScript module loader of your choice(such asRequireJS or the one bundled in Node.js)to load Codebird unobtrusively. In Node.js, loading Codebird looks like this:
varCodebird=require("codebird");// or with leading "./", if the codebird.js file is in your main folder:// var Codebird = require("./codebird");varcb=newCodebird();cb.setConsumerKey("YOURKEY","YOURSECRET");
To authenticate your API requests on behalf of a certain Twitter user(following OAuth 1.0a), take a look at these steps:
<scripttype="text/javascript"src="codebird.js"></script><scripttype="text/javascript">varcb=newCodebird;cb.setConsumerKey("YOURKEY","YOURSECRET");</script>
You may either set the OAuth token and secret, if you already have them:
cb.setToken("YOURTOKEN","YOURTOKENSECRET");
Or you authenticate, like this:
// gets a request tokencb.__call("oauth_requestToken",{oauth_callback:"oob"},function(reply,rate,err){if(err){console.log("error response or timeout exceeded"+err.error);}if(reply){if(reply.errors&&reply.errors["415"]){// check your callback URLconsole.log(reply.errors["415"]);return;}// stores the tokencb.setToken(reply.oauth_token,reply.oauth_token_secret);// gets the authorize screen URLcb.__call("oauth_authorize",{},function(auth_url){window.codebird_auth=window.open(auth_url);});}});
$(function(){$('#auth').click(function(e){e.preventDefault();varcb=newCodebird;// ...
Now you need to add a PIN box to your website.After the user enters the PIN, complete the authentication:
cb.__call("oauth_accessToken",{oauth_verifier:document.getElementById("PINFIELD").value},function(reply,rate,err){if(err){console.log("error response or timeout exceeded"+err.error);}if(reply){// store the authenticated token, which may be different from the request token (!)cb.setToken(reply.oauth_token,reply.oauth_token_secret);}// if you need to persist the login after page reload,// consider storing the token in a cookie or HTML5 local storage});
In case you want to log out the current user (to log in a different user withoutcreating a new Codebird object), just call thelogout() method.
cb.logout().then(()=>{// user is now logged out});
Codebird also supports calling the oauth/invalidate_token method directly:
cb.__call("oauth_invalidateToken", { access_key: "1234", access_key_secret: "5678"}).then(() => { // tokens are now reset});Some API methods also support authenticating on a per-application level.This is useful for getting data that are not directly related to a specificTwitter user, but generic to the Twitter ecosystem (such assearch/tweets).
To obtain an app-only bearer token, call the appropriate API:
cb.__call("oauth2_token",{},function(reply,err){varbearer_token;if(err){console.log("error response or timeout exceeded"+err.error);}if(reply){bearer_token=reply.access_token;}});
I strongly recommend that you store the obtained bearer token in your database.There is no need to re-obtain the token with each page load, as it becomes invalidonly when you call theoauth2/invalidate_token method.
If you already have your token, tell Codebird to use it:
cb.setBearerToken("YOURBEARERTOKEN");
In this case, you don't need to set the consumer key and secret.For sending an API request with app-only auth, see the ‘Usage examples’ section.
- Before sending your user off to Twitter, you have to store the request token and its secret, for example in a cookie.
- In the callback URL, extract those values and assign them to the Codebird object.
- Extract the
oauth_verifierfield from the request URI.
In Javascript, try extracting the URL parameter like this:
varcb=newCodebird();varcurrent_url=location.toString();varquery=current_url.match(/\?(.+)$/).split("&");varparameters={};varparameter;cb.setConsumerKey("STUFF","HERE");for(vari=0;i<query.length;i++){parameter=query[i].split("=");if(parameter.length===1){parameter[1]="";}parameters[decodeURIComponent(parameter[0])]=decodeURIComponent(parameter[1]);}// check if oauth_verifier is setif(typeofparameters.oauth_verifier!=="undefined"){// assign stored request token parameters to codebird here// ...cb.setToken(stored_somewhere.oauth_token,stored_somewhere.oauth_token_secret);cb.__call("oauth_accessToken",{oauth_verifier:parameters.oauth_verifier},function(reply,rate,err){if(err){console.log("error response or timeout exceeded"+err.error);}if(reply){cb.setToken(reply.oauth_token,reply.oauth_token_secret);}// if you need to persist the login after page reload,// consider storing the token in a cookie or HTML5 local storage});}
When you have an access token, calling the API is simple:
cb.setToken("YOURTOKEN","YOURTOKENSECRET");// see abovecb.__call("statuses_homeTimeline",{},function(reply,rate,err){console.log(reply);console.log(err);});
Tweeting is as easy as this:
cb.__call("statuses_update",{status:"Whohoo, I just tweeted!"},function(reply,rate,err){// ...});
& sign:
varparams="status="+encodeURIComponent("Fish & chips");cb.__call("statuses_update",params,function(reply,rate,err){// ...});
In most cases, giving all parameters in an array is easier,because no encoding is needed:
varparams={status:"Fish & chips"};cb.__call("statuses_update",params,function(reply,rate,err){// ...});
varparams={screen_name:"jublonet"};cb.__call("users_show",params,function(reply,rate,err){// ...});
varparams={q:"NYC"};cb.__call("search_tweets",params,function(reply){// ...});
Tweet media can be uploaded in a 2-step process, and the media have to bebase64-encoded.First you send each image to Twitter, like this:
varparams={"media_data":"iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAIAAAD8GO2jAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAB+0lEQVR42mP8//8/Ay0BEwONwagFoxZQDljI0PP8x7/Z93/e+PxXmpMpXp5dh4+ZgYHh0bd/clxYnMuINaMtfvRLgp3RVZwVU+rkuz+eRz+//wXVxcrEkKnEceXTX0dRlhoNTmKDaOvzXwHHv6x9+gtN/M9/hpjTX+GmMzAw/P7HMOnOj+ff//35x/Ds+z9iLfjPwPDt7//QE1/Sz319/RNh3PkPf+58+Yup/t7Xf9p8zFKcTMRa4CLGCrFm1v2fSjs+pJ/7uuvl7w+//yO7HRkUq3GEyrCREMk+kqy2IiyH3/xhYGD48uf/rPs/Z93/yczIwM3CiFU9Hw5xnD4ouvTt4Tf0AP37n+HTb+w+UOBmIs2CICm2R9/+EZlqGRkYzIVYSLMgRIYtUYGdSAsMBFgUuJhIy2iMDAwt2pysjAwLHv78RcgnOcrs5BQVHEyMG579Imi6Nh9zrBxZFgixMW624pXnwldYcTAzLjDhZmUit7AzE2K54c7fp8eF1QhWRobFptwmgiwkF3b//jMwMjJ8+P3/zPs/yx/9Wvr412+MgBJlZ1xsyuOOrbAibMHH3/87b32fce/nR2ypnpuFMVGevU6TQ5SdqKKeEVez5cuf/7te/j727s+9L/++/v3PzcyowM1kIcTiLs7Kz8pIfNnOONouGrVg1AIGAJ6gvN4J6V9GAAAAAElFTkSuQmCC");cb.__call("media_upload",params,function(reply,rate,err){// you get a media id back:console.log(reply.media_id_string);// continue upload of 2nd image here, if any (just 1 image works, too!)});
Second, you attach the collected media ids for all images to your calltostatuses/update, like this:
cb.__call("statuses_update",{"media_ids":"12345678901234567890,9876543210987654321""status":"Whohoo, I just tweeted two images!"},function(reply,rate,err){// ...});
Moredocumentation for uploading media is available on the Twitter Developer site.
To send API requests without an access token for a user (app-only auth),add another parameter to your method call, like this:
cb.__call("search_tweets","q=Twitter",function(reply){// ...},true// this parameter required);
Bear in mind that not all API methods support application-only auth.
As you can see from the last example, there is a general way how Twitter’s API methodsmap to Codebird function calls. The general rules are:
For each slash in a Twitter API method, use an underscore in the Codebird function.
Example:
statuses/updatemaps tocb.__call("statuses_update", ...).For each underscore in a Twitter API method, use camelCase in the Codebird function.
Example:
statuses/home_timelinemaps tocb.__call("statuses_homeTimeline", ...).For each parameter template in method, use UPPERCASE in the Codebird function.Also don’t forget to include the parameter in your parameter list.
Examples:
statuses/show/:idmaps tocb.__call("statuses_show_ID", 'id=12345', ...).users/profile_image/:screen_namemaps tocb.__call("users_profileImage_SCREEN_NAME", "screen_name=jublonet", ...).
Never care about which HTTP method (verb) to use when calling a Twitter API.Codebird is intelligent enough to find out on its own.
The HTTP response code that the API gave is included in any return values.You can find it within the return object’shttpstatus property.
Basically, Codebird leaves it up to you to handle Twitter’s rate limit.The library returns the response HTTP status code, so you can detect rate limits.
I suggest you to check if thereply.httpstatus property is400and check with the Twitter API to find out if you are currently beingrate-limited.See theRate Limiting FAQfor more information.
If you allow your callback function to accept a second parameter,you will receive rate-limiting details in this parameter,if the Twitter API responds with rate-limiting HTTP headers.
cb.__call("search_tweets","q=Twitter",function(reply,rate_limit_status){console.log(rate_limit_status);// ...});
Normally, browsers only allow requests being sent to addresses that are onthe same base domain. This is a security feature called the “same-originpolicy.” However, this policy is in your way when you try to access the(remote) Twitter API domain and its methods.
With Codebird, don’t worry about this. We automatically send cross-domainrequests using a secured proxy that sends back the required headers to theuser’s browser.
This CORS proxy is using an encrypted SSL connection.We do not record data sent to or from the Twitter API.Using Codebird’s CORS proxy is subject to the Acceptable use policy.
If your JavaScript environment is not restricted under the same-origin policy(for example in node.js), direct connections to the Twitter API are establishedautomatically, instead of contacting the CORS proxy.
You may also turn off the CORS compatibility manually like this:
cb.setUseProxy(false);
Cross-domain requests work well in any browser except forInternet Explorer 7-9. Codebird cannot send POST requests in these browsers.For IE7-9, Codebird works in limited operation mode:
- Calls to GET methods work fine,
- calling POST methods is impossible,
- Application-only auth does not work.
The source code of the CORS proxy is publicly available. If you want to,set up your own instance on your server. Afterwards, tell Codebird theaddress:
cb.setProxy("https://example.com/codebird-cors-proxy/");
Heads up! Follow the notes in thecodebird-cors-proxy README for details.
By default, each Codebird instance works on its own.
If you need to run requests to the Twitter API for multiple users at once,Codebird supports this automatically. Just create a new object:
varcb1=newCodebird();varcb2=newCodebird();
Please note that your OAuth consumer key and secret is shared withinmultiple Codebird instances, while the OAuth request and access tokens with theirsecrets arenot shared.
When the user returns from the authentication screen, you need to tradethe obtained request token for an access token, using the OAuth verifier.As discussed in the section ‘Usage example,’ you use a call tooauth/access_token to do that.
The API reply to this method call tells you details about the user that just logged in.These details contain theuser ID and thescreen name.
Take a look at the returned data as follows:
{oauth_token:"14648265-rPn8EJwfB**********************",oauth_token_secret:"agvf3L3**************************",user_id:14648265,screen_name:"jublonet",httpstatus:200}
If you need to get more details, such as the user’s latest tweet,you should fetch the complete User Entity. The simplest way to get theuser entity of the currently authenticated user is to use theaccount/verify_credentials API method. In Codebird, it works like this:
cb.__call("account_verifyCredentials",{},function(reply){console.log(reply);});
I suggest to cache the User Entity after obtaining it, as theaccount/verify_credentials method is rate-limited by 15 calls per 15 minutes.
The Twitter REST API utilizes a technique called ‘cursoring’ to paginatelarge result sets. Cursoring separates results into pages of no more than5000 results at a time, and provides a means to move backwards andforwards through these pages.
Here is how you can walk through cursored results with Codebird.
- Get the first result set of a cursored method:
cb.__call("followers_list",{},function(result1){// ...});
- To navigate forth, take the
next_cursor_str:
varnextCursor=result1.next_cursor_str;
- If
nextCursoris not 0, use this cursor to request the next result page:
if(nextCursor>0){cb.__call("followers_list",{cursor:nextCursor},function(result2){// ...});}
To navigate back instead of forth, use the fieldresultX.previous_cursor_strinstead ofnext_cursor_str.
It might make sense to use the cursors in a loop. Watch out, though,not to send more than the allowed number of requests tofollowers/listper rate-limit timeframe, or else you will hit your rate-limit.
Codebird supports xAuth just like every other authentication used at Twitter.Remember that your application needs to be whitelisted to be able to use xAuth.
Here’s an example:
cb.__call("oauth_accessToken",{x_auth_username:"username",x_auth_password:"4h3_p4$$w0rd",x_auth_mode:"client_auth"},function(reply){console.log(reply);// ...});
If everything went fine, you will get an object like this:
{"oauth_token":"14648265-ABLfBFlE*********************************","oauth_token_secret":"9yTBY3pEfj*********************************","user_id":"14648265","screen_name":"jublonet","x_auth_expires":"0","httpstatus":200}
Are you getting a strange error message, an empty error, or status "0"?If the user is enrolled in login verification, the server will return aHTTP 401 error with a custom body (that may be filtered by your browser).
You may check the browser web console for an error message.
When this error occurs, advise the user togenerate a temporary passwordon twitter.com and use that to complete signing in to the application.
Collections are a type of timeline that you control and can be hand curatedand/or programmed using an API.
Pay close attention to the differences in how collections are presented —often they will be decomposed, efficient objects with information about users,Tweets, and timelines grouped, simplified, and stripped of unnecessary repetition.
Never care about the OAuth signing specialities and the JSON POST bodyfor POST and PUT calls to these special APIs. Codebird takes off the work for youand will always send the correct Content-Type automatically.
Find out more about theCollections API in the Twitter API docs.More information on theDirect Messages API and theAccount Activity API is available there as well.
Here’s a sample for adding a Tweet using the Collections API:
cb.__call("collections_entries_curate",{id:"custom-672852634622144512",changes:[{op:"add",tweet_id:"672727928262828032"}]},function(reply,rate){document.body.innerText=JSON.stringify(reply);});
Have you ever heard of thePyramid of Doom?It’s when code progresses more to the right because of excessive nestingthan it progresses from top to bottom.
Because of the asynchronous requests, Codebird will use callbacks that you provide.They are called when the result from the Twitter API has arrived.However, to streamline code, there is a sleeker concept for this: Promises.
There are several popular libraries that support promises.Codebird will auto-detect and use any of the following:
- jQuery Deferred
- Q
- RSVP
- when
Here’s a usage sample for promises:
cb.__call("statuses_update",{status:"Whohoo, I just tweeted!"}).then(function(data){varreply=data.reply,rate=data.rate;// ...},function(err){// ...});
Since the app-only flag is the fourth parameter for__call,you’ll have to provide a callback stub nonetheless even with promises:
cb.__call("search_tweets",{q:"#PHP7"},null,// no callback needed, we have the promisetrue// app-only auth).then(function(data){varreply=data.reply,rate=data.rate;// ...},function(err){// ...});
Tips:
If you provideboth (callback and promise.then),Codebird will first call the callback, then resolve the promise.
If the request fails due to any errors, Codebird will reject the promise.
About
A Twitter library in JavaScript.
Topics
Resources
License
Contributing
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Packages0
Uh oh!
There was an error while loading.Please reload this page.
Contributors13
Uh oh!
There was an error while loading.Please reload this page.