Get a tweet stream client-side without exposing a private auth token, and without any server-side code.
The stream will be provided to you via an ordinary $http promise object.
Twitter has a tight lock on its API. You can't access any API data without a token. However there is a back door, the official Twitter widget which returns HTML.
This module works by scraping the official twitter widget and parsing the result into JSON.
The official twitter widget makes a JSONP call to an API. It does this using a public widget id which allows access to the tweet stream from a single pre-chosen user.
This API call returns a JSON object full of HTML which the widget normally displays in an iframe.
This service pulls that stream, extracts the HTML and reverse engineers it back into a JSON object which can be saved in scope.
Once the tweet stream is in scope you can do what you like with it.
You can find a working plunkr here.
http://plnkr.co/edit/gLkDBn?p=preview
Kudos to Jason Mayes for the idea http://www.jasonmayes.com/projects/twitterApi/
First go here https://twitter.com/settings/widgets/new and create a new widget. Configure the widget to your liking. The data from the widget will be used to compose the response. Inspect the generated widget code and grab the public widget ID. You will need this to configure the service.
You will not need an API key, secret, etc, etc.
Inject "ngTweets" into your app. The module provides a service called tweets. Call tweets.get and pass it your widget ID. You will get back an $http promise object which you can interact with in the usual way.
angular.module('app', ['ngTweets'])
.controller('twitterController', function($scope, tweets) {
tweets.get({
widgetId: '123456'
}).then(function(data) {
$scope.feed = data;
});
});
<body ng-controller="twitterController">
<ul>
<li ng-repeat='tweet in feed.tweets'>
<pre>{{tweet | json }}</pre>
</li>
</ul>
</body>
You will receive an object containing a header, and an array with a maximum of 20 tweets.
{
headers: {
"status": 200,
"xPolling": 30,
"time": 1431449793
},
tweets: [
{
"retweet": false,
"id": "598156558984290304",
"html": "<a href=\"https://twitter.com/kasiakatie\" class=\"PrettyLink profile customisable h-card\" dir=\"ltr\" data-scribe=\"element:mention\">@<b class=\"p-nickname\">kasiakatie</b></a> An unusual choice for breakfast, but we're glad that you enjoyed it :-)",
"text": "@kasiakatie An unusual choice for breakfast, but we're glad that you enjoyed it :-)",
"author": {
"url": "https://twitter.com/higgidy",
"avatar": "https://pbs.twimg.com/profile_images/378800000697698644/d09c29afa453ce0e224266efda526210_normal.jpeg",
"fullName": "Higgidy",
"nickName": "@higgidy"
},
"updated": "53m",
"permalink": "https://twitter.com/higgidy/status/598156558984290304"
},
{
"retweet": false,
"id": "598130095232913408",
"html": "Mmm, good choice <a href=\"https://twitter.com/Mmelulu\" class=\"PrettyLink profile customisable h-card\" dir=\"ltr\" data-scribe=\"element:mention\">@<b class=\"p-nickname\">Mmelulu</b></a>",
"text": "Mmm, good choice @Mmelulu",
"author": {
"url": "https://twitter.com/higgidy",
"avatar": "https://pbs.twimg.com/profile_images/378800000697698644/d09c29afa453ce0e224266efda526210_normal.jpeg",
"fullName": "Higgidy",
"nickName": "@higgidy"
},
"updated": "2h",
"permalink": "https://twitter.com/higgidy/status/598130095232913408"
},
{
"retweet": false,
"id": "598125208021635072",
"html": "During the <a href=\"https://twitter.com/artistshouses\" class=\"PrettyLink profile customisable h-card\" dir=\"ltr\" data-scribe=\"element:mention\">@<b class=\"p-nickname\">artistshouses</b></a> you can wander into random people's houses (including Abby & Cedar's) and not get told off <a href=\"http://t.co/mSA5CV480n\" class=\"PrettyLink link media customisable\" data-pre-embedded=\"true\" dir=\"ltr\" data-scribe=\"\">pic.twitter.com/mSA5CV480n</a>",
"text": "During the @artistshouses you can wander into random people's houses (including Abby & Cedar's) and not get told off pic.twitter.com/mSA5CV480n",
"author": {
"url": "https://twitter.com/higgidy",
"avatar": "https://pbs.twimg.com/profile_images/378800000697698644/d09c29afa453ce0e224266efda526210_normal.jpeg",
"fullName": "Higgidy",
"nickName": "@higgidy"
},
"updated": "2h",
"permalink": "https://twitter.com/higgidy/status/598125208021635072"
}
]
}
The header object contains information about any errors that occurred upstream. The header status would normally be 200. Anything else is an error.
Downstream errors are currently not handled. Please feel free to submit a patch for this.
Please feel free to contribute by forking this repository and submitting a pull request. Contributors will be credited in this Readme.
I'm an Angular developer and trainer working out of Brighton, England. You can find Angular lessons on my website here http://www.nicholasjohnson.com
IE9+ only please. It should work everywhere Angular 1.3.1 works.
Because this service works by scraping HTML, it will fail if the HTML changes. This could happen at any time without warning. Caution is advised.
This plugin is a dirty low down (albeit functional) hack. My assumption is that this hack is likely to remain available as long as older browsers require JSONP to access the API. However I can make no guarantees on this. This is not an official twitter API, there is no uptime guarantee, Twitter can turn it off at any time.
Caution is advised. Use at your discretion. I take no responsibility for any problems of any kind you may encounter, technical, legal, spiritual, military, etc.
MIT license, use it as you see fit. I'm not going to sue you.