
{"id":812,"date":"2011-08-06T06:33:22","date_gmt":"2011-08-06T06:33:22","guid":{"rendered":"http:\/\/opendna.com\/blog\/?p=812"},"modified":"2022-11-08T12:57:45","modified_gmt":"2022-11-08T12:57:45","slug":"host-your-own-real-time-twitter-wall","status":"publish","type":"post","link":"https:\/\/opendna.com\/blog\/2011\/08\/06\/host-your-own-real-time-twitter-wall\/","title":{"rendered":"Host your own real-time Twitter wall"},"content":{"rendered":"<blockquote><p>This article describes the use of a simple AJAX-powered webpage to display a (near) real-time feed from Twitter. If you found this page by following a link to a specific hash tag (i.e. <a rel=\"tag\" class=\"hashtag u-tag u-category\" href=\"https:\/\/opendna.com\/blog\/tag\/jan25\/\">#Jan25<\/a> for the Egyptian Revolution), it is likely that the page was removed after the tag fell into disuse.<\/p><\/blockquote>\n<p><strong>Short Title: <a rel=\"tag\" class=\"hashtag u-tag u-category\" href=\"https:\/\/opendna.com\/blog\/tag\/bloxtalk\/\">#bloxtalk<\/a> project<\/strong><\/p>\n<blockquote><p>Examples: one page like <a href=\"http:\/\/opendna.com\/bloxtalk\/sotu.html\">#SOTU<\/a>, or multiple pages like <a href=\"http:\/\/opendna.com\/bloxtalk\/egypt\/\">#egypt<\/a> and <a href=\"http:\/\/opendna.com\/bloxtalk\/algeria\/\">#algeria<\/a>, or mixed with other elements, like <a href=\"http:\/\/opendna.com\/bloxtalk\/bloxtalk.html\">#bloxtalk<\/a><\/p><\/blockquote>\n<p>Inspired by comments in <a href=\"http:\/\/www.dailykos.com\/story\/2011\/1\/25\/938747\/-Keith-OlbermannLive-Tweeting-The-SOTU-(UPDATED)\">Diogenes2008&#8217;s diary<\/a> (Jan 25 2011), I rolled out a simple ajax-powered live feed of the <a rel=\"tag\" class=\"hashtag u-tag u-category\" href=\"https:\/\/opendna.com\/blog\/tag\/fok\/\">#FOK<\/a> twitter hash tag. Having kinda botched the first version, I gave it some more thought and came out with some innovations to promote real-time, cross platform communication for web events (live blogs, tweetathons, etc). It&#8217;s off-the-shelf javascript with vanilla html, blended together to put conversations from multiple platforms on the same page.<\/p>\n<p>This is an easy how-to guide, offered in the hopes that future live blog events can be made more dynamic and live tweet events more accessible to those unfamiliar with twitter.<\/p>\n<p><strong>Contents<\/strong><\/p>\n<ol>\n<li>Twitter is&#8230;<\/li>\n<li>Why would you do this?<\/li>\n<li>Requirements<\/li>\n<li>Examples in use<\/li>\n<li>The code<\/li>\n<li>Limitations &amp; lessons learned<\/li>\n<li>Hax &amp; back-channels<\/li>\n<\/ol>\n<p><em>Originally published 26 January 2011, to DailyKos as &#8220;<a title=\"#bloxtalk: roll your own twitter+IRC wall\" href=\"http:\/\/www.dailykos.com\/story\/2011\/01\/26\/939072\/-#bloxtalk:-roll-your-own-twitter+IRC-wall?via=blog_664768\" target=\"_blank\" rel=\"noopener\">#bloxtalk: roll your own twitter+IRC wall<\/a>&#8220;<\/em><\/p>\n<p><strong>Twitter is&#8230;<\/strong><br \/>\n&#8230;a micro-blogging platform which makes it exceptionally easy to publish <a href=\"http:\/\/latimesblogs.latimes.com\/technology\/2009\/05\/invented-text-messaging.html\">140 characters<\/a>-messages from a computer or cell phone. You may not use twitter, but the site is the 10th ranked in the world for traffic, 9th ranked in the US and accounts for a little over 0.3% of global page views (<a href=\"http:\/\/www.alexa.com\/siteinfo\/twitter.com\">Alexa:Twitter<\/a>). Twitter can be to real-time public conversations (see &#8220;<a href=\"http:\/\/www.dailykos.com\/story\/2011\/1\/25\/938747\/-Keith-OlbermannLive-Tweeting-The-SOTU-(UPDATED)\">Keith Olbermann &#8211; Live-Tweeting The SOTU<\/a>&#8220;) as facebook is to reconnecting with <a href=\"http:\/\/www.robertburns.org\/works\/236.shtml\">acquaintances forgot<\/a> (but <a href=\"http:\/\/www.youtube.com\/watch?v=PN2HAroA12w\">it&#8217;s usually not<\/a>). Anyway, a great deal has written about the twitter sphere <a href=\"http:\/\/www.dailykos.com\/search?offset=0&amp;old_count=30&amp;string=tag%3Dtwitter&amp;type=diary&amp;sortby=relevance&amp;search=Search&amp;count=30&amp;wayback=262080&amp;wayfront=0\">on DailyKos<\/a> and <a href=\"http:\/\/www.google.com\/insights\/search\/?hl=en-US#q=twitter&amp;gprop=news&amp;cmpt=q\">elsewhere<\/a>, so back to the subject at hand:<\/p>\n<p><strong>Why would you do this?<\/strong><br \/>\nPersonally, I find twitter&#8217;s native tools a little annoying in that they require that you refresh frequently. <a href=\"http:\/\/search.twitter.com\/\">Twitter search<\/a>, for <a href=\"http:\/\/search.twitter.com\/search?q=twitter\">example<\/a>, updates to tell you how many new messages there are but doesn&#8217;t load them on the fly. To my eyes, it&#8217;s a bit like pre-Ajax days of comments at DailyKos (<a href=\"http:\/\/www.dailykos.com\/user\/ct\">ct<\/a> be praised). There are a number of desktop (and smart phone) client applications but if I&#8217;m in a browser, I would rather stay in a browser. I don&#8217;t entirely trust third-party developers as even the most reputable have been caught out on security but, more importantly, even they usually require a higher commitment to participation than (I feel) should be necessary. That&#8217;s where this hack comes in.<\/p>\n<p>It&#8217;s based around a simple javascript which can be loaded in (<a href=\"http:\/\/en.wikipedia.org\/wiki\/Lynx_%28web_browser%29\">almost<\/a>) any web browser page without installing extra software or browser plugins. Can be installed almost anywhere, as it doesn&#8217;t require server-side programming (you can even load it into your browser from your desktop). With this, you can host a twitter stream in a way that anyone can read it, without knowing their way around twitter.<\/p>\n<p>So it&#8217;s fast, convenient, easy but really, <strong>it&#8217;s about communicating in the back channel<\/strong>. Any time a community gets as big as DailyKos (nevermind Twitter), it&#8217;s important to find quiet corners for like-minded people to <span style=\"text-decoration: line-through;\">conspire<\/span> ways to promote their position. I think that these approaches could let us <em>watch the room while talking to our friends<\/em>.<\/p>\n<p><strong>Requirements<\/strong><br \/>\nSoftware: a modern web browser and a text editor (MS Notepad&#8217;s fine)<br \/>\nServer: host plain html files, but you can load it privately from your own computer.<br \/>\nSkills required: (a) a little HTML knowledge; (b) an identifiable twitter feed; and for public use, (d) the ability to upload HTML files.<\/p>\n<p><strong>Examples in use<\/strong><\/p>\n<ol>\n<li><a href=\"http:\/\/opendna.com\/fok\/\">http:\/\/opendna.com\/fok\/<\/a> loads tweets with the <a rel=\"tag\" class=\"hashtag u-tag u-category\" href=\"https:\/\/opendna.com\/blog\/tag\/fok\/\">#FOK<\/a> hashtag. (FOK=&#8221;Friends of Keith&#8221; Olbermann)<\/li>\n<li><a href=\"http:\/\/opendna.com\/openmedia\/twitter.html\">http:\/\/opendna.com\/openmedia\/twitter&#8230;<\/a> loads tweets with the <a rel=\"tag\" class=\"hashtag u-tag u-category\" href=\"https:\/\/opendna.com\/blog\/tag\/openmedia\/\">#openmedia<\/a> tag, related to the Canadian Internet activist group <a href=\"http:\/\/openmedia.ca\/\">OpenMedia.ca<\/a>.<\/li>\n<li><a href=\"http:\/\/opendna.com\/bloxtalk\/dkos.html\">This<\/a> shows the <a rel=\"tag\" class=\"hashtag u-tag u-category\" href=\"https:\/\/opendna.com\/blog\/tag\/dkos\/\">#dkos<\/a> tag and <a href=\"http:\/\/opendna.com\/bloxtalk\/sotu.html\">this<\/a> shows the <a rel=\"tag\" class=\"hashtag u-tag u-category\" href=\"https:\/\/opendna.com\/blog\/tag\/sotu\/\">#sotu<\/a> tag.<\/li>\n<\/ol>\n<p>&#8220;Great. A new tab for every hash tag.&#8221; Yeah, I know. That&#8217;s not ideal either, but you can load several pages in one window with frames or iframes. <a href=\"http:\/\/opendna.com\/bloxtalk\/homeframe.html\">This<\/a> frameset, for example, loads the DailyKos home page and the <a rel=\"tag\" class=\"hashtag u-tag u-category\" href=\"https:\/\/opendna.com\/blog\/tag\/dkos\/\">#dkos<\/a> page side-by-side. You could&#8230; I don&#8217;t know, have the <a rel=\"tag\" class=\"hashtag u-tag u-category\" href=\"https:\/\/opendna.com\/blog\/tag\/sotu\/\">#SOTU<\/a> feed and DailyKos liveblog comments at the same time? (If you&#8217;ve got the screen real estate, of course).<\/p>\n<p><a href=\"http:\/\/opendna.com\/bloxtalk\/sotu.html\" target=\"_blank\" rel=\"noopener\"><img decoding=\"async\" src=\"http:\/\/i100.photobucket.com\/albums\/m35\/opendna\/sotu.jpg\" alt=\"\" height=\"400\" border=\"0\" \/><\/a><br \/>\n<strong>The code<\/strong><br \/>\nMy original source is the <a href=\"http:\/\/www.taranfx.com\/live-twitter-ajax-script\">LIVE Twitter AJAX Script<\/a> from <a href=\"http:\/\/twitter.com\/taranfx\">@taranfx<\/a> (some directions there), but you&#8217;re welcome to grap the source of any of the pages in the previous section or download them all <a href=\"http:\/\/opendna.com\/bloxtalk\">here<\/a> (&#8220;Save as&#8221;).<\/p>\n<p><strong><em>Search Filters<\/em><\/strong><br \/>\nSetting up the script is really, really easy. Search the file for &#8220;search.twitter.com&#8221;. You&#8217;ll find this<\/p>\n<blockquote><p>var url = &#8220;http:\/\/search.twitter.com\/search.json?q=<strong>%23dkos<\/strong>&amp;callback=?&#8221;; \/\/ Change your query here<\/p><\/blockquote>\n<p>%23 = # so &#8220;%23dkos&#8221; is <a rel=\"tag\" class=\"hashtag u-tag u-category\" href=\"https:\/\/opendna.com\/blog\/tag\/dkos\/\">#dkos<\/a> and and &#8220;%23followfriday&#8221; is <a rel=\"tag\" class=\"hashtag u-tag u-category\" href=\"https:\/\/opendna.com\/blog\/tag\/followfriday\/\">#followfriday<\/a>. Similarly, %40 = @ so &#8220;%40barackobama&#8221; is @barackobama and %40octothorpe&#8221; is @octothorpe. (And <a href=\"http:\/\/www.nationalpost.com\/opinion\/columnists\/What+have+here+great+comeback+stories+history+competitive+punctuation\/3903206\/story.html\">octothorpe<\/a> is the best twitter name. Ever).<\/p>\n<p><i>[I put up the <a href=\"http:\/\/opendna.com\/bloxtalk\/atobama.html\">@barackobama page<\/a> and was going to make some snarky &#8220;you know he doesn&#8217;t read this&#8221; comment, then I noticed that it was dominated by re-tweets of Leonardo DiCaprio (<a href=\"http:\/\/twitter.com\/LeoDiCaprio\/status\/30410275848978433\">you&#8217;ll approve<\/a>).]<\/i><\/p>\n<p>You can filter by tweets which have a keyword \u2014 or phrase if joined by &#8220;%20&#8221; (space) \u2014 and can use &#8220;+from:&#8221; to filter tweets from a single account. &#8220;+from:barackobama&#8221; reads the President&#8217;s tweets, &#8220;%40barackobama&#8221; is people talking to his account and &#8220;barack%20obama&#8221; is people talking about him. You can combine and filter in magnificent ways with a monstrously long search string, but I&#8217;ll let you play around with that. Go to <a href=\"http:\/\/search.twitter.com\/advanced\">http:\/\/search.twitter.com\/advanced<\/a> and then adapt the RSS feed.<\/p>\n<p><strong><em>Colors<\/em><\/strong><br \/>\nWith a little HTML\/CSS experience, you&#8217;ll muddle your way though the font coloring and styling, the page background color and padding. (If you&#8217;re new at this, start by changing the <a href=\"http:\/\/www.w3schools.com\/tags\/ref_colorpicker.asp\">hex color codes<\/a>.) Here&#8217;s what&#8217;s likely going to trip you up: the background color of the tweets is deeper in the code. Search for<\/p>\n<blockquote><p>Simple Styling of the boxes START<\/p><\/blockquote>\n<p>and you&#8217;ll find the background colors for odd- and even-numbered tweets.<\/p>\n<p><strong>Limitations &amp; lessons learned<\/strong> The code does not provide links to individual tweets. If someone comes up with a hack to do that, please let me know.<\/p>\n<p>The vanilla code only pulls one feed and it&#8217;s very strict. This raises the possibility that you set up a page with one hash tag for an event, and another one gets used instead. I made a similar this goof during the <a rel=\"tag\" class=\"hashtag u-tag u-category\" href=\"https:\/\/opendna.com\/blog\/tag\/sotu\/\">#SOTU<\/a> when I set the feed to %23fok (#fok) when +from:keithobermann (from @keithobermann) would have been more appropriate. If you think ahead, you can structure your search string to cast a wider filter and avoid this error.<\/p>\n<p><strong>Hax &amp; back-channels<\/strong><br \/>\n<strong><em>Tweet this meta<\/em><\/strong> You&#8217;ve seen those little blue &#8220;Tweet this&#8221; buttons? (Hint: see the top of this page), well you can get the code <a href=\"http:\/\/twitter.com\/about\/resources\/tweetbutton#status-fields\">here<\/a>.<br \/>\n<strong><em>Go old school<\/em><\/strong> Twitter is limited by the technology it adopted (SMS), so it&#8217;s feels very much like talking via text message. If you want to have a chat, why not embed an IRC channel along with the twitter feeds? <a href=\"http:\/\/qchat.rizon.net\/\">Rizon.net&#8217;s webclient<\/a> allows you to open and embed an IRC channel with iframes (click the blue icon in the top left).<\/p>\n<p><strong>When I mixed it all together<\/strong>&#8230; I came up with this: <a href=\"http:\/\/opendna.com\/bloxtalk\/bloxtalk.html\" target=\"_blank\" rel=\"noopener\"><img decoding=\"async\" src=\"http:\/\/i100.photobucket.com\/albums\/m35\/opendna\/final.jpg\" alt=\"\" border=\"0\" \/><\/a>.<br \/>\nThanks for playing along.<\/p>\n<p><span class=\"update\">Updated by opendna at Sun Feb 13, 2011, 7:03:51 PM<\/span><\/p>\n<p>That last page got borked by the DK4 update and will require a new hack. Here&#8217;s an alternate example, just for DK4: <a href=\"http:\/\/opendna.com\/bloxtalk\/dk4\/\">http:\/\/opendna.com\/bloxtalk\/dk4<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>This article describes the use of a simple AJAX-powered webpage to display a real-time feed from Twitter. It suggests use cases and reasons to pair it with an IRC webapp to provide a back channel to noisy hashtags.<\/p>\n<p>Note: code uses Twitter REST API v1. This post has not been updated.<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"webmentions_disabled_pings":false,"webmentions_disabled":false,"activitypub_content_warning":"","activitypub_content_visibility":"","activitypub_max_image_attachments":3,"activitypub_interaction_policy_quote":"anyone","activitypub_status":"","footnotes":""},"categories":[208,8],"tags":[212,215,213,217,211,214,216],"class_list":["post-812","post","type-post","status-publish","format-standard","hentry","category-archive","category-geek-out","tag-bloxtalk","tag-dkos","tag-fok","tag-followfriday","tag-jan25","tag-openmedia","tag-sotu"],"_links":{"self":[{"href":"https:\/\/opendna.com\/blog\/wp-json\/wp\/v2\/posts\/812","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/opendna.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/opendna.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/opendna.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/opendna.com\/blog\/wp-json\/wp\/v2\/comments?post=812"}],"version-history":[{"count":1,"href":"https:\/\/opendna.com\/blog\/wp-json\/wp\/v2\/posts\/812\/revisions"}],"predecessor-version":[{"id":1880,"href":"https:\/\/opendna.com\/blog\/wp-json\/wp\/v2\/posts\/812\/revisions\/1880"}],"wp:attachment":[{"href":"https:\/\/opendna.com\/blog\/wp-json\/wp\/v2\/media?parent=812"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/opendna.com\/blog\/wp-json\/wp\/v2\/categories?post=812"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/opendna.com\/blog\/wp-json\/wp\/v2\/tags?post=812"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}