I use twitter sometime, I even tweet sometimes. But I had never tried to put a time-line on a page before (believe it or not). Reading on the Internet I realized that a change made in ca. July 2013, to API v1.1, had made a mark with people embedding twitter on sites. There is no need in repeating what was done, but it got more difficult to do what you want to do (eg. OAUTH ). So I wanted to find out what options there was for this. I found the four options below.
1) Twitter widget
The "easy" way to get a twitter feed on your page; use the twitter widget from Twitter
(called Embedded Timelines).
"They load fast, scale with your traffic, and update in real-time".
This is a pure JavaScript-solution
from Twitter.
Pros: easy, scales.
Cons: bloated, ugly, can't style it anyway you'd want, not as stable as you'd think...
- Sign in to twitter.com, and visit the widgets section of your settings page.
- Chose to "Create new" widget. Customize and click "Save".
- Go back to the Widget, chose Edit. Copy the HTML-code it gives you, paste to your site.
- <a class="twitter-timeline" href="https://twitter.com/twitterapi" data-widget-id="YOUR-WIDGET-ID-HERE">Tweets by @twitterapi</a>
- <script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){
- js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}
- }(document,"script","twitter-wjs");</script>
- Done! You should now see something like below, a working Twitter timeline.
2) Twitter widget over-ride
One of the people who got annoyed at the change to API v1.1 was Jason Mayes. He wrote a small work-around,
that uses the "over bloated" client from Twitter and "that cuts out all the nonsense (and non semantic markup), and returns to you your raw tweet text so you can do with it as you please -
See more at: http://jasonmayes.com/projects/twitterApi/#sthash.u0aj8WyH.dpuf.
I could not agree more, I don't understand how a company like Twitter could come up with a really crappy (well, layout wise) client like that...
Pros: quite easy, scales, no bloated client.
Cons: only thing I can think of is Twitter changing their API and this stops working...
- Perform the steps above, i.e. create a widget from Twitter. Make a note of the "data-widget-id" you have, it looks something like this example: '345170787868762112' (but don't use this one! :) ).
- Download the latest build (v10 currently). Extract the zip-file, open example.html-file.
- Scroll down to where the examples start. Pick one of these. The file contains comments, read these for more info. Include the twitterFetcher_v10_min.js-file!
- // ##### Simple example 1 #####
- // A simple example to get my latest tweet and write to a HTML element with
- // id "tweets". Also automatically hyperlinks URLS and user mentions and
- // hashtags.
- twitterFetcher.fetch('345170787868762112', 'example1', 1, true);
- // ##### Simple example 2 #####
- // A simple example to get my latest 5 of my favourite tweets and write to a HTML
- // element with id "talk". Also automatically hyperlinks URLS and user mentions and
- // hashtags but does not display time of post.
- twitterFetcher.fetch('347099293930377217', 'example2', 5, true, true, false);
- // ##### Advanced example #####
- // An advance example to get latest 5 posts using hashtag #API and write to a
- // HTML element with id "tweets2" without showing user details and using a
- // custom format to display the date/time of the post, and does not show
- // retweets.
- twitterFetcher.fetch('345690956013633536', 'example3', 3, true, false, true, dateFormatter, false);
-
I picked the "simple example 1" for the example below:
- Done! You have now a way to make your time-line to look anyway you want.
3) Server-side
This seems to be the "correct" way if you look at how Twitter "promotes" this. You have to use OAuth, and because of its security restrictions
in JavaScript, server-side (proxy) is the way to go...unless you create a read-only client etc. (More on that below)
Since I like .Net, I have used ASP.Net/C#, but there are plenty of example in both
Ruby and PHP if you google.
Even Twitter has their own libraries to help you with this. Need
more convincing to use server-side? ;-)
NOTE I have not tried any of the libraries/frameworks!
Even for C# there are choices, but the
most fun has to be to write it all yourself, right? So this is authenticating using OAuth API v1.1.
Pros: quite easy, no bloated client, control.
Cons: does not scale as well (that is up to you), needs server-side
- Set up an Application in Twitter Dev Center. Log in with any Twitter-account you have, it doesn't have to be the account you want to show a timeline for. Select "Create new Application".
- Choose a name and description. Website can be anything you like, or your page. Callback URL can be empty, not used for this example.
- Agree to terms and enter captcha. You should now see the "Details"-tab of your Application. Access level should be "Read-Only" (unless you are sure about what you are doing). Now click "Create my access token" in the bottom. There seems to be a small "feature" here, you might need to refresh the page to see the "Access token string".
- Copy the "OAuth settings".Consumer key, "OAuth settings".Consumer secret, "Your access token".Access token and "Your access token".Access token secret. One application can be used with several timelines/twitter-accounts. There are some access rate limits though.
-
Now you can use the library of your choice (see above) for the server-side stuff. There are a lot of examples on the Internet.
However I chose to write it "myself". Well, I have cheated a bit, why re-invent the wheel? ;-)
Stackoverflow
has a really nice example of this, the code is based on that code. It has even been made into a great wrapper!
- public class TwitterClient
- {
- private string oAuthUrl = "https://api.twitter.com/oauth2/token";
- private string screenname = "rolandegedi";
- public JArray GetTimeLine()
- {
- string twitterConsumerKey = ConfigurationManager.AppSettings["twitterConsumerKey"];
- string twitterConsumerSecret = ConfigurationManager.AppSettings["twitterConsumerSecret"];
- // Do the Authenticate
- string authHeaderFormat = "Basic {0}";
- var authHeader = string.Format(authHeaderFormat,
- Convert.ToBase64String(Encoding.UTF8.GetBytes(Uri.EscapeDataString(twitterConsumerKey) + ":" +
- Uri.EscapeDataString((twitterConsumerSecret)))
- ));
- var postBody = "grant_type=client_credentials";
- HttpWebRequest authRequest = (HttpWebRequest)WebRequest.Create(oAuthUrl);
- authRequest.Headers.Add("Authorization", authHeader);
- authRequest.Method = "POST";
- authRequest.ContentType = "application/x-www-form-urlencoded;charset=UTF-8";
- authRequest.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
- using (Stream stream = authRequest.GetRequestStream())
- {
- byte[] content = ASCIIEncoding.ASCII.GetBytes(postBody);
- stream.Write(content, 0, content.Length);
- }
- authRequest.Headers.Add("Accept-Encoding", "gzip");
- WebResponse authResponse = authRequest.GetResponse();
- // deserialize into an object
- string rawJsonResponse = string.Empty;
- using (authResponse)
- {
- using (var reader = new StreamReader(authResponse.GetResponseStream()))
- {
- rawJsonResponse = reader.ReadToEnd();
- }
- }
- JObject root = JObject.Parse(rawJsonResponse);
- string access_token = root.Value<string>("access_token");
- string token_type = root.Value<string>("token_type");
- // Do the timeline
- string timelineFormat = "https://api.twitter.com/1.1/statuses/user_timeline.json?screen_name={0}&include_rts=1&exclude_replies=1&count=5";
- var timelineUrl = string.Format(timelineFormat, screenname);
- HttpWebRequest timeLineRequest = (HttpWebRequest)WebRequest.Create(timelineUrl);
- var timelineHeaderFormat = "{0} {1}";
- timeLineRequest.Headers.Add("Authorization", string.Format(timelineHeaderFormat, token_type, access_token));
- timeLineRequest.Method = "Get";
- WebResponse timeLineResponse = timeLineRequest.GetResponse();
- string timeLineJson = string.Empty;
- using (timeLineResponse)
- {
- using (var reader = new StreamReader(timeLineResponse.GetResponseStream()))
- {
- timeLineJson = reader.ReadToEnd();
- }
- }
- JArray retTimeLineJson = JArray.Parse(timeLineJson);
- return retTimeLineJson;
- }
- }
-
Now you need to make use of the client also, e.g. like so (note the super-quick proof-of-concept code :) ):
- TwitterClient cli = new TwitterClient();
- JArray tweetsJson = cli.GetTimeLine();
- List<string> theList = new List<string>();
- for (int x = 0; x < tweetsJson.Count(); x++)
- {
- JObject entity = JObject.Parse(tweetsJson[x]["entities"].ToString());
- theList.Add("Text:" + tweetsJson[x]["text"].ToString() + " date:" + tweetsJson[x]["created_at"].ToString());
- }
- string wow = string.Empty;
- theList.ForEach(lst => wow += lst + "<br />");
- lblOut.Text = wow;
4) Pure JavaScript
Hm, didn't we do this in "2)" above? Yes, but without (our own) OAuth, the "correct" way to do it. Note that this is not a recommended way
of solving things since all your keys are visible in JavaScript. However, if you use a read-only client the impact should be small...I guess.
Codebird is an example of a Twitter-library built in JavaScript. They also use a proxy server
for the CORS issue.
You can also use Yahoo Query Language (YQL) to make server side requests to the Twitter API.
So basically this is as number 3) above, I guess. Only you don't need to write/host your own proxy.
I did not go deeper than this, so I haven't tried this out even if it sound very cool. Here are three pages that claim to have working
examples (my quick tests couldn't confirm this, but I might have done something wrong): Code Project,
Steve Zeidner and
Derek Gathright.
Conclusion
For me, the choice is between "2) Twitter widget over-ride" and "3) Server-side". The requirements would give which of these two to chose. For this site I used a custom version of 2), see the bottom of the start page. "4) Pure JavaScript" is very intriguing, but the security issues and the lack of working examples makes me back-away a bit. (sounds like a challenge! ;) )