<?xml version="1.0" encoding="UTF-8"?> <rss
version="2.0"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns:wfw="http://wellformedweb.org/CommentAPI/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
><channel><title>Terence Eden has a Blog &#187; twitter</title> <atom:link href="http://shkspr.mobi/blog/index.php/tag/twitter/feed/" rel="self" type="application/rss+xml" /><link>http://shkspr.mobi/blog</link> <description>Mobiles, Shakespeare, Politics, Usability.</description> <lastBuildDate>Mon, 06 Feb 2012 16:31:09 +0000</lastBuildDate> <language>en</language> <sy:updatePeriod>hourly</sy:updatePeriod> <sy:updateFrequency>1</sy:updateFrequency> <generator>http://wordpress.org/?v=3.3.1</generator> <item><title>Sky News Infringed My Copyright</title><link>http://shkspr.mobi/blog/index.php/2012/01/sky-news-infringed-my-copyright/</link> <comments>http://shkspr.mobi/blog/index.php/2012/01/sky-news-infringed-my-copyright/#comments</comments> <pubDate>Fri, 27 Jan 2012 15:00:43 +0000</pubDate> <dc:creator>Terence Eden</dc:creator> <category><![CDATA[/etc/]]></category> <category><![CDATA[copyright]]></category> <category><![CDATA[legal]]></category> <category><![CDATA[sky]]></category> <category><![CDATA[sky news]]></category> <category><![CDATA[twitter]]></category> <category><![CDATA[youtube]]></category><guid
isPermaLink="false">http://shkspr.mobi/blog/?p=5301</guid> <description><![CDATA[UPDATE! I have reached a settlement with Sky. tl;dr Sky News stole my copyrighted work and distributed it without credit or payment. I asked them to pay &#163;1,500. They refused. Full Story During the recent O2 brouhaha I recorded a video showing how the issue could affect people. I deliberately gave it the standard YouTube <a
href='http://shkspr.mobi/blog/index.php/2012/01/sky-news-infringed-my-copyright/'>[...]</a>]]></description> <content:encoded><![CDATA[<h2>UPDATE!</h2><p><a
href="#settled">I have reached a settlement with Sky.</a></p><h2>tl;dr</h2><p>Sky News stole my copyrighted work and distributed it without credit or payment.</p><p>I asked them to pay &pound;1,500.</p><p>They refused.</p><h2>Full Story</h2><p>During the recent O2 brouhaha <a
href="http://www.youtube.com/watch?v=67b4GTI2Tto">I recorded a video showing how the issue could affect people</a>.  I deliberately gave it the standard YouTube licence rather than the Creative Commons licence.</p><p>Later that evening, I was alerted to the fact that Sky News had broadcast my video without first seeking permission.</p> <style type='text/css'>#bbpBox_162228673632669696 a { text-decoration:none; color:#94a4ae; }#bbpBox_162228673632669696 a:hover { text-decoration:underline; }</style><div
id='bbpBox_162228673632669696' class='bbpBox' style='padding:20px; margin:5px 0; background-color:#251810; background-image:url(http://a0.twimg.com/profile_background_images/172038994/twit-background-naked.jpg); background-repeat:no-repeat'><div
style='background:#fff; padding:10px; margin:0; min-height:48px; color:#a98e6f; -moz-border-radius:5px; -webkit-border-radius:5px;'><span
style='width:100%; font-size:18px; line-height:22px;'>Just did Sky News spot about the @<a
href="http://twitter.com/intent/user?screen_name=O2" class="twitter-action">O2</a> controversy. From sound of what came down my earpiece they also used @<a
href="http://twitter.com/intent/user?screen_name=edent" class="twitter-action">edent</a>'s vid <a
href="https://t.co/tBr2SoAp" rel="nofollow">https://t.co/tBr2SoAp</a></span><div
class='bbp-actions' style='font-size:12px; width:100%; padding:5px 0; margin:0 0 10px 0; border-bottom:1px solid #e6e6e6;'><img
align='middle' src='http://shkspr.mobi/blog/wp-content/plugins/twitter-blackbird-pie//images/bird.png' /><a
title='tweeted on 25/01/2012 17:41' href='http://twitter.com/#!/gcluley/status/162228673632669696' target='_blank'>25/01/2012 17:41</a> via <a
href="http://www.echofon.com/" rel="nofollow" target="blank">Echofon</a><a
href='https://twitter.com/intent/tweet?in_reply_to=162228673632669696&related=https://twitter.com/edent' class='bbp-action bbp-reply-action' title='Reply'><span><em
style='margin-left: 1em;'></em><strong>Reply</strong></span></a><a
href='https://twitter.com/intent/retweet?tweet_id=162228673632669696&related=https://twitter.com/edent' class='bbp-action bbp-retweet-action' title='Retweet'><span><em
style='margin-left: 1em;'></em><strong>Retweet</strong></span></a><a
href='https://twitter.com/intent/favorite?tweet_id=162228673632669696&related=https://twitter.com/edent' class='bbp-action bbp-favorite-action' title='Favorite'><span><em
style='margin-left: 1em;'></em><strong>Favorite</strong></span></a></div><div
style='float:left; padding:0; margin:0'><a
href='http://twitter.com/intent/user?screen_name=gcluley'><img
style='width:48px; height:48px; padding-right:7px; border:none; background:none; margin:0' src='http://a0.twimg.com/profile_images/1147378679/vote-cluley-twitter_normal.jpg' /></a></div><div
style='float:left; padding:0; margin:0'><a
style='font-weight:bold' href='http://twitter.com/intent/user?screen_name=gcluley'>@gcluley</a><div
style='margin:0; padding-top:2px'>Graham Cluley</div></div><div
style='clear:both'></div></div></div><p>I grumbled a bit on Twitter and was contacted by a representative of Sky News.  He was very quick in ascertaining that my video was used without my permission and arranged to prevent it being shown again.</p><p>I was not happy about this state of affairs.  BSkyB and News International have been very vocal about digital piracy and copyright infringement.  They have relentlessly pursued a copyright maximalist agenda which &#8211; I believe &#8211; is damaging to the creative industries.  Not to mention rampantly hypocritical.</p><p>Sky News accept user generated videos, with this stern warning:</p><blockquote><p>Copyright protects the interests of the people and companies who create these products. If the content or product or marks in your video are owned by someone else, you are infringing copyright and run the risk being prosecuted.</p><p><strong>It is important that you understand that you cannot take other people&#8217;s creations and use them as you see fit</strong>.</p><p>Uploading somebody else&#8217;s video is no different to taking something from a shop without paying. Copyright infringement damages the music, film and television businesses and the future development of music, film and TV programmes.</p><p>From <a
href="http://uservideos.sky.com/site-skynews/article/index/faq.html">Sky News&#8217; Frequently Asked Questions about user videos</a>.  Emphasis added.</p></blockquote><p>Sky News have a <a
href="http://onlinejournalismblog.com/2009/08/19/what-happened-when-sky-news-took-images-from-twitter/">history of ignoring copyright</a> and infringing the moral rights of authors.</p><p>Unfortunately, the Digital Economy Act doesn&#8217;t allow me to sue Sky News for distributing my content for free without my permission.  An individual can lose their Internet access for sharing a movie, however there don&#8217;t seem to be any sanctions against a large company for sharing my copyrighted work without permission.</p><p>I don&#8217;t have the resources to fight a legal battle against Sky.  So I decided to settle for cold, hard cash.</p><p>Originally, Sky made the following offer:</p><blockquote><p> For a short youtube video like that we would normally pay around £50 &#038; would be more than willing to pay an extra £25 for the fact you weren&#8217;t asked in the inconvenience it has caused you.</p></blockquote><p>The <a
href="http://www.londonfreelance.org/feesguide/index.php?&#038;section=Photography&#038;subsect=Videography&#038;page=INDEX">NUJ publish a freelance rate card</a>. The rate for freelance video should be around &pound;300 per minute.</p><p>I farted in Sky&#8217;s general direction.  I wanted &pound;300 for the broadcast of the video, plus &pound;1,200. I calculated that as &pound;400 for them failing to ask permission, another &pound;400 for them infringing my copyright, and then &pound;400 for them violating my moral rights.</p><p>Even if they didn&#8217;t agree with the above reasoning, it is usual to charge <a
href="http://www.londonfreelance.org/feesguide/index.php?language=en&#038;country=UK&#038;section=General&#038;subsect=Rights+and+why+they+are+important&#038;page=Advice">four times time standard licence rate</a> when a copyright owner is asked to assign all rights away.  Effectively, Sky News had unilaterally assigned all my rights to them &#8211; so I felt justified asking for this sum.</p><p>Overall, I thought &pound;1,500 was reasonable &#8211; especially when you consider that <a
href="http://www.wonderlandblog.com/wonderland/2011/08/the-daily-mail-knowingly-and-commercially-used-my-photos-despite-my-denying-them-permission.html">the Daily Mail paid &pound;2,000 for using photographs without permission</a>.</p><p>Sky came back with an offer of &pound;300.</p><p>I pointed out that <a
href="http://www.legislation.gov.uk/ukpga/1988/48/section/107">s107 of the Copyright, Designs and Patents Act 1988</a> had provisions for fines of up to &pound;50,000, or a six month prison sentence.  In comparison &pound;1,500 seems modest.</p><p>Sky replied:</p><blockquote><p>As I indicated, we do not yet agree on a sensible figure for this use.</p><p>Bearing in mind you are now invoking the Copyright Designs and Patents Act I have placed this matter in the hands of our lawyers.</p><p>This does not represent an unwillingness to come to an agreement between us but, unfortunately, it is likely to slow the progress slightly.</p></blockquote><p>Now I&#8217;m waiting to hear back from their lawyers.  I wonder what their hourly rate is?</p><p>I&#8217;ll update this post when I know more&#8230;</p><h1><a
name="settled">A Settlement</a></h1><p>I have accepted an offer of &pound;300.  A few minutes ago, I received this email from Sky:</p><blockquote><p>After consulting with our Sky lawyers our position is that we believe a £300 settlement is a fair and appropriate sum.<br
/> Our position is:</p><ul><li>The &pound;300 is in respect of what you describes as &#8220;infringement of copyright&#8221; rather than any &#8220;union rate&#8221;;</li><li>Contrary to what you claim, we did not act as if you had assigned us all rights. Specifically, we did not claim ownership nor seek to profit from it by licensing to others;</li><li>Criminal liability will not attach in relation to an inadvertent use of footage;</li><li>English law does not recognise violation of moral rights;</li><li>There is no authority that an infringement in these circumstances attracts four times the usual licence fee.  To the contrary, the usual measure is what the reasonable cost of licensing would have been.</li><li>Our offer is generous for the reasons above and we will not increase it.</li></ul><p>May I also stress that when you are relating this issue to third parties on whatever platform I would consider it unfair if you did not relay the fact that we immediately acknowledged your copyright and sought to bring redress. I stress, once again, that we take copyright and its infringement very seriously at Sky News.</p></blockquote><p>I&#8217;m not a copyright lawyer, so am in no position to argue against their formidable legal might.  I have invoiced them for &pound;300.  I must point out that &#8211; once I contacted them &#8211; Sky were very quick to take down the infringing content and have been unfailingly polite in their dealings with me.</p><p>I will be donating &pound;100 to both <a
href="http://www.openrightsgroup.org/">The Open Rights Group</a> and <a
href="http://www.mysociety.org/donate/">MySociety</a>.   And drinking the rest.</p><p>Thank you for all your comments, tweets, and messages of support.</p><h3>Footnote</h3><p>I&#8217;m currently on holiday &#8211; so comment moderation and updates may be delayed.</p><p><a
href="http://shkspr.mobi/blog/?flattrss_redirect&amp;id=5301&amp;md5=06c5fc112486877747077d4d5b33ff70" title="Flattr" target="_blank"><img
src="http://shkspr.mobi/blog/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded> <wfw:commentRss>http://shkspr.mobi/blog/index.php/2012/01/sky-news-infringed-my-copyright/feed/</wfw:commentRss> <slash:comments>19</slash:comments> <atom:link rel="payment" href="http://shkspr.mobi/blog/?flattrss_redirect&amp;id=5301&amp;md5=06c5fc112486877747077d4d5b33ff70" type="text/html" /> </item> <item><title>Leaving Klout</title><link>http://shkspr.mobi/blog/index.php/2011/11/leaving-klout/</link> <comments>http://shkspr.mobi/blog/index.php/2011/11/leaving-klout/#comments</comments> <pubDate>Fri, 04 Nov 2011 13:47:03 +0000</pubDate> <dc:creator>Terence Eden</dc:creator> <category><![CDATA[/etc/]]></category> <category><![CDATA[influence]]></category> <category><![CDATA[klout]]></category> <category><![CDATA[loudmouthman]]></category> <category><![CDATA[nablopomo]]></category> <category><![CDATA[twitter]]></category><guid
isPermaLink="false">http://shkspr.mobi/blog/?p=4631</guid> <description><![CDATA[According to faux-influence-measument site, Klout, I was influential on Verizon Droid Stock Market Hotels Errr&#8230;..? What? If you&#8217;re following me on Twitter for any of the above, perhaps you&#8217;d like to consider your life choices. So, I opted-out of Klout. Their opt-out page is full of feel-good nonsense to try and convince people not to <a
href='http://shkspr.mobi/blog/index.php/2011/11/leaving-klout/'>[...]</a>]]></description> <content:encoded><![CDATA[<p>According to faux-influence-measument site, Klout, I was influential on</p><ul><li>Verizon Droid</li><li>Stock Market</li><li>Hotels</li></ul><p>Errr&#8230;..? What? If you&#8217;re <a
href="https://twitter.com/edent">following me on Twitter</a> for any of the above, perhaps you&#8217;d like to consider your life choices.</p><p>So, I <a
href="http://klout.com/corp/optout">opted-out of Klout</a>.</p><p>Their opt-out page is full of feel-good nonsense to try and convince people not to remove their own profile.  It didn&#8217;t work on me.  They asked for my reasons for leaving, and this is what I told them:</p><blockquote><p> Three reasons.<br
/> 1) You think I&#8217;m influential about things that I&#8217;ve never tweeted about (Stock market? Verizon?)<br
/> 2) I didn&#8217;t ask to sign up.<br
/> 3) It&#8217;s taken you too long to offer this opt-out. If I&#8217;d known from the start I could have opted out, I would have been fairly relaxed. The fact that you&#8217;ve resisted for so long to offer the opt-out makes me think you&#8217;re not trustworthy.</p></blockquote><p>I am indebted to <a
href="http://loudmouthman.com/2011/08/16/lacking-in-klout/">LoudMouthMan for taking Klout to task</a>.  I&#8217;m sure that without his persistence, Klout would still be peddling lies about me.</p><p>For a good overview of why &#8220;influence measument&#8221; site like Klout don&#8217;t really work, read <a
href="http://jonathanmacdonald.com/?p=5694">The Fallacy of Presumed Influence</a> by Jonathan Macdonald.</p><p><a
href="http://shkspr.mobi/blog/?flattrss_redirect&amp;id=4631&amp;md5=c3a3d2890b0ad839503bd69112441d0f" title="Flattr" target="_blank"><img
src="http://shkspr.mobi/blog/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded> <wfw:commentRss>http://shkspr.mobi/blog/index.php/2011/11/leaving-klout/feed/</wfw:commentRss> <slash:comments>3</slash:comments> <atom:link rel="payment" href="http://shkspr.mobi/blog/?flattrss_redirect&amp;id=4631&amp;md5=c3a3d2890b0ad839503bd69112441d0f" type="text/html" /> </item> <item><title>When is a URL not a URL?</title><link>http://shkspr.mobi/blog/index.php/2011/07/when-is-a-url-not-a-url/</link> <comments>http://shkspr.mobi/blog/index.php/2011/07/when-is-a-url-not-a-url/#comments</comments> <pubDate>Wed, 27 Jul 2011 11:37:57 +0000</pubDate> <dc:creator>Terence Eden</dc:creator> <category><![CDATA[/etc/]]></category> <category><![CDATA[usability]]></category> <category><![CDATA[api]]></category> <category><![CDATA[regex]]></category> <category><![CDATA[twitter]]></category> <category><![CDATA[urls]]></category><guid
isPermaLink="false">http://shkspr.mobi/blog/?p=4271</guid> <description><![CDATA[Summary Twitter&#8217;s way of linking URLs is broken. It&#8217;s annoying to users, and a pain in the arse to developers. This quick post talks about the problem and offers a solution. I&#8217;ve raised a bug with Twitter and I hope you&#8217;ll star it as important to you. Preamble A common trope in programming classes is <a
href='http://shkspr.mobi/blog/index.php/2011/07/when-is-a-url-not-a-url/'>[...]</a>]]></description> <content:encoded><![CDATA[<h2>Summary</h2><p>Twitter&#8217;s way of linking URLs is broken.  It&#8217;s annoying to users, and a pain in the arse to developers.  This quick post talks about the problem and offers a solution.</p><p><a
href="http://code.google.com/p/twitter-api/issues/detail?id=2240">I&#8217;ve raised a bug with Twitter</a> and I hope you&#8217;ll star it as important to you.<br
/> <span
id="more-4271"></span></p><h2>Preamble</h2><p>A common trope in programming classes is &#8220;<a
href="http://www.regular-expressions.info/email.html">how do you detect valid email address</a>?&#8221;</p><p>It should be obvious, right?  A string of text, an @, a domain &#8211; probably ending in .com.<br
/> As it turns out, it&#8217;s not that simple.  &#8220;who+o&#8217;toole@invalid.museum&#8221; is a potentially valid address, for example.<br
/> There are literally thousands of ways to detect the potentially infinite variety of email addresses.</p><p>The same is true for URLs &#8211; and slavish adherence to guidelines is killing Twitter&#8217;s usefulness.</p><h2>The URL Matching Problem</h2><p>Which of these strings should be turned into hyperlinks?</p><pre>
www.bbc.co.uk

example.com

http://test

https://test.test

ftp://news.com
</pre><p>As it happens, Twitter only matches &#8220;https://test.test&#8221; and none of the others.</p><p><a
href="https://twitter.com/edent/status/96172785436590080"><img
src="http://shkspr.mobi/blog/wp-content/uploads/2011/07/URL-test-1.jpg" alt="" title="URL test 1" width="514" height="216" class="aligncenter size-full wp-image-4274" /></a></p><p>Twitter&#8217;s matching regex is, as far as I can tell, this</p><pre>If it starts with http:// or https:// and has a dot in it - it's a URL</pre><p>I think this is a serious weakness.  Twitter users are sharing URLs which their followers can&#8217;t click on &#8211; Twitter is also linking to URLs which don&#8217;t exist.</p><p>I&#8217;ve picked these examples more or less at random.<br
/> <a
href="https://twitter.com/ianvisits/status/82712842112991232"><img
src="http://shkspr.mobi/blog/wp-content/uploads/2011/07/URL-test-2.jpg" alt="" title="URL test 2" width="514" height="216" class="aligncenter size-full wp-image-4275" /></a></p><p><a
href="https://twitter.com/PeakChief/status/82722453767462912"><img
src="http://shkspr.mobi/blog/wp-content/uploads/2011/07/URL-test-3.jpg" alt="" title="URL test 3" width="514" height="216" class="aligncenter size-full wp-image-4276" /></a></p><h2>Solution?</h2><p>Much like the email regexes, I would take a much more lax approach.  Essentially, if it looks vaguely like a URL &#8211; link to it.</p><p>I would suggest the following rules:</p><ul><li>If it starts with a protocol &#8211; http:// ftp:// tel: etc &#8211; create a hyperlink.</li><li>If it starts with www. &#8211; create a hyperlink.</li><li>If it ends . then a <a
href="http://data.iana.org/TLD/tlds-alpha-by-domain.txt">valid TLD</a> &#8211; create a hyperlink.</li><li>If it contains a <a
href="http://data.iana.org/TLD/tlds-alpha-by-domain.txt">valid TLD</a> followed by a slash then some other characters &#8211; create a hyperlink.</li></ul><p>The &#8220;correct&#8221; method would then be for Twitter to perform an <a
href="http://en.wikipedia.org/wiki/HTTP#Request_methods">HTTP HEAD request</a> to see if the URL is potentially valid.  There are three drawbacks to this.</p><ol><li>It may place excessive load on Twitter&#8217;s servers to process and cache these requests.</li><li>The URL may be that of an Intranet site &#8211; and thus inaccessible to Twitter.</li><li>The URL may be valid but temporarily inaccessible.</li></ol><p>Regardless of the method, surely it&#8217;s inexcusable that &#8220;www.example.com&#8221; isn&#8217;t detected as a URL whereas &#8220;http://bork.bork.bork&#8221; is?</p><h2>ACTION!</h2><p>If you think Twitter&#8217;s approach to hyperlinks is wrong &#8211; please <a
href="http://code.google.com/p/twitter-api/issues/detail?id=2240">make your voice heard at the bug report</a>.</p><p><a
href="http://shkspr.mobi/blog/?flattrss_redirect&amp;id=4271&amp;md5=14fc56a48a7b728fe933b966dd9788cb" title="Flattr" target="_blank"><img
src="http://shkspr.mobi/blog/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded> <wfw:commentRss>http://shkspr.mobi/blog/index.php/2011/07/when-is-a-url-not-a-url/feed/</wfw:commentRss> <slash:comments>1</slash:comments> <atom:link rel="payment" href="http://shkspr.mobi/blog/?flattrss_redirect&amp;id=4271&amp;md5=14fc56a48a7b728fe933b966dd9788cb" type="text/html" /> </item> <item><title>Twitter Hashtags and QR Codes</title><link>http://shkspr.mobi/blog/index.php/2011/06/twitter-hashtags-and-qr-codes/</link> <comments>http://shkspr.mobi/blog/index.php/2011/06/twitter-hashtags-and-qr-codes/#comments</comments> <pubDate>Wed, 29 Jun 2011 11:14:47 +0000</pubDate> <dc:creator>Terence Eden</dc:creator> <category><![CDATA[mobile]]></category> <category><![CDATA[qr]]></category> <category><![CDATA[hashtag]]></category> <category><![CDATA[search]]></category> <category><![CDATA[twitter]]></category><guid
isPermaLink="false">http://shkspr.mobi/blog/?p=4224</guid> <description><![CDATA[I spotted this poster today, encouraging people to search for the Twitter hashtag &#8220;#Transformers&#8221;. Wouldn&#8217;t it make sense to use a QR code as well? That way people could quickly scan, and be taken straight to the discussion, rather than have to fire up Twitter and do a manual search. As it happens, it&#8217;s slightly <a
href='http://shkspr.mobi/blog/index.php/2011/06/twitter-hashtags-and-qr-codes/'>[...]</a>]]></description> <content:encoded><![CDATA[<p>I spotted this poster today, encouraging people to search for the Twitter hashtag &#8220;#Transformers&#8221;.<br
/> <img
src="http://shkspr.mobi/blog/wp-content/uploads/2011/06/Transformers-Poster-Twitter-Hashtag-300x225.jpg" alt="Transformers Poster Twitter Hashtag" title="Transformers Poster Twitter Hashtag" width="300" height="225" class="aligncenter size-medium wp-image-4226" /></p><p>Wouldn&#8217;t it make sense to use a QR code as well?  That way people could quickly scan, and be taken straight to the discussion, rather than have to fire up Twitter and do a manual search.</p><p>As it happens, it&#8217;s slightly tricky to make a QR code which searches for a Twitter hashtag.</p><p>There are two things to note:</p><ol><li>Twitter&#8217;s search URLs are annoyingly different from every other search URL on the planet.</li><li>You will need to take care of URL Encoding for special characters.</li></ol><p><span
id="more-4224"></span></p><h2>Building The Search Query</h2><p>A typical Twitter search URL is</p><pre>https://mobile.twitter.com/#!/search/</pre><p>With the query at the end, so a search for &#8220;Transformers&#8221; would be</p><pre>https://mobile.twitter.com/#!/search/Transformers</pre><h2>Encoding Correctly</h2><p>Hash symbols (#) need to be <a
href="http://en.wikipedia.org/wiki/Percent-encoding">URL Encoded</a>.  In this case, the hash becomes &#8220;%23&#8243;</p><pre>https://mobile.twitter.com/#!/search/%23Transformers</pre><p>However, there is a &#8220;gotcha&#8221;.  Because of the&#8230; special&#8230;  way Twitter constructs its search URLs, we have to URL Encode the <em>percentage</em> sign!  So, the &#8220;%&#8221; becomes &#8220;%25&#8243;.</p><p>So, our final URL becomes</p><pre>https://mobile.twitter.com/#!/search/%2523Transformers</pre><p>Finally, if you want to use something like Google Charts to create your QR codes, you&#8217;ll need the URL Encode <em>all</em> of the : / # ! and other special characters.</p><pre>https://chart.googleapis.com/chart?chs=200x200&#038;cht=qr&#038;chl=
   https%3A%2F%2Fmobile.twitter.com%2F%23%21%2Fsearch%2F%2523Transformers
</pre><h2>The Final Result</h2><p>We end up with a QR code which can be scanned to take the user directly to the hashtag they are searching for,<img
src="http://shkspr.mobi/blog/wp-content/uploads/2011/06/Transformers-Hashtag-Twitter-Search.png" alt="Transformers Hashtag Twitter Search" title="Transformers Hashtag Twitter Search" width="200" height="200" class="aligncenter size-full wp-image-4225" /></p><p><a
href="http://shkspr.mobi/blog/?flattrss_redirect&amp;id=4224&amp;md5=1945f2e29578005a77ec04f417805b04" title="Flattr" target="_blank"><img
src="http://shkspr.mobi/blog/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded> <wfw:commentRss>http://shkspr.mobi/blog/index.php/2011/06/twitter-hashtags-and-qr-codes/feed/</wfw:commentRss> <slash:comments>7</slash:comments> <atom:link rel="payment" href="http://shkspr.mobi/blog/?flattrss_redirect&amp;id=4224&amp;md5=1945f2e29578005a77ec04f417805b04" type="text/html" /> </item> <item><title>Does Your Employer Own Your Twitter Account?</title><link>http://shkspr.mobi/blog/index.php/2011/06/does-your-employer-own-your-twitter-account/</link> <comments>http://shkspr.mobi/blog/index.php/2011/06/does-your-employer-own-your-twitter-account/#comments</comments> <pubDate>Wed, 22 Jun 2011 14:45:48 +0000</pubDate> <dc:creator>Terence Eden</dc:creator> <category><![CDATA[/etc/]]></category> <category><![CDATA[bbc]]></category> <category><![CDATA[social media]]></category> <category><![CDATA[twitter]]></category><guid
isPermaLink="false">http://shkspr.mobi/blog/?p=4208</guid> <description><![CDATA[What happens to your social media profile when you change jobs? Recently, the BBC&#8217;s Laura Kunessberg announced she was heading off to ITV. Which got me wondering. Twitter allows any user to change their name and keep all their followers. All of Laura&#8217;s followers, friends, favourites, tweets, retweets, and lists will dissapear when she swaps <a
href='http://shkspr.mobi/blog/index.php/2011/06/does-your-employer-own-your-twitter-account/'>[...]</a>]]></description> <content:encoded><![CDATA[<p>What happens to your social media profile when you change jobs?  Recently, the BBC&#8217;s Laura Kunessberg announced she was heading off to ITV.</p> <style type='text/css'>#bbpBox_83527461131911168 a { text-decoration:none; color:#1f527b; }#bbpBox_83527461131911168 a:hover { text-decoration:underline; }</style><div
id='bbpBox_83527461131911168' class='bbpBox' style='padding:20px; margin:5px 0; background-color:#ffffff; background-image:url(http://a2.twimg.com/profile_background_images/72164945/bbc_twitter_template1280.jpg); background-repeat:no-repeat'><div
style='background:#fff; padding:10px; margin:0; min-height:48px; color:#5a5a5a; -moz-border-radius:5px; -webkit-border-radius:5px;'><span
style='width:100%; font-size:18px; line-height:22px;'>As you've discovered I will become @<a
href="http://twitter.com/intent/user?screen_name=ITVLauraK" class="twitter-action">ITVLauraK</a> in September! Thanks for all the lovely tweets - Back in Westminster tomorrow</span><div
class='bbp-actions' style='font-size:12px; width:100%; padding:5px 0; margin:0 0 10px 0; border-bottom:1px solid #e6e6e6;'><img
align='middle' src='http://shkspr.mobi/blog/wp-content/plugins/twitter-blackbird-pie//images/bird.png' /><a
title='tweeted on 22/06/2011 13:31' href='http://twitter.com/#!/BBCLauraK/status/83527461131911168' target='_blank'>22/06/2011 13:31</a> via web<a
href='https://twitter.com/intent/tweet?in_reply_to=83527461131911168&related=https://twitter.com/edent' class='bbp-action bbp-reply-action' title='Reply'><span><em
style='margin-left: 1em;'></em><strong>Reply</strong></span></a><a
href='https://twitter.com/intent/retweet?tweet_id=83527461131911168&related=https://twitter.com/edent' class='bbp-action bbp-retweet-action' title='Retweet'><span><em
style='margin-left: 1em;'></em><strong>Retweet</strong></span></a><a
href='https://twitter.com/intent/favorite?tweet_id=83527461131911168&related=https://twitter.com/edent' class='bbp-action bbp-favorite-action' title='Favorite'><span><em
style='margin-left: 1em;'></em><strong>Favorite</strong></span></a></div><div
style='float:left; padding:0; margin:0'><a
href='http://twitter.com/intent/user?screen_name=BBCLauraK'><img
style='width:48px; height:48px; padding-right:7px; border:none; background:none; margin:0' src='http://a0.twimg.com/profile_images/337645054/laura_normal.jpg' /></a></div><div
style='float:left; padding:0; margin:0'><a
style='font-weight:bold' href='http://twitter.com/intent/user?screen_name=BBCLauraK'>@BBCLauraK</a><div
style='margin:0; padding-top:2px'>Laura Kuenssberg</div></div><div
style='clear:both'></div></div></div><p>Which got me wondering.</p> <style type='text/css'>#bbpBox_83531895127810048 a { text-decoration:none; color:#0084B4; }#bbpBox_83531895127810048 a:hover { text-decoration:underline; }</style><div
id='bbpBox_83531895127810048' class='bbpBox' style='padding:20px; margin:5px 0; background-color:#C0DEED; background-image:url(http://a0.twimg.com/images/themes/theme1/bg.png); background-repeat:no-repeat'><div
style='background:#fff; padding:10px; margin:0; min-height:48px; color:#333333; -moz-border-radius:5px; -webkit-border-radius:5px;'><span
style='width:100%; font-size:18px; line-height:22px;'>Why doesn't  @<a
href="http://twitter.com/intent/user?screen_name=BBCLauraK" class="twitter-action">BBCLauraK</a> simply rename her account to @<a
href="http://twitter.com/intent/user?screen_name=ITVLauraK" class="twitter-action">ITVLauraK</a> in September? Or are her followers the BBC's property?</span><div
class='bbp-actions' style='font-size:12px; width:100%; padding:5px 0; margin:0 0 10px 0; border-bottom:1px solid #e6e6e6;'><img
align='middle' src='http://shkspr.mobi/blog/wp-content/plugins/twitter-blackbird-pie//images/bird.png' /><a
title='tweeted on 22/06/2011 13:48' href='http://twitter.com/#!/edent/status/83531895127810048' target='_blank'>22/06/2011 13:48</a> via <a
href="https://shkspr.mobi/dabr/" rel="nofollow" target="blank">Shkspr&#039;s SSL Dabr</a><a
href='https://twitter.com/intent/tweet?in_reply_to=83531895127810048&related=https://twitter.com/edent' class='bbp-action bbp-reply-action' title='Reply'><span><em
style='margin-left: 1em;'></em><strong>Reply</strong></span></a><a
href='https://twitter.com/intent/retweet?tweet_id=83531895127810048&related=https://twitter.com/edent' class='bbp-action bbp-retweet-action' title='Retweet'><span><em
style='margin-left: 1em;'></em><strong>Retweet</strong></span></a><a
href='https://twitter.com/intent/favorite?tweet_id=83531895127810048&related=https://twitter.com/edent' class='bbp-action bbp-favorite-action' title='Favorite'><span><em
style='margin-left: 1em;'></em><strong>Favorite</strong></span></a></div><div
style='float:left; padding:0; margin:0'><a
href='http://twitter.com/intent/user?screen_name=edent'><img
style='width:48px; height:48px; padding-right:7px; border:none; background:none; margin:0' src='http://a3.twimg.com/profile_images/1283757621/Sketch_Avatar_normal.jpg' /></a></div><div
style='float:left; padding:0; margin:0'><a
style='font-weight:bold' href='http://twitter.com/intent/user?screen_name=edent'>@edent</a><div
style='margin:0; padding-top:2px'>Terence Eden</div></div><div
style='clear:both'></div></div></div><p>Twitter allows any user to change their name and <em>keep all their followers</em>.  All of Laura&#8217;s followers, friends, favourites, tweets, retweets, and lists will dissapear when she swaps to a new account.</p><p>Or will they?  Is @BBCLauraK the twitter account for the BBC&#8217;s Chief Political Correspondent? Or is it Laura&#8217;s account?<br
/> If the former, I&#8217;d expect it to be taken over by her successor and renamed @BBCgordonGopher (or whoever).<br
/> If the latter, it makes sense for her to rename the account to @ITVlauraK (or whatever).</p><p>Looking at her feed, it&#8217;s broadcast only with almost no &#8220;personal&#8221; tweets.  Certainly no &#8220;Urgh, hungover&#8221; or &#8220;Trains late again!&#8221; tweets.</p><p>So, it probably makes sense for Laura to hand over control of the account when she leaves.</p><h2>Impact On You</h2><p>How much work tweeting do you do from your Twitter account?  If you left your job, would your bosses be able to demand you surrender the account to them?</p><p>Sure, if you&#8217;re tweeting from @NameOfYourCompany &#8211; it&#8217;s their account.  But if you&#8217;re @CompanyName_Bob &#8211; do you get to keep it when you go?  What if you&#8217;re just @You &#8211; and you tweet about the company you work for &#8211; what happens to all that good-will when you go?</p><h2>Work Phone vs Work Email</h2><p>When I first joined Vodafone nearly a decade ago, I was given a mobile phone number.  Our office was quite revolutionary because there we <em>no desk phones</em>! Of course not; we were in the mobile phone business.</p><p>This confused some people greatly.  I&#8217;d give them my number and they&#8217;d say &#8220;yes, but how can I reach you at your desk?&#8221;<br
/> And I&#8217;d say &#8220;Errrr&#8230;. I always have my mobile with me.  Assuming it&#8217;s me you want to reach, ring that number.  Why would you want to talk to someone who happened to be sitting near where I work?&#8221;</p><p>Since then, I&#8217;ve kept the same mobile number.  If you want to reach <strong>me</strong> &#8211; that&#8217;s the number you call.  No matter who I end up working for, that&#8217;s my number.  When I move roles, I take my number with me.  When I leave a job, I take my number with me.</p><p>Yet I don&#8217;t take my email address with me.  Mails to terence.eden@vodafone.com will go unanswered &#8211; I hope!<br
/> I can understand that &#8211; I don&#8217;t want confidential documents forwarded to me.  The domain name would make it look like I was still affiliated with an old employer.</p><p>But my phone number comes to me, Terence Eden.  Wherever I am.  Whoever I work for.</p><p>My Twitter account &#8211; @edent &#8211; is personal.  It&#8217;s mine.  No boss can take it away from me.</p><p>What about yours?</p><p><a
href="http://shkspr.mobi/blog/?flattrss_redirect&amp;id=4208&amp;md5=e0750ffb45cb8738bcd12d195508dbae" title="Flattr" target="_blank"><img
src="http://shkspr.mobi/blog/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded> <wfw:commentRss>http://shkspr.mobi/blog/index.php/2011/06/does-your-employer-own-your-twitter-account/feed/</wfw:commentRss> <slash:comments>1</slash:comments> <atom:link rel="payment" href="http://shkspr.mobi/blog/?flattrss_redirect&amp;id=4208&amp;md5=e0750ffb45cb8738bcd12d195508dbae" type="text/html" /> </item> <item><title>Displaying Twitter Photos via Entities</title><link>http://shkspr.mobi/blog/index.php/2011/06/displaying-twitter-photos-via-entities/</link> <comments>http://shkspr.mobi/blog/index.php/2011/06/displaying-twitter-photos-via-entities/#comments</comments> <pubDate>Fri, 03 Jun 2011 15:43:19 +0000</pubDate> <dc:creator>Terence Eden</dc:creator> <category><![CDATA[mobile]]></category> <category><![CDATA[api]]></category> <category><![CDATA[code]]></category> <category><![CDATA[dabr]]></category> <category><![CDATA[howto]]></category> <category><![CDATA[php]]></category> <category><![CDATA[twitter]]></category><guid
isPermaLink="false">http://shkspr.mobi/blog/?p=4150</guid> <description><![CDATA[Twitter has announced that it will soon open up a native photo sharing service. Rather than using an external service like Embed.ly to retrieve thumbnails, all the data is embedded within Twitter Entities. So, if you request a status using &#8220;include_entities=true&#8220;, you will be able to grab the image and display the thumbnail using the <a
href='http://shkspr.mobi/blog/index.php/2011/06/displaying-twitter-photos-via-entities/'>[...]</a>]]></description> <content:encoded><![CDATA[<p>Twitter has announced that it will soon open up a <a
href="http://groups.google.com/group/twitter-development-talk/browse_thread/thread/99b451ce5d8259ce#">native photo sharing service</a>.</p><p>Rather than using an external service like Embed.ly to retrieve thumbnails, all the data is embedded within <a
href="http://dev.twitter.com/pages/tweet_entities">Twitter Entities</a>.</p><p>So, if you request a status using &#8220;<em>include_entities=true</em>&#8220;, you will be able to grab the image and display the thumbnail using the following code.</p><div
class="geshi no php"><ol><li
class="li1"><div
class="de1"><span
class="kw2">function</span> twitter_get_media<span
class="br0">&#40;</span><span
class="re1">$status</span><span
class="br0">&#41;</span> <span
class="br0">&#123;</span></div></li><li
class="li1"><div
class="de1">&nbsp; &nbsp;<span
class="kw1">if</span><span
class="br0">&#40;</span><span
class="re1">$status</span><span
class="sy0">-&gt;</span><span
class="me1">entities</span><span
class="sy0">-&gt;</span><span
class="me1">media</span><span
class="br0">&#41;</span> <span
class="br0">&#123;</span></div></li><li
class="li1"><div
class="de1">&nbsp;</div></li><li
class="li1"><div
class="de1">&nbsp; &nbsp; &nbsp; <span
class="re1">$url</span> <span
class="sy0">=</span> <span
class="re1">$status</span><span
class="sy0">-&gt;</span><span
class="me1">entities</span><span
class="sy0">-&gt;</span><span
class="me1">media</span><span
class="br0">&#91;</span><span
class="nu0">0</span><span
class="br0">&#93;</span><span
class="sy0">-&gt;</span><span
class="me1">media_url_https</span><span
class="sy0">;</span></div></li><li
class="li1"><div
class="de1">&nbsp;</div></li><li
class="li1"><div
class="de1">&nbsp; &nbsp; &nbsp; <span
class="re1">$width</span> <span
class="sy0">=</span> <span
class="re1">$status</span><span
class="sy0">-&gt;</span><span
class="me1">entities</span><span
class="sy0">-&gt;</span><span
class="me1">media</span><span
class="br0">&#91;</span><span
class="nu0">0</span><span
class="br0">&#93;</span><span
class="sy0">-&gt;</span><span
class="me1">sizes</span><span
class="sy0">-&gt;</span><span
class="me1">thumb</span><span
class="sy0">-&gt;</span><span
class="me1">w</span><span
class="sy0">;</span></div></li><li
class="li1"><div
class="de1">&nbsp; &nbsp; &nbsp; <span
class="re1">$height</span> <span
class="sy0">=</span> <span
class="re1">$status</span><span
class="sy0">-&gt;</span><span
class="me1">entities</span><span
class="sy0">-&gt;</span><span
class="me1">media</span><span
class="br0">&#91;</span><span
class="nu0">0</span><span
class="br0">&#93;</span><span
class="sy0">-&gt;</span><span
class="me1">sizes</span><span
class="sy0">-&gt;</span><span
class="me1">thumb</span><span
class="sy0">-&gt;</span><span
class="me1">h</span><span
class="sy0">;</span></div></li><li
class="li1"><div
class="de1">&nbsp;</div></li><li
class="li1"><div
class="de1">&nbsp; &nbsp; &nbsp; <span
class="re1">$media_html</span> <span
class="sy0">=</span> <span
class="st0">&quot;&lt;a href=<span
class="es0">\&quot;</span>&quot;</span> <span
class="sy0">.</span> <span
class="re1">$url</span> <span
class="sy0">.</span> <span
class="st0">&quot;<span
class="es0">\&quot;</span> target=&#39;_blank&#39;&gt;&quot;</span><span
class="sy0">;</span></div></li><li
class="li1"><div
class="de1">&nbsp; &nbsp; &nbsp; <span
class="re1">$media_html</span> <span
class="sy0">.=</span> &nbsp;<span
class="st0">&quot;&lt;img src=<span
class="es0">\&quot;</span>&quot;</span> <span
class="sy0">.</span> <span
class="re1">$url</span> <span
class="sy0">.</span> <span
class="st0">&quot;:thumb<span
class="es0">\&quot;</span> width=<span
class="es0">\&quot;</span>&quot;</span> <span
class="sy0">.</span> <span
class="re1">$width</span> <span
class="sy0">.</span></div></li><li
class="li1"><div
class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span
class="st0">&quot;<span
class="es0">\&quot;</span> height=<span
class="es0">\&quot;</span>&quot;</span> <span
class="sy0">.</span> <span
class="re1">$height</span> <span
class="sy0">.</span> <span
class="st0">&quot;<span
class="es0">\&quot;</span> /&gt;&quot;</span><span
class="sy0">;</span></div></li><li
class="li1"><div
class="de1">&nbsp; &nbsp; &nbsp; <span
class="re1">$media_html</span> <span
class="sy0">.=</span> <span
class="st0">&quot;&lt;/a&gt;&lt;br /&gt;&quot;</span><span
class="sy0">;</span></div></li><li
class="li1"><div
class="de1">&nbsp; &nbsp; &nbsp;</div></li><li
class="li1"><div
class="de1">&nbsp; &nbsp; &nbsp; <span
class="kw1">return</span> <span
class="re1">$media_html</span><span
class="sy0">;</span></div></li><li
class="li1"><div
class="de1">&nbsp; &nbsp;<span
class="br0">&#125;</span> &nbsp; &nbsp; &nbsp; &nbsp;</div></li><li
class="li1"><div
class="de1"><span
class="br0">&#125;</span></div></li></ol></div><p>So, a tweet like this:<br
/> <style type='text/css'>#bbpBox_76360760606986241 a { text-decoration:none; color:#038543; }#bbpBox_76360760606986241 a:hover { text-decoration:underline; }</style><div
id='bbpBox_76360760606986241' class='bbpBox' style='padding:20px; margin:5px 0; background-color:#ACDED6; background-image:url(http://a1.twimg.com/images/themes/theme18/bg.gif); background-repeat:no-repeat'><div
style='background:#fff; padding:10px; margin:0; min-height:48px; color:#333333; -moz-border-radius:5px; -webkit-border-radius:5px;'><span
style='width:100%; font-size:18px; line-height:22px;'><a
href="http://twitter.com/search?q=%23Photos" title="#Photos">#Photos</a> on Twitter: taking flight <a
href="http://t.co/qbJx26r" rel="nofollow">http://t.co/qbJx26r</a></span><div
class='bbp-actions' style='font-size:12px; width:100%; padding:5px 0; margin:0 0 10px 0; border-bottom:1px solid #e6e6e6;'><img
align='middle' src='http://shkspr.mobi/blog/wp-content/plugins/twitter-blackbird-pie//images/bird.png' /><a
title='tweeted on 02/06/2011 18:53' href='http://twitter.com/#!/twitter/status/76360760606986241' target='_blank'>02/06/2011 18:53</a> via web<a
href='https://twitter.com/intent/tweet?in_reply_to=76360760606986241&related=https://twitter.com/edent' class='bbp-action bbp-reply-action' title='Reply'><span><em
style='margin-left: 1em;'></em><strong>Reply</strong></span></a><a
href='https://twitter.com/intent/retweet?tweet_id=76360760606986241&related=https://twitter.com/edent' class='bbp-action bbp-retweet-action' title='Retweet'><span><em
style='margin-left: 1em;'></em><strong>Retweet</strong></span></a><a
href='https://twitter.com/intent/favorite?tweet_id=76360760606986241&related=https://twitter.com/edent' class='bbp-action bbp-favorite-action' title='Favorite'><span><em
style='margin-left: 1em;'></em><strong>Favorite</strong></span></a></div><div
style='float:left; padding:0; margin:0'><a
href='http://twitter.com/intent/user?screen_name=twitter'><img
style='width:48px; height:48px; padding-right:7px; border:none; background:none; margin:0' src='http://a0.twimg.com/profile_images/1124040897/at-twitter_normal.png' /></a></div><div
style='float:left; padding:0; margin:0'><a
style='font-weight:bold' href='http://twitter.com/intent/user?screen_name=twitter'>@twitter</a><div
style='margin:0; padding-top:2px'>Twitter</div></div><div
style='clear:both'></div></div></div><br
/> Will render like this (in Dabr):<br
/> <img
src="http://shkspr.mobi/blog/wp-content/uploads/2011/06/Twitter-Dabr-Images.jpg" alt="Twitter Dabr Images" title="Twitter Dabr Images" width="317" height="528" class="aligncenter size-full wp-image-4154" /></p><h2>Notes</h2><p>This is very rough and ready proof of concept code.  Beware of the following:</p><ul><li>This will only take the first image from the tweet.</li><li>Only images are supported &#8211; I&#8217;m not sure how their proposed video sharing will work.</li><li>There&#8217;s no error checking.</li><li>In the above code, the https URL is used &#8211; if you want a non-SSL link, you&#8217;ll need to remove the &#8220;_https&#8221;</li></ul><p>Enjoy!</p><p><a
href="http://shkspr.mobi/blog/?flattrss_redirect&amp;id=4150&amp;md5=3e6ea664f76da8468cb1d87dd54edddd" title="Flattr" target="_blank"><img
src="http://shkspr.mobi/blog/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded> <wfw:commentRss>http://shkspr.mobi/blog/index.php/2011/06/displaying-twitter-photos-via-entities/feed/</wfw:commentRss> <slash:comments>3</slash:comments> <atom:link rel="payment" href="http://shkspr.mobi/blog/?flattrss_redirect&amp;id=4150&amp;md5=3e6ea664f76da8468cb1d87dd54edddd" type="text/html" /> </item> <item><title>A (Minor) Twitter Privacy Bug?</title><link>http://shkspr.mobi/blog/index.php/2011/05/a-minor-twitter-privacy-bug/</link> <comments>http://shkspr.mobi/blog/index.php/2011/05/a-minor-twitter-privacy-bug/#comments</comments> <pubDate>Mon, 09 May 2011 12:00:03 +0000</pubDate> <dc:creator>Terence Eden</dc:creator> <category><![CDATA[/etc/]]></category> <category><![CDATA[api]]></category> <category><![CDATA[https]]></category> <category><![CDATA[privacy]]></category> <category><![CDATA[security]]></category> <category><![CDATA[ssl]]></category> <category><![CDATA[twitter]]></category><guid
isPermaLink="false">http://shkspr.mobi/blog/?p=4045</guid> <description><![CDATA[Quick Summary Twitter&#8217;s secure API hides the contents of the tweets you are reading. But it doesn&#8217;t hide the images of those you converse with. Raised as Issue 2175. A Bit More Detail Twitter has a secure (HTTPS) and insecure (HTTP) API. When calling the secure API, all the content of the returned message (tweets) <a
href='http://shkspr.mobi/blog/index.php/2011/05/a-minor-twitter-privacy-bug/'>[...]</a>]]></description> <content:encoded><![CDATA[<h2>Quick Summary</h2><p>Twitter&#8217;s secure API hides the contents of the tweets you are reading. But it doesn&#8217;t hide the images of those you converse with.</p><p><a
href="http://code.google.com/p/twitter-api/issues/detail?id=2175">Raised as Issue 2175</a>.</p><h2>A Bit More Detail</h2><p>Twitter has a secure (HTTPS) and insecure (HTTP) API.</p><p>When calling the secure API, all the content of the returned message (tweets) are encrypted.  Eavesdroppers only see the cipher-text &#8211; essentially garbage.</p><p>However, within that cipher-text are links to <em>insecure</em> resources.</p><p>For example, a user requesting my tweets will get an object which contains a link to my avatar image.</p><p>Twitter is currently returning the <em>insecure</em> link:</p><pre>"profile_image_url" :
    "http://a2.twimg.com/profile_images/1283757621/Sketch_Avatar.jpg"</pre><p>Twitter should be returning the <em>secure</em> link:</p><pre>"profile_image_url" :
    "https://si0.twimg.com/profile_images/1283757621/Sketch_Avatar.jpg"</pre><h2>Exploiting This Weakness</h2><p>A user (Anna) will request the <em>encrypted</em> text of my tweets<br
/> She then requests the <em>unencrypted</em> image.<br
/> An eavesdropper (Eve) is listening in on the connection between Anna and Twitter.</p><pre>Anna ----&gt;Eve----&gt;Twitter  (Secure request)
Anna &lt;----Eve&lt;----Twitter  (Secure response)</pre><p>When Anna makes the initial request to Twitter, the malicious Eve can&#8217;t see what they&#8217;re talking about.</p><ul><li>The request &#8220;http<strong>s</strong>://example.com/twitter/edent&#8221; is itself encrypted.  Eve only sees an encrypted request to example.com &#8211; not &#8220;twitter/edent</li><li>The response containing all the tweets is also encrypted</li></ul><pre>Anna ----&gt;Eve----&gt;Images  (insecure request)
Anna &lt;----Eve&lt;----Twitter  (insecure response)
</pre><p>Anna then makes the subsequent request for the twitter user&#8217;s image, a malicious user can see</p><ul><li>The URI of the request.</li><li>The content of the image.</li></ul><h2>Impact</h2><p>Truth is, this has a pretty low security impact.</p><ul><li>There is no way to determine a user&#8217;s name based on the URI for their image. (Unless you already have both).</li><li>An eavesdropper has no way of knowing if the image is from the timeline, a reply, a DM, a search, a retweet, or the public timeline.</li><li>Images may be locally cached by the user&#8217;s browser &#8211; so frequency analysis isn&#8217;t reliable.</li><li>A malicious user <em>could</em> alter the image in transit.</li></ul><p>Worst case scenario is that if a malicious man-in-the-middle knows which images relate to which Twitter users, they know the intercepted user has seen at least one tweet from that user.</p><p>Let&#8217;s say Anna is communicating with Bob.  Eve is trying to eavesdrop.<br
/> If Bob has never tweeted, and Eve sees repeated requests from Anna for Bob&#8217;s avatar, she may reasonably surmise that they are exchanging DMs.</p><h2>Overall</h2><p>This is a pretty low-impact privacy risk.<br
/> It can be fixed by Twitter&#8217;s API returning HTTPS URIs where possible.<br
/> In the meantime, developers can replace &#8220;http://a2.twimg.com/&#8221; with &#8220;https://si0.twimg.com&#8221;.</p><p><a
href="http://shkspr.mobi/blog/?flattrss_redirect&amp;id=4045&amp;md5=58b67a9f7c54e43b59a6489ce9e20d8b" title="Flattr" target="_blank"><img
src="http://shkspr.mobi/blog/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded> <wfw:commentRss>http://shkspr.mobi/blog/index.php/2011/05/a-minor-twitter-privacy-bug/feed/</wfw:commentRss> <slash:comments>1</slash:comments> <atom:link rel="payment" href="http://shkspr.mobi/blog/?flattrss_redirect&amp;id=4045&amp;md5=58b67a9f7c54e43b59a6489ce9e20d8b" type="text/html" /> </item> <item><title>Dabr, Dabr, Everywhere&#8230;</title><link>http://shkspr.mobi/blog/index.php/2011/03/dabr-dabr-everywhere/</link> <comments>http://shkspr.mobi/blog/index.php/2011/03/dabr-dabr-everywhere/#comments</comments> <pubDate>Fri, 25 Mar 2011 11:30:35 +0000</pubDate> <dc:creator>Terence Eden</dc:creator> <category><![CDATA[mobile]]></category> <category><![CDATA[dabr]]></category> <category><![CDATA[twitter]]></category><guid
isPermaLink="false">http://shkspr.mobi/blog/?p=3763</guid> <description><![CDATA[I contribute code to Dabr &#8211; a mobile twitter client. It&#8217;s a great project to keep my hand in the world of PHP, APIs, SVN, and all the other tools that are essential to the modern online world. Dabr&#8217;s strength for developers is two-fold Dead easy to install. Unzip the files, fill in your API <a
href='http://shkspr.mobi/blog/index.php/2011/03/dabr-dabr-everywhere/'>[...]</a>]]></description> <content:encoded><![CDATA[<p>I contribute code to<a
href="http://code.google.com/p/dabr/"> Dabr &#8211; a mobile twitter client</a>.  It&#8217;s a great project to keep my hand in the world of PHP, APIs, SVN, and all the other tools that are essential to the modern online world.</p><p>Dabr&#8217;s strength for developers is two-fold</p><ol><li>Dead easy to install.  Unzip the files, fill in your API key(s), upload, done.</li><li>It&#8217;s under an incredibly permissive Open Source <a
href="http://www.opensource.org/licenses/mit-license.php">MIT License</a>. Essentially anyone can do anything with the code and they don&#8217;t need to ask permission, nor contribute anything back to the code base.</li></ol><p>It&#8217;s a really popular tool.  Although it&#8217;s hard to count how many users are on the main Dabr server &#8211; not to mention all the clones &#8211; it&#8217;s obvious that many people find it an indispensable way to access Twitter.</p><p>According to the New York Times, <a
href="http://6thfloor.blogs.nytimes.com/2011/03/24/a-better-way-to-measure-twitter-influence/">Rafinha Bastos is the most influential person on Twitter</a>.  Guess what client he uses?<br
/> <img
src="https://shkspr.mobi/blog/wp-content/uploads/2011/03/rafinhabastos-uses-Dabr.jpg" alt="rafinhabastos uses Dabr" title="rafinhabastos uses Dabr" width="345" height="769" class="aligncenter size-full wp-image-3772" /><br
/> <span
id="more-3763"></span><br
/> So, with a kick-arse product and no silly &#8220;Intellectual Property&#8221; restrictions, we have let a thousand flowers bloom. There are clients deployed all over the world.  Including on my secure server &#8211; <a
href="https://shkspr.mobi/dabr/">SSL Dabr</a>.  And here&#8217;s one more&#8230;</p><h2>Welcome UberSocial!</h2><p>The most recent flower is <a
href="http://www.ubersocial.com/">UberSocial</a>. As well as having the most popular BlackBerry Twitter client, and an iPhone client &#8211; they&#8217;ve now beta-launched a <a
href="http://m.ubersocial.com/">mobile web client</a> &#8211; based on Dabr!</p><p><img
class="alignleft size-full wp-image-3764" title="munch_2011_03_24_153355" src="https://shkspr.mobi/blog/wp-content/uploads/2011/03/munch_2011_03_24_153355.jpg" alt="UberSocial Dabr" width="252" height="336" /><img
class="alignright size-full wp-image-3765" title="munch_2011_03_24_153106" src="https://shkspr.mobi/blog/wp-content/uploads/2011/03/munch_2011_03_24_153106.jpg" alt="UberSocial Dabr" width="252" height="336" /></p><div
style="clear: both"> It looks like UberSocial are running a slightly out of date version of the code &#8211; but I&#8217;m sure they&#8217;ll be up to the latest version shortly.</div><p>I&#8217;m really excited to see Dabr spreading far and wide.  The intention &#8211; for me &#8211; has never been to make pots of money from it.  The adverts on <a
href="https://shkspr.mobi/dabr/">SSL Dabr</a> just about cover the hosting costs.</p><p>What I like seeing is my code being used far and wide &#8211; and helping people.  I know it&#8217;s corny, but seeing my code being used by Twitter users in Egypt during the uprising was overwhelming.  In a tiny, almost insignificant way, I helped.</p><p>I don&#8217;t think my coding is good enough to get something into a really important project &#8211; like <a
href="http://www.kernel.org/">the Linux Kernel</a>, or <a
href="http://spaceflight.nasa.gov/station/index.html">the International Space Station</a> &#8211; but seeing millions of users is personally edifying.</p><p>So, long live Open Source and long live Dabr!</p><p><a
href="http://shkspr.mobi/blog/?flattrss_redirect&amp;id=3763&amp;md5=a6a1f23d03ea9dbcd1146658c9243d99" title="Flattr" target="_blank"><img
src="http://shkspr.mobi/blog/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded> <wfw:commentRss>http://shkspr.mobi/blog/index.php/2011/03/dabr-dabr-everywhere/feed/</wfw:commentRss> <slash:comments>1</slash:comments> <atom:link rel="payment" href="http://shkspr.mobi/blog/?flattrss_redirect&amp;id=3763&amp;md5=a6a1f23d03ea9dbcd1146658c9243d99" type="text/html" /> </item> <item><title>#WeLoveBaskers</title><link>http://shkspr.mobi/blog/index.php/2011/02/baskers/</link> <comments>http://shkspr.mobi/blog/index.php/2011/02/baskers/#comments</comments> <pubDate>Wed, 09 Feb 2011 13:00:13 +0000</pubDate> <dc:creator>Terence Eden</dc:creator> <category><![CDATA[/etc/]]></category> <category><![CDATA[baskers]]></category> <category><![CDATA[bullies]]></category> <category><![CDATA[cyber bullying]]></category> <category><![CDATA[dailymail]]></category> <category><![CDATA[newspapers]]></category> <category><![CDATA[rants]]></category> <category><![CDATA[twitter]]></category> <category><![CDATA[welovebaskers]]></category><guid
isPermaLink="false">http://shkspr.mobi/blog/?p=3609</guid> <description><![CDATA[I have twice been subject to some very inept blackmail over a posts I had made on twitter. The first time was after I called a particularly nasty company &#8220;twunts&#8221; over a dispute I&#8217;d had with them. I&#8217;ll be the first to admit that it wasn&#8217;t a particularly mature reaction &#8211; but I&#8217;m not sure <a
href='http://shkspr.mobi/blog/index.php/2011/02/baskers/'>[...]</a>]]></description> <content:encoded><![CDATA[<p><a
href="http://ckasurak.blogspot.com/2010/05/revisiting-cyber-bullying.html" class="broken_link"><img
src="http://shkspr.mobi/blog/wp-content/uploads/2011/02/cyberbully_new_web.jpg" alt="Image by Chris Kasurak - under a Creative Commons Attribution, non-commercial, share-alike license" title="cyberbully_new_web" width="250" height="271" class="aligncenter size-full wp-image-3619" /></a><br
/> I have twice been subject to some very inept blackmail over a posts I had made on twitter.</p><p>The first time was after I called a particularly nasty company &#8220;twunts&#8221; over a dispute I&#8217;d had with them.  I&#8217;ll be the first to admit that it wasn&#8217;t a particularly mature reaction &#8211; but I&#8217;m not sure it warranted taking a screenshot of the tweet, threatening to show it to the CEO of the company I worked for, then continually calling the company to complain about me.  I was a private citizen, not tweeting on behalf of his employer.  Luckily, my employers were very good about it and supported me.  There is no small measure of schadenfreude when I read about my blackmailers current protracted legal difficulties.</p><p>The second time was rather different &#8211; and in many ways nastier.  I was at a private function and twitpic&#8217;d a photo of a (very) minor celebrity.  I was immediately contacted by his PR team saying &#8220;please don&#8217;t tweet anything he says &#8211; it&#8217;s a private event.&#8221;  Not a problem for me, I emailed back saying I&#8217;d keep schtum.<br
/> A few weeks later, I got hauled over the coals and threatened by his &#8220;team&#8221; for &#8220;invading his privacy&#8221; and &#8220;endangering him by revealing his location.&#8221;  All over a blurry twitpic which, if they&#8217;d asked at the time, I would gladly have removed.  Again, threats were made to me about the consequences of my tweets.</p><p>Both tweets have now been deleted.</p><p>All of which has left me with a rather sour outlook.  I now think twice before I tweet anything.  Who knows what innocent, flippant, or satirical content can be taken, twisted out of context and then used against you?</p><h2>#welovebaskers</h2><p>All of which brings me, in a round about way, to a <em>cause célèbre</em> on twitter &#8211; @<a
href="http://baskersworld.wordpress.com/">Baskers</a>.  I&#8217;ve met her a couple of times at social occasions, but I wouldn&#8217;t say I knew her well.  Even though enough has been written about her to fill a book, but I&#8217;d like to add my tuppenceworth.</p><p>It would be the height of egocentricity to claim my experiences were anything like hers.  I&#8217;ve neither been pilloried in the press nor caused my employers publicly defend me.</p><p>But there is a similarity.  We are both victims of bullying.  It took me a little while to realise this but, since doing so, it has made the world a lot clearer.</p><p>@Baskers was the victim of <a
href="http://www.guardian.co.uk/society/patrick-butler-cuts-blog/2010/nov/15/baskers-time-for-abuse-to-stop">a vicious and petty bullying campaign in two national newspapers</a>.</p><p>Perhaps she got picked on because she&#8217;s a smart and successful woman.  Bullies hate those more successful than themselves.<br
/> Was it because she is witty, intelligent, and able to eloquently express her opinion that lead her to be despised by talentless hacks?<br
/> Or, as is so often, was she a victim of someone who can only make themselves feel good about their pathetic and wretched life by randomly lashing out at a weaker target?</p><p>Whatever the reasons, it&#8217;s abuse.  Using a position of power to bully someone who can&#8217;t respond on the same scale is disgusting &#8211; especially from papers which claim to be against bullying.</p><h2>What Should We Do About Bullying?</h2><p>I was told by countless teachers that you should ignore bullies and eventually they go away.  That may well be true for some childhood scrapes &#8211; but removing oneself from the vengeful eye of the gutter press isn&#8217;t just as simple as closing the curtains and hoping they go away &#8211; as <a
href="http://girlwithaonetrackmind.blogspot.com/2006/08/response.html">Zoe Margolis found out</a>.</p><p>So, can we go down the &#8220;official&#8221; routes to complain?  Sadly, the game is rigged.</p><p>In the case of the UK&#8217;s legal system &#8211; the costs are prohibitive, the players all work against you, the rules are obscure, and even if you win &#8211; you&#8217;re still tainted by association and may not recover your costs.</p><p>In the case of the the <a
href="http://www.pcc.org.uk/">Press Complaints Commission</a> the game is so one sided that you stand virtually no chance of success.</p><ul><li>The body you complain to is populated with <a
href="http://www.pcc.org.uk/about/whoswho/members.html">senior members of the UK&#8217;s newspaper industry</a> &#8211; so very little chance of a fair or impartial hearing.</li><li>The PCC limit the scope of the complaints you can make about their members.</li><li> If a newspaper doesn&#8217;t like the way the PCC timidly pursues it &#8211; they can simply <a
href="http://tabloid-watch.blogspot.com/2011/01/pcc-drops-outstanding-complaints.html">leave the PCC and have all cases against them dropped</a>.</li><li> The chair of the PCC, on the basis of <a
href="http://www.bbc.co.uk/journalism/blog/2011/02/writing-on-the-wall.shtml">this BBC interview</a>, is unrepentant in her stewardship of such an obviously incompetent authority.</li></ul><p>Unsurprisingly, <a
href="http://www.pcc.org.uk/news/index.html?article=NjkzNA==">the PCC once again looked after their members&#8217; interests</a>.</p><h2>Revenge?</h2><p>But what can we do?  How do we stop these hideous cyber-bullies?</p><p>It&#8217;s tempting to think of revenge.  It&#8217;s a basic human instinct.  I&#8217;m salivating at the thought of extracting retribution &#8211; both on my behalf and by proxy for @Baskers.  I&#8217;d love to set a pack of ravenous paparazzi on the editors of those newspapers and hound them until they couldn&#8217;t take it any more.  I&#8217;d love to fill the pages of other newspapers with a long exposé of their reports weird sexual habits (as an aside, <a
href="https://secure2.subscribeonline.co.uk/PEYE/subscription.cfm">subscribe to Private Eye</a> and read <a
href="http://www.private-eye.co.uk/sections.php?section_link=street_of_shame&#038;">Street of Shame</a> &#8211; they&#8217;re the only paper which reports on other papers).<br
/> I want to set up website detailing every miss-step a journalist has ever made &#8211; and SEO it so that when potential employers search for them, all they find is the very worst.<br
/> I want parody twitter accounts dedicated to making them a laughing stock.</p><p>I&#8217;d love to watch newspaper editors and journalists in utter despair as their children come home weeping because of what the other kids are saying about their mummy or daddy.</p><p>And that&#8217;s why revenge is wrong.  It&#8217;s morally wrong to stoop to their level.  Hurting other people just traps you in a cycle of violence.  Revenge is usually indiscriminate and hurts far more than the target.<br
/> Besides, as they say, &#8220;never fight with a pig. You both end up covered in shit &#8211; but the pig likes it.&#8221;</p><p>I&#8217;m not saying we should passively resist them.  We can&#8217;t let them beat up our friends and hope they get tired and go away.  We can&#8217;t simply watch bullying ruin life after life.  We can&#8217;t close our eyes and wish for the best.</p><h2>What Can We Do?</h2><p>I&#8217;m a hippy.  I think it&#8217;s up to us to take a stand in what we believe in.  To be the better person.  Ultimately, to forgive and show the bullies that there is a better way.</p><p>I&#8217;m inspired by <a
href="http://theforgivenessproject.com/stories/michael-lapsley-south-africa/">Michael Lapsley</a> &#8211; my wife&#8217;s uncle &#8211; and the work of <a
href="http://theforgivenessproject.com/">The Forgiveness Project</a>.  Michael, and the others on the site, have managed to find forgiveness for those who have done them dreadful wrongs.<br
/> I can&#8217;t even begin to compare Michael&#8217;s horrific and permanent injuries to the next-day&#8217;s-chip-paper assaults on members of our community.  Although I do know the mental scarring from bullying can be as painful as anything which can be done to our bodies.</p><p>Reading through the stories on the site one thing becomes clear.  It&#8217;s important for both parties to understand each other.  To understand where the pain comes from and why it was dished out so callously.</p><p>I don&#8217;t know how we make this happen.  I don&#8217;t know whether it&#8217;s as simple as inviting Quentin Letts out for a drink. Chatting with him and letting him see what pain he has wrought.  Is it a case of &#8220;adopting&#8221; a journalist and showing them how twitter works &#8211; and helping them make friends?</p><p>How do we reach out to these bullies?  How do we show them that they don&#8217;t need to fear us?  How do we make them understand that their words have consequences?  How can we make them see that picking on people isn&#8217;t big, and it isn&#8217;t clever?</p><p>I don&#8217;t want (some) newspapers and (some) blogs trying to ruin the lives of those who have caused them no harm.  Is that really an impossible task?</p><p><a
href="http://shkspr.mobi/blog/?flattrss_redirect&amp;id=3609&amp;md5=d21bccf6fd578b48f88db345b1bbdcf3" title="Flattr" target="_blank"><img
src="http://shkspr.mobi/blog/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded> <wfw:commentRss>http://shkspr.mobi/blog/index.php/2011/02/baskers/feed/</wfw:commentRss> <slash:comments>5</slash:comments> <atom:link rel="payment" href="http://shkspr.mobi/blog/?flattrss_redirect&amp;id=3609&amp;md5=d21bccf6fd578b48f88db345b1bbdcf3" type="text/html" /> </item> <item><title>OAuth Will Murder Your Children &#8211; for one week only!</title><link>http://shkspr.mobi/blog/index.php/2011/01/oauth-will-murder-your-children-for-one-week-only/</link> <comments>http://shkspr.mobi/blog/index.php/2011/01/oauth-will-murder-your-children-for-one-week-only/#comments</comments> <pubDate>Wed, 26 Jan 2011 15:39:34 +0000</pubDate> <dc:creator>Terence Eden</dc:creator> <category><![CDATA[usability]]></category> <category><![CDATA[oauth]]></category> <category><![CDATA[security]]></category> <category><![CDATA[twitter]]></category><guid
isPermaLink="false">http://shkspr.mobi/blog/?p=3508</guid> <description><![CDATA[Why doesn&#8217;t Twitter&#8217;s OAuth let me specify the length of time a 3rd party has access to my account? Take a look at all the crap you&#8217;ve given access to your Twitter account. Are you ever going to use that &#8220;See how many of your friends like cheese&#8221; app again? No. Long time readers will <a
href='http://shkspr.mobi/blog/index.php/2011/01/oauth-will-murder-your-children-for-one-week-only/'>[...]</a>]]></description> <content:encoded><![CDATA[<p>Why doesn&#8217;t Twitter&#8217;s OAuth let me specify the length of time a 3rd party has access to my account?  Take a look at <a
href="http://twitter.com/settings/connections">all the crap you&#8217;ve given access to your Twitter account</a>.  Are you <em>ever</em> going to use that &#8220;See how many of your friends like cheese&#8221; app again? No.</p><p>Long time readers will know that I have <a
href="http://shkspr.mobi/blog/index.php/2009/11/twitter-oauth-and-passwords-oh-my/"> some severe usability and security concerns with Twitter&#8217;s OAuth implementation</a>.  See also <a
href="http://www.theregister.co.uk/2009/11/04/oauth_dark_side/">my interview in The Register</a>.</p><p>Zach Holman has <a
href="http://zachholman.com/2011/01/oauth_will_murder_your_children/">an entertaining and informative blog post about giving Twitter applications fine grained controls</a>.</p><p>Essentially, he&#8217;s saying that you should be able to authorise an app for <em>just</em> posting, for example.<br
/> Here&#8217;s his graphic which I&#8217;ve stolen.<br
/> <a
href="http://zachholman.com/2011/01/oauth_will_murder_your_children/"><img
src="http://shkspr.mobi/blog/wp-content/uploads/2011/01/kanye-stopped-300x238.png" alt="Fine Grained Access Controls" title="kanye-stopped" width="300" height="238" class="aligncenter size-medium wp-image-3513" /></a></p><p>This doesn&#8217;t go far enough.</p><p>I was taking a look at this <a
href="http://inmaps.linkedinlabs.com/">LinkedIn application which graphs your contacts</a>.</p><p>Take a look at their OAuth screen.</p><p><img
src="http://shkspr.mobi/blog/wp-content/uploads/2011/01/Access-Duration.png" alt="Access Duration" title="Access Duration" width="521" height="418" class="aligncenter size-full wp-image-3509" /></p><p>At the bottom is an &#8220;Access Duration&#8221; option &#8211; giving you the option to try out the app and have it automatically revoke after a specified period of time.</p><p>Now, this isn&#8217;t something you&#8217;d want to do for every app. But it gives you a method to limit the damage that a malicious app can do.  Remember, just because an app isn&#8217;t malicious today, doesn&#8217;t give you any guarantee about its future performance.</p><p>As it happens, the Oauth Specification 2.0 has this to say in section <a
href="http://tools.ietf.org/html/draft-ietf-oauth-v2-12#section-4.2">4.2.2. Access Token Response</a></p><pre>
expires_in
         OPTIONAL.  The duration in seconds of the access token
         lifetime.  For example, the value "3600" denotes that the
         access token will expire in one hour from the time the response
         was generated.
</pre><p>If you run a service relying on OAuth, please consider giving users an Access Duration option.</p><p><a
href="http://shkspr.mobi/blog/?flattrss_redirect&amp;id=3508&amp;md5=5b3f92d873a758bbbbb60c4d4d4eebf0" title="Flattr" target="_blank"><img
src="http://shkspr.mobi/blog/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded> <wfw:commentRss>http://shkspr.mobi/blog/index.php/2011/01/oauth-will-murder-your-children-for-one-week-only/feed/</wfw:commentRss> <slash:comments>0</slash:comments> <atom:link rel="payment" href="http://shkspr.mobi/blog/?flattrss_redirect&amp;id=3508&amp;md5=5b3f92d873a758bbbbb60c4d4d4eebf0" type="text/html" /> </item> <item><title>Share Android Apps on Twitter (or anywhere else)</title><link>http://shkspr.mobi/blog/index.php/2010/07/share-android-apps-on-twitter-or-anywhere-else/</link> <comments>http://shkspr.mobi/blog/index.php/2010/07/share-android-apps-on-twitter-or-anywhere-else/#comments</comments> <pubDate>Tue, 20 Jul 2010 09:41:43 +0000</pubDate> <dc:creator>Terence Eden</dc:creator> <category><![CDATA[mobile]]></category> <category><![CDATA[android]]></category> <category><![CDATA[api]]></category> <category><![CDATA[sdk]]></category> <category><![CDATA[sharing]]></category> <category><![CDATA[sharing is caring]]></category> <category><![CDATA[twitter]]></category><guid
isPermaLink="false">http://shkspr.mobi/blog/?p=2172</guid> <description><![CDATA[I attended the Mobile Monday meeting &#8220;200,000 Apps &#8211; Where&#8217;s Mine&#8221; last night. One thing that became clear is that apps don&#8217;t do a very good job of promoting themselves. One crippling problems with most app stores is that there&#8217;s no (easy) way to share an app with a friend. Here&#8217;s some basic code for <a
href='http://shkspr.mobi/blog/index.php/2010/07/share-android-apps-on-twitter-or-anywhere-else/'>[...]</a>]]></description> <content:encoded><![CDATA[<p>I attended the Mobile Monday meeting &#8220;<a
href="http://www.ibegyourparton.co.uk/2010/07/20/mobile-monday-london-write-up-%E2%80%93-%E2%80%9C200000-apps-where%E2%80%99s-mine%E2%80%9D/" class="broken_link">200,000 Apps &#8211; Where&#8217;s Mine</a>&#8221; last night.<br
/> One thing that became clear is that apps don&#8217;t do a very good job of promoting themselves.  One crippling problems with most app stores is that there&#8217;s no (easy) way to share an app with a friend.</p><p>Here&#8217;s some basic code for an Android app which will post the URL of your app to Twitter.  Stick it in a button or menu item for easy sharing.</p><div
class="geshi no java"><ol><li
class="li1"><div
class="de1"><span
class="kw3">String</span> twitterUri = <span
class="st0">&quot;http://m.twitter.com/?status=&quot;</span><span
class="sy0">;</span></div></li><li
class="li1"><div
class="de1"><span
class="kw3">String</span> marketUri = Uri.<span
class="me1">encode</span><span
class="br0">&#40;</span><span
class="st0">&quot;http://example.com/?q=app&amp;amp;title=test&quot;</span><span
class="br0">&#41;</span><span
class="sy0">;</span></div></li><li
class="li1"><div
class="de1">Intent shareOnTwitterIntent = <span
class="kw2">new</span> Intent<span
class="br0">&#40;</span>Intent.<span
class="me1">ACTION_VIEW</span>, Uri.<span
class="me1">parse</span><span
class="br0">&#40;</span>twitterUri + marketUri<span
class="br0">&#41;</span><span
class="br0">&#41;</span><span
class="sy0">;</span></div></li><li
class="li1"><div
class="de1">startActivity<span
class="br0">&#40;</span>shareOnTwitterIntent<span
class="br0">&#41;</span><span
class="sy0">;</span></div></li></ol></div><p>Some important things to note.</p><ol><li>This is set to post to the <em>mobile </em>version of Twitter.  Your user is on a phone &#8211; don&#8217;t direct them to a site that won&#8217;t work on their device.</li><li>The second string is <a
href="http://en.wikipedia.org/wiki/Percent-encoding">URI encoded</a>.</li><li>Consider if you want to post a &#8220;market://&#8221; link.  I would advise against it.  Twitter won&#8217;t render it as a link and, even if it did, 90% of users won&#8217;t be able to click on it.  Make it a link that will direct desktop users to your website, mobile users to a mobile friendly site and Android users direct to the market.</li></ol><p>Facebook also has an <a
href="http://www.facebook.com/share/">API</a> for this sort of sharing.</p><pre>

http://m.facebook.com/sharer.php?u=example.com&#038;t=test
</pre><p>Again, it points to the mobile site and needs to be URL encoded.</p><p>Happy sharing!</p><p><a
href="http://shkspr.mobi/blog/?flattrss_redirect&amp;id=2172&amp;md5=53bfecec5b40f562ee7c4422e0e41d66" title="Flattr" target="_blank"><img
src="http://shkspr.mobi/blog/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded> <wfw:commentRss>http://shkspr.mobi/blog/index.php/2010/07/share-android-apps-on-twitter-or-anywhere-else/feed/</wfw:commentRss> <slash:comments>3</slash:comments> <atom:link rel="payment" href="http://shkspr.mobi/blog/?flattrss_redirect&amp;id=2172&amp;md5=53bfecec5b40f562ee7c4422e0e41d66" type="text/html" /> </item> <item><title>Twitter API &#8211; pagination and IDs</title><link>http://shkspr.mobi/blog/index.php/2010/06/twitter-api-pagination-and-ids/</link> <comments>http://shkspr.mobi/blog/index.php/2010/06/twitter-api-pagination-and-ids/#comments</comments> <pubDate>Sun, 27 Jun 2010 07:54:36 +0000</pubDate> <dc:creator>Terence Eden</dc:creator> <category><![CDATA[/etc/]]></category> <category><![CDATA[api]]></category> <category><![CDATA[dabr]]></category> <category><![CDATA[twitter]]></category><guid
isPermaLink="false">http://shkspr.mobi/blog/?p=2121</guid> <description><![CDATA[Looking for some Twitter API help.  Bit of a geeky post, this&#8230; Pagination is the act of splitting data into logical  pages. Suppose I had a list of item, numbered 0 &#8211; 99.  If I want 20 items per page, it&#8217;s trivial to see that pagination looks like: p1 = 0-19 p2 = 20-40 p3 <a
href='http://shkspr.mobi/blog/index.php/2010/06/twitter-api-pagination-and-ids/'>[...]</a>]]></description> <content:encoded><![CDATA[<p>Looking for some Twitter API help.  Bit of a geeky post, this&#8230;</p><p>Pagination is the act of splitting data into logical  pages. Suppose I had a list of item, numbered 0 &#8211; 99.  If I want 20 items per page, it&#8217;s trivial to see that pagination looks like:</p><pre>p1 = 0-19
p2 = 20-40
p3 = 41-61
p4 = 62-82
p5 = 83-99
</pre><p>If I wanted to start at, say, page 55 &#8211; pagination would look like:</p><pre>p1 = 55-75
p2 = 76-96
p3 = 97-99</pre><p>Easy, right?  So why am I telling you this?</p><h2>Twitter Timeline</h2><p>Imagine that those items are Twitter Status ID.  Each one represents a tweet in your timeline.</p><p>Twitter will allow us to &#8220;page&#8221; back and forth through our timeline. If we say status ID 80 is the most recent post in our timeline, and we want to see 20 tweets at a time, pagination would look like this.</p><pre>p1 = 80-60
p2 = 60-40
... etc.</pre><p>Normally, that would be fine.</p><p>The only issue is that friends are posting <em>all the time</em>.  Imagine we start with tweets 80-60.  We go to page 2, but in the meantime, 5 new tweets have been made.</p><pre>p1 = 80-60
p2 = 65-45</pre><p>The user sees 5 tweets she has already read.  Not desirable.</p><p>If 20 tweets had been made before clicking on the &#8220;next&#8221; button, this is what happens.</p><pre>p1 = 80-60
p2 = 80-60</pre><h2>Max_ID To The Rescue (AKA, the easy bit)</h2><p>Luckily, Twitter allows us to use a max_id parameter in our API calls.  This says &#8220;Get the tweets <strong>older</strong> than this number.&#8221;</p><pre>http://api.twitter.com/1/statuses/home_timeline.json?max_id=123465789</pre><p>So, using max_id we can ensure that the user never has to read the same tweet twice.  Instead of dumbly using pages, we call the specific tweets we want.</p><pre><span style="text-decoration: line-through;">p1</span> max_id=80 = 80-60</pre><pre><span style="text-decoration: line-through;">p2</span> max_id=60 = 60-40</pre><p>Easy!  We just use the oldest tweet on the page as the max_id parameter when we call the next page.</p><h2>Looking To The Future (AKA, where it all goes horribly wrong)</h2><p>So far, we&#8217;ve looked at stepping back in time.  Seeing older tweets.  Suppose we want to see newer tweets?</p><p>Twitter provides us with a since_id parameter for API calls.  This says &#8220;Get the tweets <strong>newer</strong> than this number.&#8221;</p><p>Unfortunately, it doesn&#8217;t work.  Well, it <em>works</em> but not the way I expected it to!</p><p>Suppose our user is deep down in her tweets, this is how I would expect since_id to work</p><pre>max_id=60  = 60-40</pre><pre> (So, let's show any more recent tweets)</pre><pre>since_id=60 = 80-60</pre><p>We see the 20 tweets that occured <em>since</em> the since_id.  Right?  Wrong!  This is what happens?</p><pre>max_id=60  = 60-40</pre><pre>(So, let's show any more recent tweets)</pre><pre>since_id=60 = 100-80</pre><p><strong>What?</strong></p><h2>An Explanation</h2><p>The since_id retrieves tweets <em>starting with the most recent</em>.  It stops when it reaches the since_id.</p><p>I don&#8217;t know the max_id that I&#8217;m looking for, so I can&#8217;t call that.</p><p>I could call the most recent 200 tweets and look for the 20 I need.  That&#8217;s wasteful in terms of bandwidth and processing &#8211; there&#8217;s also no guarantee that the since_id will be in there.</p><p>So, I have a problem.  The &#8220;Older&#8221; link in my Twitter application will work.  The &#8220;Newer&#8221; links won&#8217;t.</p><p>Any suggestions?</p><p><a
href="http://shkspr.mobi/blog/?flattrss_redirect&amp;id=2121&amp;md5=93574a165e925710efeff37e057cc2ac" title="Flattr" target="_blank"><img
src="http://shkspr.mobi/blog/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded> <wfw:commentRss>http://shkspr.mobi/blog/index.php/2010/06/twitter-api-pagination-and-ids/feed/</wfw:commentRss> <slash:comments>8</slash:comments> <atom:link rel="payment" href="http://shkspr.mobi/blog/?flattrss_redirect&amp;id=2121&amp;md5=93574a165e925710efeff37e057cc2ac" type="text/html" /> </item> <item><title>HOWTO: Twitpic and OAuth</title><link>http://shkspr.mobi/blog/index.php/2010/05/howto-twitpic-and-oauth/</link> <comments>http://shkspr.mobi/blog/index.php/2010/05/howto-twitpic-and-oauth/#comments</comments> <pubDate>Mon, 31 May 2010 17:07:29 +0000</pubDate> <dc:creator>Terence Eden</dc:creator> <category><![CDATA[/etc/]]></category> <category><![CDATA[dabr]]></category> <category><![CDATA[howto]]></category> <category><![CDATA[oauth]]></category> <category><![CDATA[php]]></category> <category><![CDATA[twitpic]]></category> <category><![CDATA[twitter]]></category><guid
isPermaLink="false">http://shkspr.mobi/blog/?p=2084</guid> <description><![CDATA[I am no longer confused! Here is a quick tutorial in how to post images to Twitpic and Twitter when using OAuth. I&#8217;m indebted to Steve Corona of Twitpic, for his help with this. You can see the full code on Dabr&#8217;s Google Code page. First of all, you&#8217;ll need to have enabled OAuth for <a
href='http://shkspr.mobi/blog/index.php/2010/05/howto-twitpic-and-oauth/'>[...]</a>]]></description> <content:encoded><![CDATA[<p>I am no longer <a
href="http://shkspr.mobi/blog/index.php/2010/05/twitpic-oauth-im-stuck">confused</a>!  Here is a quick tutorial in how to post images to Twitpic and Twitter when using OAuth.  I&#8217;m indebted to <a
href="http://twitter.com/stevencorona">Steve Corona of Twitpic</a>, for his help with this.</p><p>You can see the full code on <a
href="http://code.google.com/p/dabr/source/detail?r=318">Dabr&#8217;s Google Code page</a>.</p><p>First of all, you&#8217;ll need to have enabled OAuth for your Twitter client.  I use Abraham&#8217;s excellent <a
href="http://github.com/abraham/twitteroauth/tree/master/twitteroauth/">OAuth libraries for PHP</a>.</p><p>This tutorial assumes you already have OAuth working.  I&#8217;ll attempt to explain what I&#8217;m doing as I go along &#8211; but the code should be pretty readable.</p><p>Start by reading the <a
href="http://dev.twitpic.com/docs/2/upload/">Twitpic API documentation</a>.  You will also need to <a
href="http://dev.twitpic.com/apps/new">register for an API key</a> &#8211; this only takes a few seconds.</p><p>We start by setting CURL&#8217;s headers to those required by Twitpic</p><div
class="geshi no php"><ol><li
class="li1"><div
class="de1"><span
class="co1">//Has the user submitted an image and message?</span></div></li><li
class="li1"><div
class="de1"><span
class="kw1">if</span> <span
class="br0">&#40;</span><span
class="re1">$_POST</span><span
class="br0">&#91;</span><span
class="st0">&#39;message&#39;</span><span
class="br0">&#93;</span><span
class="br0">&#41;</span></div></li><li
class="li1"><div
class="de1"><span
class="br0">&#123;</span></div></li><li
class="li1"><div
class="de1">&nbsp;<span
class="re1">$twitpicURL</span> <span
class="sy0">=</span> <span
class="st0">&#39;http://api.twitpic.com/2/upload.json&#39;</span><span
class="sy0">;</span></div></li><li
class="li1"><div
class="de1">&nbsp;</div></li><li
class="li1"><div
class="de1">&nbsp;<span
class="co1">//Set the initial headers</span></div></li><li
class="li1"><div
class="de1">&nbsp;<span
class="re1">$header</span> <span
class="sy0">=</span> <span
class="kw3">array</span><span
class="br0">&#40;</span></div></li><li
class="li1"><div
class="de1">&nbsp; &nbsp; &nbsp; &nbsp;<span
class="st0">&#39;X-Auth-Service-Provider: https://api.twitter.com/1/account/verify_credentials.json&#39;</span><span
class="sy0">,</span></div></li><li
class="li1"><div
class="de1">&nbsp; &nbsp; &nbsp; &nbsp;<span
class="st0">&#39;X-Verify-Credentials-Authorization: OAuth realm=&quot;http://api.twitter.com/&quot;&#39;</span></div></li><li
class="li1"><div
class="de1">&nbsp; &nbsp; &nbsp; <span
class="br0">&#41;</span><span
class="sy0">;</span></div></li></ol></div><p>Next, we create the OAuth credentials that we need.  Essentially, we&#8217;re signing a URL request. We then pass that on to Twitpic and they verify it with Twitter.  We <em>never</em> pass our OAUTH_CONSUMER_SECRET &#8211; so Twitpic can&#8217;t impersonate us.</p><div
class="geshi no php"><ol><li
class="li1"><div
class="de1">&nbsp;<span
class="co1">//Using Abraham&#39;s OAuth library</span></div></li><li
class="li1"><div
class="de1">&nbsp;<span
class="kw1">require_once</span><span
class="br0">&#40;</span><span
class="st0">&#39;OAuth.php&#39;</span><span
class="br0">&#41;</span><span
class="sy0">;</span></div></li><li
class="li1"><div
class="de1">&nbsp;</div></li><li
class="li1"><div
class="de1">&nbsp;<span
class="co1">// instantiating OAuth customer </span></div></li><li
class="li1"><div
class="de1">&nbsp;<span
class="re1">$consumer</span> <span
class="sy0">=</span> <span
class="kw2">new</span> OAuthConsumer<span
class="br0">&#40;</span>OAUTH_CONSUMER_KEY<span
class="sy0">,</span> OAUTH_CONSUMER_SECRET<span
class="br0">&#41;</span><span
class="sy0">;</span></div></li><li
class="li1"><div
class="de1">&nbsp;</div></li><li
class="li1"><div
class="de1">&nbsp;<span
class="co1">// instantiating signer</span></div></li><li
class="li1"><div
class="de1">&nbsp;<span
class="re1">$sha1_method</span> <span
class="sy0">=</span> <span
class="kw2">new</span> OAuthSignatureMethod_HMAC_SHA1<span
class="br0">&#40;</span><span
class="br0">&#41;</span><span
class="sy0">;</span></div></li><li
class="li1"><div
class="de1">&nbsp;</div></li><li
class="li1"><div
class="de1">&nbsp;<span
class="co1">// user&#39;s token</span></div></li><li
class="li1"><div
class="de1">&nbsp;<span
class="kw3">list</span><span
class="br0">&#40;</span><span
class="re1">$oauth_token</span><span
class="sy0">,</span> <span
class="re1">$oauth_token_secret</span><span
class="br0">&#41;</span> <span
class="sy0">=</span> <span
class="kw3">explode</span><span
class="br0">&#40;</span><span
class="st0">&#39;|&#39;</span><span
class="sy0">,</span> <span
class="re1">$GLOBALS</span><span
class="br0">&#91;</span><span
class="st0">&#39;user&#39;</span><span
class="br0">&#93;</span><span
class="br0">&#91;</span><span
class="st0">&#39;password&#39;</span><span
class="br0">&#93;</span><span
class="br0">&#41;</span><span
class="sy0">;</span></div></li><li
class="li1"><div
class="de1">&nbsp;<span
class="re1">$token</span> <span
class="sy0">=</span> <span
class="kw2">new</span> OAuthConsumer<span
class="br0">&#40;</span><span
class="re1">$oauth_token</span><span
class="sy0">,</span> <span
class="re1">$oauth_token_secret</span><span
class="br0">&#41;</span><span
class="sy0">;</span></div></li><li
class="li1"><div
class="de1">&nbsp;</div></li><li
class="li1"><div
class="de1">&nbsp;<span
class="co1">// Generate all the OAuth parameters needed</span></div></li><li
class="li1"><div
class="de1">&nbsp;<span
class="re1">$signingURL</span> <span
class="sy0">=</span> <span
class="st0">&#39;https://api.twitter.com/1/account/verify_credentials.json&#39;</span><span
class="sy0">;</span></div></li><li
class="li1"><div
class="de1">&nbsp;</div></li><li
class="li1"><div
class="de1">&nbsp;<span
class="re1">$request</span> <span
class="sy0">=</span> OAuthRequest<span
class="sy0">::</span><span
class="me2">from_consumer_and_token</span><span
class="br0">&#40;</span><span
class="re1">$consumer</span><span
class="sy0">,</span> <span
class="re1">$token</span><span
class="sy0">,</span> <span
class="st0">&#39;GET&#39;</span><span
class="sy0">,</span> <span
class="re1">$signingURL</span><span
class="sy0">,</span> <span
class="kw3">array</span><span
class="br0">&#40;</span><span
class="br0">&#41;</span><span
class="br0">&#41;</span><span
class="sy0">;</span></div></li><li
class="li1"><div
class="de1">&nbsp;</div></li><li
class="li1"><div
class="de1">&nbsp;<span
class="re1">$request</span><span
class="sy0">-&gt;</span><span
class="me1">sign_request</span><span
class="br0">&#40;</span><span
class="re1">$sha1_method</span><span
class="sy0">,</span> <span
class="re1">$consumer</span><span
class="sy0">,</span> <span
class="re1">$token</span><span
class="br0">&#41;</span><span
class="sy0">;</span></div></li></ol></div><p>We add these generated credentials into the header.</p><div
class="geshi no php"><ol><li
class="li1"><div
class="de1">&nbsp;<span
class="re1">$header</span><span
class="br0">&#91;</span><span
class="nu0">1</span><span
class="br0">&#93;</span> <span
class="sy0">.=</span> <span
class="st0">&quot;, oauth_consumer_key=<span
class="es0">\&quot;</span>&quot;</span> <span
class="sy0">.</span> <span
class="re1">$request</span><span
class="sy0">-&gt;</span><span
class="me1">get_parameter</span><span
class="br0">&#40;</span><span
class="st0">&#39;oauth_consumer_key&#39;</span><span
class="br0">&#41;</span> <span
class="sy0">.</span><span
class="st0">&quot;<span
class="es0">\&quot;</span>&quot;</span><span
class="sy0">;</span></div></li><li
class="li1"><div
class="de1">&nbsp;<span
class="re1">$header</span><span
class="br0">&#91;</span><span
class="nu0">1</span><span
class="br0">&#93;</span> <span
class="sy0">.=</span> <span
class="st0">&quot;, oauth_signature_method=<span
class="es0">\&quot;</span>&quot;</span> <span
class="sy0">.</span> <span
class="re1">$request</span><span
class="sy0">-&gt;</span><span
class="me1">get_parameter</span><span
class="br0">&#40;</span><span
class="st0">&#39;oauth_signature_method&#39;</span><span
class="br0">&#41;</span> <span
class="sy0">.</span><span
class="st0">&quot;<span
class="es0">\&quot;</span>&quot;</span><span
class="sy0">;</span></div></li><li
class="li1"><div
class="de1">&nbsp;<span
class="re1">$header</span><span
class="br0">&#91;</span><span
class="nu0">1</span><span
class="br0">&#93;</span> <span
class="sy0">.=</span> <span
class="st0">&quot;, oauth_token=<span
class="es0">\&quot;</span>&quot;</span> <span
class="sy0">.</span> <span
class="re1">$request</span><span
class="sy0">-&gt;</span><span
class="me1">get_parameter</span><span
class="br0">&#40;</span><span
class="st0">&#39;oauth_token&#39;</span><span
class="br0">&#41;</span> <span
class="sy0">.</span><span
class="st0">&quot;<span
class="es0">\&quot;</span>&quot;</span><span
class="sy0">;</span></div></li><li
class="li1"><div
class="de1">&nbsp;<span
class="re1">$header</span><span
class="br0">&#91;</span><span
class="nu0">1</span><span
class="br0">&#93;</span> <span
class="sy0">.=</span> <span
class="st0">&quot;, oauth_timestamp=<span
class="es0">\&quot;</span>&quot;</span> <span
class="sy0">.</span> <span
class="re1">$request</span><span
class="sy0">-&gt;</span><span
class="me1">get_parameter</span><span
class="br0">&#40;</span><span
class="st0">&#39;oauth_timestamp&#39;</span><span
class="br0">&#41;</span> <span
class="sy0">.</span><span
class="st0">&quot;<span
class="es0">\&quot;</span>&quot;</span><span
class="sy0">;</span></div></li><li
class="li1"><div
class="de1">&nbsp;<span
class="re1">$header</span><span
class="br0">&#91;</span><span
class="nu0">1</span><span
class="br0">&#93;</span> <span
class="sy0">.=</span> <span
class="st0">&quot;, oauth_nonce=<span
class="es0">\&quot;</span>&quot;</span> <span
class="sy0">.</span> <span
class="re1">$request</span><span
class="sy0">-&gt;</span><span
class="me1">get_parameter</span><span
class="br0">&#40;</span><span
class="st0">&#39;oauth_nonce&#39;</span><span
class="br0">&#41;</span> <span
class="sy0">.</span><span
class="st0">&quot;<span
class="es0">\&quot;</span>&quot;</span><span
class="sy0">;</span></div></li><li
class="li1"><div
class="de1">&nbsp;<span
class="re1">$header</span><span
class="br0">&#91;</span><span
class="nu0">1</span><span
class="br0">&#93;</span> <span
class="sy0">.=</span> <span
class="st0">&quot;, oauth_version=<span
class="es0">\&quot;</span>&quot;</span> <span
class="sy0">.</span> <span
class="re1">$request</span><span
class="sy0">-&gt;</span><span
class="me1">get_parameter</span><span
class="br0">&#40;</span><span
class="st0">&#39;oauth_version&#39;</span><span
class="br0">&#41;</span> <span
class="sy0">.</span><span
class="st0">&quot;<span
class="es0">\&quot;</span>&quot;</span><span
class="sy0">;</span></div></li><li
class="li1"><div
class="de1">&nbsp;<span
class="re1">$header</span><span
class="br0">&#91;</span><span
class="nu0">1</span><span
class="br0">&#93;</span> <span
class="sy0">.=</span> <span
class="st0">&quot;, oauth_signature=<span
class="es0">\&quot;</span>&quot;</span> <span
class="sy0">.</span> <span
class="kw3">urlencode</span><span
class="br0">&#40;</span><span
class="re1">$request</span><span
class="sy0">-&gt;</span><span
class="me1">get_parameter</span><span
class="br0">&#40;</span><span
class="st0">&#39;oauth_signature&#39;</span><span
class="br0">&#41;</span><span
class="br0">&#41;</span> <span
class="sy0">.</span><span
class="st0">&quot;<span
class="es0">\&quot;</span>&quot;</span><span
class="sy0">;</span></div></li></ol></div><p>Add everything into CURL</p><div
class="geshi no php"><ol><li
class="li1"><div
class="de1">&nbsp;<span
class="co1">//open connection</span></div></li><li
class="li1"><div
class="de1">&nbsp;<span
class="re1">$ch</span> <span
class="sy0">=</span> curl_init<span
class="br0">&#40;</span><span
class="br0">&#41;</span><span
class="sy0">;</span></div></li><li
class="li1"><div
class="de1">&nbsp;</div></li><li
class="li1"><div
class="de1">&nbsp;<span
class="co1">//Set paramaters</span></div></li><li
class="li1"><div
class="de1">&nbsp;curl_setopt<span
class="br0">&#40;</span><span
class="re1">$ch</span><span
class="sy0">,</span> CURLOPT_HTTPHEADER<span
class="sy0">,</span> <span
class="re1">$header</span><span
class="br0">&#41;</span><span
class="sy0">;</span></div></li><li
class="li1"><div
class="de1">&nbsp;curl_setopt<span
class="br0">&#40;</span><span
class="re1">$ch</span><span
class="sy0">,</span> CURLOPT_RETURNTRANSFER<span
class="sy0">,</span> <span
class="kw2">TRUE</span><span
class="br0">&#41;</span><span
class="sy0">;</span></div></li><li
class="li1"><div
class="de1">&nbsp;curl_setopt<span
class="br0">&#40;</span><span
class="re1">$ch</span><span
class="sy0">,</span> CURLOPT_SSL_VERIFYPEER<span
class="sy0">,</span> <span
class="nu0">0</span><span
class="br0">&#41;</span><span
class="sy0">;</span></div></li><li
class="li1"><div
class="de1">&nbsp;</div></li><li
class="li1"><div
class="de1">&nbsp;<span
class="co1">//set the url, number of POST vars, POST data</span></div></li><li
class="li1"><div
class="de1">&nbsp;curl_setopt<span
class="br0">&#40;</span><span
class="re1">$ch</span><span
class="sy0">,</span>CURLOPT_URL<span
class="sy0">,</span><span
class="re1">$twitpicURL</span><span
class="br0">&#41;</span><span
class="sy0">;</span></div></li></ol></div><p>The data we send to Twitpic (message text, image and key) have to go via POST.</p><div
class="geshi no php"><ol><li
class="li1"><div
class="de1">&nbsp;<span
class="co1">//TwitPic requires the data to be sent as POST</span></div></li><li
class="li1"><div
class="de1">&nbsp;<span
class="re1">$media_data</span> <span
class="sy0">=</span> <span
class="kw3">array</span><span
class="br0">&#40;</span></div></li><li
class="li1"><div
class="de1">&nbsp; &nbsp; &nbsp; &nbsp;<span
class="st0">&#39;media&#39;</span> <span
class="sy0">=&gt;</span> <span
class="st0">&#39;@&#39;</span><span
class="sy0">.</span><span
class="re1">$_FILES</span><span
class="br0">&#91;</span><span
class="st0">&#39;media&#39;</span><span
class="br0">&#93;</span><span
class="br0">&#91;</span><span
class="st0">&#39;tmp_name&#39;</span><span
class="br0">&#93;</span><span
class="sy0">,</span></div></li><li
class="li1"><div
class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span
class="st0">&#39;message&#39;</span> <span
class="sy0">=&gt;</span> <span
class="st0">&#39; &#39;</span> <span
class="sy0">.</span> <span
class="kw3">stripslashes</span><span
class="br0">&#40;</span><span
class="re1">$_POST</span><span
class="br0">&#91;</span><span
class="st0">&#39;message&#39;</span><span
class="br0">&#93;</span><span
class="br0">&#41;</span><span
class="sy0">,</span> <span
class="co1">//A space is needed because twitpic b0rks if first char is an @</span></div></li><li
class="li1"><div
class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span
class="st0">&#39;key&#39;</span><span
class="sy0">=&gt;</span>TWITPIC_API_KEY</div></li><li
class="li1"><div
class="de1">&nbsp; &nbsp; &nbsp; <span
class="br0">&#41;</span><span
class="sy0">;</span></div></li><li
class="li1"><div
class="de1">&nbsp;</div></li><li
class="li1"><div
class="de1">&nbsp;curl_setopt<span
class="br0">&#40;</span><span
class="re1">$ch</span><span
class="sy0">,</span> CURLOPT_POST<span
class="sy0">,</span> <span
class="kw2">true</span><span
class="br0">&#41;</span><span
class="sy0">;</span></div></li><li
class="li1"><div
class="de1">&nbsp;curl_setopt<span
class="br0">&#40;</span><span
class="re1">$ch</span><span
class="sy0">,</span>CURLOPT_POSTFIELDS<span
class="sy0">,</span><span
class="re1">$media_data</span><span
class="br0">&#41;</span><span
class="sy0">;</span></div></li></ol></div><p>All done, we now send the data to Twitpic.</p><div
class="geshi no php"><ol><li
class="li1"><div
class="de1">&nbsp;<span
class="co1">//execute post</span></div></li><li
class="li1"><div
class="de1">&nbsp;<span
class="re1">$result</span> <span
class="sy0">=</span> curl_exec<span
class="br0">&#40;</span><span
class="re1">$ch</span><span
class="br0">&#41;</span><span
class="sy0">;</span></div></li><li
class="li1"><div
class="de1">&nbsp;<span
class="re1">$response_info</span><span
class="sy0">=</span>curl_getinfo<span
class="br0">&#40;</span><span
class="re1">$ch</span><span
class="br0">&#41;</span><span
class="sy0">;</span></div></li><li
class="li1"><div
class="de1">&nbsp;</div></li><li
class="li1"><div
class="de1">&nbsp;<span
class="co1">//close connection</span></div></li><li
class="li1"><div
class="de1">&nbsp;curl_close<span
class="br0">&#40;</span><span
class="re1">$ch</span><span
class="br0">&#41;</span><span
class="sy0">;</span></div></li></ol></div><p>If this has worked, Twitpic will pass back the URL of the image we posted.  We then need to post the entire message to Twitter ourselves (Twitpic can&#8217;t do it for us).</p><div
class="geshi no php"><ol><li
class="li1"><div
class="de1">&nbsp;<span
class="kw1">if</span> <span
class="br0">&#40;</span><span
class="re1">$response_info</span><span
class="br0">&#91;</span><span
class="st0">&#39;http_code&#39;</span><span
class="br0">&#93;</span> <span
class="sy0">==</span> <span
class="nu0">200</span><span
class="br0">&#41;</span> <span
class="co1">//Success</span></div></li><li
class="li1"><div
class="de1">&nbsp;<span
class="br0">&#123;</span></div></li><li
class="li1"><div
class="de1">&nbsp; <span
class="co1">//Decode the response</span></div></li><li
class="li1"><div
class="de1">&nbsp; <span
class="re1">$json</span> <span
class="sy0">=</span> json_decode<span
class="br0">&#40;</span><span
class="re1">$result</span><span
class="br0">&#41;</span><span
class="sy0">;</span></div></li><li
class="li1"><div
class="de1">&nbsp; <span
class="re1">$id</span> <span
class="sy0">=</span> <span
class="re1">$json</span><span
class="sy0">-&gt;</span><span
class="me1">id</span><span
class="sy0">;</span></div></li><li
class="li1"><div
class="de1">&nbsp; <span
class="re1">$twitpicURL</span> <span
class="sy0">=</span> <span
class="re1">$json</span><span
class="sy0">-&gt;</span><span
class="me1">url</span><span
class="sy0">;</span></div></li><li
class="li1"><div
class="de1">&nbsp; <span
class="re1">$text</span> <span
class="sy0">=</span> <span
class="re1">$json</span><span
class="sy0">-&gt;</span><span
class="me1">text</span><span
class="sy0">;</span></div></li><li
class="li1"><div
class="de1">&nbsp; <span
class="re1">$message</span> <span
class="sy0">=</span> <span
class="kw3">trim</span><span
class="br0">&#40;</span><span
class="re1">$text</span><span
class="br0">&#41;</span> <span
class="sy0">.</span> <span
class="st0">&quot; &quot;</span> <span
class="sy0">.</span> <span
class="re1">$twitpicURL</span><span
class="sy0">;</span></div></li></ol></div><p>This next part is specific to Dabr &#8211; your client may post things differently.</p><div
class="geshi no php"><ol><li
class="li1"><div
class="de1">&nbsp; <span
class="co1">//Send the user&#39;s message to twitter</span></div></li><li
class="li1"><div
class="de1">&nbsp; <span
class="re1">$request</span> <span
class="sy0">=</span> API_URL<span
class="sy0">.</span><span
class="st0">&#39;statuses/update.json&#39;</span><span
class="sy0">;</span></div></li><li
class="li1"><div
class="de1">&nbsp;</div></li><li
class="li1"><div
class="de1">&nbsp; <span
class="re1">$post_data</span> <span
class="sy0">=</span> <span
class="kw3">array</span><span
class="br0">&#40;</span><span
class="st0">&#39;source&#39;</span> <span
class="sy0">=&gt;</span> <span
class="st0">&#39;dabr&#39;</span><span
class="sy0">,</span> <span
class="st0">&#39;status&#39;</span> <span
class="sy0">=&gt;</span> <span
class="re1">$message</span><span
class="br0">&#41;</span><span
class="sy0">;</span></div></li><li
class="li1"><div
class="de1">&nbsp; <span
class="re1">$status</span> <span
class="sy0">=</span> twitter_process<span
class="br0">&#40;</span><span
class="re1">$request</span><span
class="sy0">,</span> <span
class="re1">$post_data</span><span
class="br0">&#41;</span><span
class="sy0">;</span></div></li><li
class="li1"><div
class="de1">&nbsp;</div></li><li
class="li1"><div
class="de1">&nbsp; <span
class="co1">//Back to the timeline</span></div></li><li
class="li1"><div
class="de1">&nbsp; twitter_refresh<span
class="br0">&#40;</span><span
class="st0">&quot;twitpic/confirm/$id&quot;</span><span
class="br0">&#41;</span><span
class="sy0">;</span></div></li><li
class="li1"><div
class="de1">&nbsp;<span
class="br0">&#125;</span></div></li></ol></div><p>If it didn&#8217;t work, Twitpic will tell us why.</p><div
class="geshi no php"><ol><li
class="li1"><div
class="de1">&nbsp;<span
class="kw1">else</span></div></li><li
class="li1"><div
class="de1">&nbsp;<span
class="br0">&#123;</span></div></li><li
class="li1"><div
class="de1">&nbsp; <span
class="re1">$content</span> <span
class="sy0">=</span> <span
class="st0">&quot;&lt;p&gt;Twitpic upload failed. No idea why!&lt;/p&gt;&quot;</span><span
class="sy0">;</span></div></li><li
class="li1"><div
class="de1">&nbsp; <span
class="re1">$json</span> <span
class="sy0">=</span> json_decode<span
class="br0">&#40;</span><span
class="re1">$result</span><span
class="br0">&#41;</span><span
class="sy0">;</span></div></li><li
class="li1"><div
class="de1">&nbsp; <span
class="re1">$content</span> <span
class="sy0">.=</span> <span
class="st0">&quot;&lt;br / /&gt;&lt;b&gt;message&lt;/b&gt; &quot;</span> <span
class="sy0">.</span> <span
class="kw3">urlencode</span><span
class="br0">&#40;</span><span
class="re1">$_POST</span><span
class="br0">&#91;</span><span
class="st0">&#39;message&#39;</span><span
class="br0">&#93;</span><span
class="br0">&#41;</span><span
class="sy0">;</span></div></li><li
class="li1"><div
class="de1">&nbsp; <span
class="re1">$content</span> <span
class="sy0">.=</span> <span
class="st0">&quot;&lt;br / /&gt;&lt;b&gt;json&lt;/b&gt; &quot;</span> <span
class="sy0">.</span> <span
class="kw3">print_r</span><span
class="br0">&#40;</span><span
class="re1">$json</span><span
class="br0">&#41;</span><span
class="sy0">;</span></div></li><li
class="li1"><div
class="de1">&nbsp; <span
class="re1">$content</span> <span
class="sy0">.=</span> <span
class="st0">&quot;&lt;br / /&gt;&lt;b&gt;Response&lt;/b&gt; &quot;</span> <span
class="sy0">.</span> <span
class="kw3">print_r</span><span
class="br0">&#40;</span><span
class="re1">$response_info</span><span
class="br0">&#41;</span><span
class="sy0">;</span></div></li><li
class="li1"><div
class="de1">&nbsp; <span
class="re1">$content</span> <span
class="sy0">.=</span> <span
class="st0">&quot;&lt;br / /&gt;&lt;b&gt;header&lt;/b&gt; &quot;</span> <span
class="sy0">.</span> <span
class="kw3">print_r</span><span
class="br0">&#40;</span><span
class="re1">$header</span><span
class="br0">&#41;</span><span
class="sy0">;</span></div></li><li
class="li1"><div
class="de1">&nbsp; <span
class="re1">$content</span> <span
class="sy0">.=</span> <span
class="st0">&quot;&lt;br / /&gt;&lt;b&gt;media_data&lt;/b&gt; &quot;</span> <span
class="sy0">.</span> <span
class="kw3">print_r</span><span
class="br0">&#40;</span><span
class="re1">$media_data</span><span
class="br0">&#41;</span><span
class="sy0">;</span></div></li><li
class="li1"><div
class="de1">&nbsp; <span
class="re1">$content</span> <span
class="sy0">.=</span> <span
class="st0">&quot;&lt;br /&gt;&lt;b&gt;URL was&lt;/b&gt; &quot;</span> <span
class="sy0">.</span> <span
class="re1">$twitpicURL</span><span
class="sy0">;</span></div></li><li
class="li1"><div
class="de1">&nbsp; <span
class="re1">$content</span> <span
class="sy0">.=</span> <span
class="st0">&quot;&lt;br /&gt;&lt;b&gt;File uploaded was&lt;/b&gt; &quot;</span> <span
class="sy0">.</span> <span
class="re1">$_FILES</span><span
class="br0">&#91;</span><span
class="st0">&#39;media&#39;</span><span
class="br0">&#93;</span><span
class="br0">&#91;</span><span
class="st0">&#39;tmp_name&#39;</span><span
class="br0">&#93;</span><span
class="sy0">;</span></div></li><li
class="li1"><div
class="de1">&nbsp;<span
class="br0">&#125;</span></div></li><li
class="li1"><div
class="de1"><span
class="br0">&#125;</span></div></li></ol></div><p><a
href="http://shkspr.mobi/blog/?flattrss_redirect&amp;id=2084&amp;md5=71593e8ec741c57504029f65f36a4261" title="Flattr" target="_blank"><img
src="http://shkspr.mobi/blog/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded> <wfw:commentRss>http://shkspr.mobi/blog/index.php/2010/05/howto-twitpic-and-oauth/feed/</wfw:commentRss> <slash:comments>25</slash:comments> <atom:link rel="payment" href="http://shkspr.mobi/blog/?flattrss_redirect&amp;id=2084&amp;md5=71593e8ec741c57504029f65f36a4261" type="text/html" /> </item> <item><title>Twitpic OAuth &#8211; I&#8217;m Stuck</title><link>http://shkspr.mobi/blog/index.php/2010/05/twitpic-oauth-im-stuck/</link> <comments>http://shkspr.mobi/blog/index.php/2010/05/twitpic-oauth-im-stuck/#comments</comments> <pubDate>Sun, 23 May 2010 20:15:18 +0000</pubDate> <dc:creator>Terence Eden</dc:creator> <category><![CDATA[/etc/]]></category> <category><![CDATA[api]]></category> <category><![CDATA[oauth]]></category> <category><![CDATA[php]]></category> <category><![CDATA[programming]]></category> <category><![CDATA[twitpic]]></category> <category><![CDATA[twitter]]></category><guid
isPermaLink="false">http://shkspr.mobi/blog/?p=2073</guid> <description><![CDATA[Twitpic has implemented an OAuth API. No more having to hand out passwords to all and sundy. Only I&#8217;m too much of a dunderhead to get it working. Perhaps it&#8217;s a combination of heatstroke or this rotten head-cold, but I just can&#8217;t see what I&#8217;m doing wrong. Any help much appreciated. The easy bit. It&#8217;s <a
href='http://shkspr.mobi/blog/index.php/2010/05/twitpic-oauth-im-stuck/'>[...]</a>]]></description> <content:encoded><![CDATA[<p>Twitpic has implemented an <a
href="http://dev.twitpic.com/docs/2/upload/">OAuth API</a>. No more having to hand out passwords to all and sundy.  Only I&#8217;m too much of a dunderhead to get it working.  Perhaps it&#8217;s a combination of heatstroke or this rotten head-cold, but I just can&#8217;t see what I&#8217;m doing wrong.  Any help much appreciated.</p><h2>The easy bit.</h2><p>It&#8217;s easy to post the data to Twitpic</p><pre>$media_data = array(
	'media' =&gt; '@'.$_FILES['media']['tmp_name'],
	'message' =&gt; html_entity_decode($_POST['message']),
	'key'=&gt;'123465789132465'
);
curl_setopt($ch,CURLOPT_POSTFIELDS,$media_data);
</pre><h2>OAuth Credentials</h2><p>Using <a
href="http://twitter.com/abraham">Abrahams</a> <a
href="http://github.com/abraham/twitteroauth">OAuth library for PHP</a>, it&#8217;s easy to get the required OAuth data.</p><pre>require_once('OAuth.php');
// instantiating OAuth customer
$consumer = new OAuthConsumer(OAUTH_CONSUMER_KEY, OAUTH_CONSUMER_SECRET);
// instantiating signer
$sha1_method = new OAuthSignatureMethod_HMAC_SHA1();
// user's token
list($oauth_token, $oauth_token_secret) = explode('|', $GLOBALS['user']['password']);
$token = new OAuthConsumer($oauth_token, $oauth_token_secret);

// signing URL
$fakeurl = 'https://twitter.com/account/verify_credentials.xml';
$request = OAuthRequest::from_consumer_and_token($consumer, $token, 'GET', $fakeurl, array());
$request-&gt;sign_request($sha1_method, $consumer, $token);
$OAuthurl = $request-&gt;to_url();
</pre><h2>The Tricky Bit</h2><p>I&#8217;m following the header example in the <a
href="http://dev.twitpic.com/docs/2/upload/">API documentation</a>. Passing these variable to Twitpic is where I seem to go wrong.<br
/> <code><br
/> $header = array(<br
/> 'X-Auth-Service-Provider: https://api.twitter.com/1/account/verify_credentials.json',<br
/> 'X-Verify-Credentials-Authorization: OAuth realm="http://api.twitter.com/"'<br
/> );<br
/> </code><br
/> I then modify the second header so it reads</p><pre>
"X-Verify-Credentials-Authorization: OAuth realm="http://api.twitter.com/",
oauth_consumer_key="aaaaaaa",
oauth_nonce="bbbbbbbbbbb",
oauth_signature="ccccccccccccc%3D",
oauth_signature_method="HMAC-SHA1",
oauth_timestamp="123456798",
oauth_token="15948715-dddddddddd",
oauth_version="1.0""
</pre><h2>The Error</h2><p>401 &#8220;Could not authenticate you (header rejected by twitter).&#8221;</p><p>GAH!</p><p><a
href="http://shkspr.mobi/blog/?flattrss_redirect&amp;id=2073&amp;md5=b90c99ce28b1790dd6a5701cb4208df8" title="Flattr" target="_blank"><img
src="http://shkspr.mobi/blog/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded> <wfw:commentRss>http://shkspr.mobi/blog/index.php/2010/05/twitpic-oauth-im-stuck/feed/</wfw:commentRss> <slash:comments>14</slash:comments> <atom:link rel="payment" href="http://shkspr.mobi/blog/?flattrss_redirect&amp;id=2073&amp;md5=b90c99ce28b1790dd6a5701cb4208df8" type="text/html" /> </item> <item><title>Bugs in Twitter Text Libraries</title><link>http://shkspr.mobi/blog/index.php/2010/03/bugs-in-twitter-text-libraries/</link> <comments>http://shkspr.mobi/blog/index.php/2010/03/bugs-in-twitter-text-libraries/#comments</comments> <pubDate>Wed, 31 Mar 2010 10:27:50 +0000</pubDate> <dc:creator>Terence Eden</dc:creator> <category><![CDATA[/etc/]]></category> <category><![CDATA[mobile]]></category> <category><![CDATA[usability]]></category> <category><![CDATA[bugs]]></category> <category><![CDATA[dabr]]></category> <category><![CDATA[parse]]></category> <category><![CDATA[regex]]></category> <category><![CDATA[twitter]]></category> <category><![CDATA[urls]]></category><guid
isPermaLink="false">http://shkspr.mobi/blog/?p=1924</guid> <description><![CDATA[The Twitter Engineering Team have a set of text processing classes which are meant to simplify and standardise the recognition of URLs, screen names, and hashtags. Dabr makes use of them to keep in conformance with Twitter&#8217;s style. One of the advantages of the text processing is that it will recognise that www.example.com is a <a
href='http://shkspr.mobi/blog/index.php/2010/03/bugs-in-twitter-text-libraries/'>[...]</a>]]></description> <content:encoded><![CDATA[<p>The <a
href="http://engineering.twitter.com/2010/02/introducing-open-source-twitter-text.html">Twitter Engineering Team have a set of text processing classes</a> which are meant to simplify and standardise the recognition of URLs, screen names, and hashtags.  Dabr makes use of them to keep in conformance with Twitter&#8217;s style.</p><p>One of the advantages of the text processing is that it will recognise that www.example.com is a URL and automatically create a hyperlink. Considering that dropping the &#8220;http://&#8221; represents 5% saving on Twitter&#8217;s 140 character limit for messages, this is great.</p><p>So, I was mightily surprised to get <a
href="http://twitter.com/schmmuck/status/11352406573">this bug report</a> from user &#8220;schmmuck&#8221;</p><div
id="attachment_1927" class="wp-caption aligncenter" style="width: 490px"><img
class="size-full wp-image-1927" title="Dabr rendering error" src="http://shkspr.mobi/blog/wp-content/uploads/2010/03/Capture8_19_22.jpg" alt="Dabr rendering error" width="480" height="320" /><p
class="wp-caption-text">Dabr rendering error</p></div><p>How very odd&#8230;  This is how it looks on <a
href="http://m.twitter.com/">m.twitter.com</a>.</p><div
id="attachment_1926" class="wp-caption aligncenter" style="width: 490px"><img
class="size-full wp-image-1926" title="m.twitter rendering error" src="http://shkspr.mobi/blog/wp-content/uploads/2010/03/Capture8_20_48.jpg" alt="m.twitter rendering error" width="480" height="320" /><p
class="wp-caption-text">m.twitter rendering error</p></div><p>Twitter also use <a
href="http://mobile.twitter.com/">mobile.twitter.com</a> for smartphones.  Here&#8217;s how that site renders the text.</p><div
id="attachment_1925" class="wp-caption aligncenter" style="width: 490px"><img
class="size-full wp-image-1925" title="mobile.twitter rendering error" src="http://shkspr.mobi/blog/wp-content/uploads/2010/03/Capture8_21_54.jpg" alt="mobile.twitter rendering error" width="480" height="320" /><p
class="wp-caption-text">mobile.twitter rendering error</p></div><p>Finally, let&#8217;s take a look at the &#8220;canonical&#8221; rendering at Twitter.com</p><div
id="attachment_1928" class="wp-caption aligncenter" style="width: 410px"><img
class="size-full wp-image-1928" title="Twitter rendering error" src="http://shkspr.mobi/blog/wp-content/uploads/2010/03/Twitter-rendering-error.jpg" alt="Twitter rendering error" width="400" height="213" /><p
class="wp-caption-text">Twitter rendering error</p></div><h2>The Problem(s)</h2><p>The first issue is inconsistency.  Twitter ought to be using the same regex for each of its sites.  It doesn&#8217;t.  This means that different developers will get divergent experiences.  This leads to confusion, which leads to fear, which, as we all know, leads to anger&#8230;. and so forth.</p><p>Secondly, and more importantly, parsing is <em>hard</em>.  There are so many edge cases that errors inevitably creep in.  My post about hashtags explains the problems in defining what <em>should</em> be recognised.</p><p>So, based on what we&#8217;ve seen, should Twitter recognise any of the following as URLs?</p><p>news.bbc.co.uk &#8211; no www there.</p><p>invalid.name &#8211; a silly URL, but a valid one.</p><p>खोज.com &#8211; International domains contain more than just ASCII</p><p>All the above are valid &#8211; yet they&#8217;re not recognised by Twitter.</p><h2>A (Simple) Solution?</h2><p>There is a <a
href="http://www.iana.org/domains/root/db/">canonical list of TLDs</a> which is also available as a <a
href="http://data.iana.org/TLD/tlds-alpha-by-domain.txt">plain text list</a>.</p><p>Any string containing a &#8220;.&#8221; followed by a valid TLD, then followed by a space or &#8220;/&#8221; should be treated as a URL.</p><p>Your thoughts?</p><p><a
href="http://shkspr.mobi/blog/?flattrss_redirect&amp;id=1924&amp;md5=f23a393180b7edf5f5386e927c745cec" title="Flattr" target="_blank"><img
src="http://shkspr.mobi/blog/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded> <wfw:commentRss>http://shkspr.mobi/blog/index.php/2010/03/bugs-in-twitter-text-libraries/feed/</wfw:commentRss> <slash:comments>6</slash:comments> <atom:link rel="payment" href="http://shkspr.mobi/blog/?flattrss_redirect&amp;id=1924&amp;md5=f23a393180b7edf5f5386e927c745cec" type="text/html" /> </item> <item><title>Dabr &#8211; Reply to all and Geotagging</title><link>http://shkspr.mobi/blog/index.php/2010/03/dabr-reply-to-all-and-geotagging/</link> <comments>http://shkspr.mobi/blog/index.php/2010/03/dabr-reply-to-all-and-geotagging/#comments</comments> <pubDate>Wed, 24 Mar 2010 11:36:39 +0000</pubDate> <dc:creator>Terence Eden</dc:creator> <category><![CDATA[mobile]]></category> <category><![CDATA[dabr]]></category> <category><![CDATA[geotagging]]></category> <category><![CDATA[twitter]]></category><guid
isPermaLink="false">http://shkspr.mobi/blog/?p=1881</guid> <description><![CDATA[People have been very excited to see some new functionality in Dabr &#8211; the mobile Twitter client I develop for. But what is it and how does it work? Reply to All The @@ symbol allows you to reply to all the people mentioned within the tweet. It only shows up on tweets which mention <a
href='http://shkspr.mobi/blog/index.php/2010/03/dabr-reply-to-all-and-geotagging/'>[...]</a>]]></description> <content:encoded><![CDATA[<p>People have been very excited to see some new functionality in <a
href="http://m.dabr.co.uk/">Dabr</a> &#8211; the mobile Twitter client I develop for.  But what is it and how does it work?</p><div
id="attachment_1882" class="wp-caption aligncenter" style="width: 456px"><img
class="size-full wp-image-1882" title="@@ and geotag" src="http://shkspr.mobi/blog/wp-content/uploads/2010/03/@@-and-geotag.png" alt="@@ and geotag" width="446" height="60" /><p
class="wp-caption-text">@@ and geotag</p></div><h2>Reply to All</h2><p>The <strong>@@</strong> symbol allows you to reply to all the people mentioned within the tweet.<br
/> It only shows up on tweets which mention other users &#8211; so you should only ever see it when it can be used.</p><p>Hitting <strong>@@</strong> on the above tweet will pre-populate the text box with &#8220;@topgold @whatleydude @dabr&#8221;.</p><p>It should remove any duplicates and should also remove your username.</p><h2>Geotagging</h2><p>Twitter recently allowed the geotagging of tweets.  This allows you to set the longitude and latitude of where you are when you wrote your message.<br
/> Clicking on the green globe (it just looks like a dot at that size!) takes you to a mobile mapping service.</p><div
id="attachment_1884" class="wp-caption aligncenter" style="width: 330px"><img
class="size-full wp-image-1884" title="Google Maps Mobile" src="http://shkspr.mobi/blog/wp-content/uploads/2010/03/snap20100324_110828.png" alt="Google Maps Mobile" width="320" height="480" /><p
class="wp-caption-text">Google Maps Mobile</p></div><p>It only shows up on tweets which are geotagged &#8211; so you should only ever see it when it can be used.</p><h2>How Does It Work?</h2><p>You can see <a
href="http://code.google.com/p/dabr/source/list">all the code in the SVN</a>, but here&#8217;s a quick rundown.</p><p>Geotagging is very simple.  Statuses now have a &lt;geo&gt; field.  If this is populated, it will contain a longitude and latitude.</p><p>﻿We can take those values and pass them to Google Maps Mobile (or your favourite mobile mapping service).<br
/> <code>if ($geo !== null)<br
/> {<br
/> &nbsp;&nbsp;&nbsp;$latlong = $geo->coordinates;<br
/> &nbsp;&nbsp;&nbsp;$lat = $latlong[0];<br
/> &nbsp;&nbsp;&nbsp;$long = $latlong[1];<br
/> &nbsp;&nbsp;&nbsp;$actions[] = theme('action_icon', "http://maps.google.co.uk/m?q={$lat},{$long}", 'images/map.png', 'MAP');<br
/> }</code></p><p>Reply to all is a little more involved.<br
/> Twitter provide an <a
href="http://engineering.twitter.com/2010/02/introducing-open-source-twitter-text.html">excellent set of Text Libraries</a>.  These provide officially sanctioned regular expressions to help your project find URLs, hashtags and usernames.</p><p>Using the <a
href="http://github.com/mzsanford/twitter-text-php/blob/master/src/Twitter/Extractor.php">Twitter Text Extractor class</a> we can determine how many usernames are mentioned in a tweet.  Any duplicates are removed &#8211; as is the user&#8217;s username.</p><p>Any questions &#8211; just ask!</p><p><a
href="http://shkspr.mobi/blog/?flattrss_redirect&amp;id=1881&amp;md5=dbf9f757fc788e0c1e2191cde3940932" title="Flattr" target="_blank"><img
src="http://shkspr.mobi/blog/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded> <wfw:commentRss>http://shkspr.mobi/blog/index.php/2010/03/dabr-reply-to-all-and-geotagging/feed/</wfw:commentRss> <slash:comments>1</slash:comments> <atom:link rel="payment" href="http://shkspr.mobi/blog/?flattrss_redirect&amp;id=1881&amp;md5=dbf9f757fc788e0c1e2191cde3940932" type="text/html" /> </item> <item><title>The Perfect Twitter Spam Attack?</title><link>http://shkspr.mobi/blog/index.php/2010/03/the-perfect-twitter-spam-attack/</link> <comments>http://shkspr.mobi/blog/index.php/2010/03/the-perfect-twitter-spam-attack/#comments</comments> <pubDate>Sun, 07 Mar 2010 09:59:03 +0000</pubDate> <dc:creator>Terence Eden</dc:creator> <category><![CDATA[usability]]></category> <category><![CDATA[evil genius]]></category> <category><![CDATA[oauth]]></category> <category><![CDATA[passwords]]></category> <category><![CDATA[security]]></category> <category><![CDATA[twitter]]></category><guid
isPermaLink="false">http://shkspr.mobi/blog/?p=1796</guid> <description><![CDATA[This morning, when I logged on to Twitter, I saw a user who I didn&#8217;t recognise tweeting away in my timeline. I wracked my brains thinking about how they could have gotten in there before I realised it was a long-dormant friend who had changed their name and avatar. But, in thinking about how a <a
href='http://shkspr.mobi/blog/index.php/2010/03/the-perfect-twitter-spam-attack/'>[...]</a>]]></description> <content:encoded><![CDATA[<p>This morning, when I logged on to Twitter, I saw a user who I didn&#8217;t recognise tweeting away in my timeline.</p><p>I wracked my brains thinking about how they could have gotten in there before I realised it was a long-dormant friend who had changed their name and avatar.</p><p>But, in thinking about how a spammer could infiltrate one&#8217;s timeline, I think I came up with a fairly bullet-proof method to spam Twitter users.</p><p>I present this as an exercise in devious thinking &#8211; and also to show how our assumptions about security can play against us. Remember, hacking and impersonation are likely to be illegal in your jurisdiction.  This information is designed to help you understand how security weaknesses can occur.</p><h2>Being Evil</h2><p>Imagine you are a nasty, evil Twitter spammer.  Your own mother wouldn&#8217;t spit on you if you were on fire &#8211; that&#8217;s how mean you are.  Here&#8217;s what you do.</p><ol><li>Obtain a user&#8217;s password.  Admittedly, this is the hardest part of the process. You might use a dictionary attack, use the same password they use to log in to another site, or somehow steal it.</li><li>Log on to Twitter.</li><li>Go to &#8220;Connections&#8221; and see which services they have connected to using OAuth.  For the purposes of this experiment, let&#8217;s assume they use Example.com.</li><li>Go to Example.com and OAuth yourself with Twitter using your mark&#8217;s credentials.</li><li>Here&#8217;s where the ordinary spammer falls down.  The ordinary spammer will start sending out messages from the mark&#8217;s account.  That&#8217;s <strong>not</strong> the aim of this weakness.</li><li>From the mark&#8217;s account, through Example.com, make your victim follow one of your spam accounts.  An account which exists solely to show adverts to your victim.</li></ol><p>Your victim now sees your adverts for pills, poker and porn in their timeline.  With any luck, they&#8217;ll just assume that one of their true friends is promoting your illicit wares.</p><h2>Counter Attack</h2><p>Most victims will assume that they accidentally followed your spam account &#8211; or that one of their friends has been hacked.</p><p>Worst case scenario, they unfollow your spam account.</p><p><strong><em>So you just make them follow you again!</em></strong> Remember, you are <strong>still</strong> OAuth&#8217;d to Example.com. You can make them follow as many of your spam accounts as you think you can get away with.</p><p>At this point, the intelligent victim will think that their account may be compromised and change their password.</p><p><strong><em>It doesn&#8217;t matter</em>!</strong> Because you have used OAuth, password changes <em>don&#8217;t affect you</em>.  You can continue make them follow as many of your spam accounts as you think you can get away with.</p><p>At this point, the <em>really</em> intelligent victim will go through their OAuth connections to look for something suspicious.  They won&#8217;t find it.  Remember steps 3 and 4?  <strong>You are OAuth&#8217;d to a service that your victim trusts</strong>.</p><p>Because of the way Twitter displays OAuth information, there&#8217;s no way for a victim to know when a service was last authorised.</p><div
id="attachment_1798" class="wp-caption aligncenter" style="width: 460px"><img
class="size-full wp-image-1798" title="Twitter OAuth Connections" src="http://shkspr.mobi/blog/wp-content/uploads/2010/03/Twitter-OAuth-Connections.png" alt="Twitter OAuth Connections" width="450" height="501" /><p
class="wp-caption-text">Twitter OAuth Connections</p></div><p>There is no information other than the <em>first time</em> the OAuth was set up.  No last accessed date, no IP addresses, nothing useful.</p><p>When following an account, the victim gets no notification of what has happened, when it has happened or how it has happened.  There is no way of them knowing which of their OAuth&#8217;d connections have been compromised, nor when it happened.</p><p>Their only safe option is to revoke <em>every single </em>OAuth connection.  Then reauthorise.  A time consuming and annoying prospect.</p><h2>Conclusion</h2><p>I hope I&#8217;ve demonstrated two things.</p><p>Firstly, there&#8217;s more to spam then just sending out messages.  Forcing someone to read a message is just as annoying.</p><p>Secondly, our understanding of security and usability haven&#8217;t quite caught up with the new tools which are available to us.  OAuth is still better than giving your password to an untrusted site &#8211; but without essential usability changes, a compromised account is a lot more dangerous than the user would suspect.</p><p>This &#8220;attack&#8221; still relies on a victim having their original password compromised.  That&#8217;s not a trivial matter.  But security is like sexual health &#8211; it only takes one little accident&#8230;</p><p><a
href="http://shkspr.mobi/blog/?flattrss_redirect&amp;id=1796&amp;md5=702b9847a3d966eaca8e8e6204cee1d5" title="Flattr" target="_blank"><img
src="http://shkspr.mobi/blog/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded> <wfw:commentRss>http://shkspr.mobi/blog/index.php/2010/03/the-perfect-twitter-spam-attack/feed/</wfw:commentRss> <slash:comments>2</slash:comments> <atom:link rel="payment" href="http://shkspr.mobi/blog/?flattrss_redirect&amp;id=1796&amp;md5=702b9847a3d966eaca8e8e6204cee1d5" type="text/html" /> </item> <item><title>Hashtag Standards</title><link>http://shkspr.mobi/blog/index.php/2010/02/hashtag-standards/</link> <comments>http://shkspr.mobi/blog/index.php/2010/02/hashtag-standards/#comments</comments> <pubDate>Thu, 25 Feb 2010 17:35:38 +0000</pubDate> <dc:creator>Terence Eden</dc:creator> <category><![CDATA[/etc/]]></category> <category><![CDATA[usability]]></category> <category><![CDATA[api]]></category> <category><![CDATA[geek]]></category> <category><![CDATA[hashtags]]></category> <category><![CDATA[standards]]></category> <category><![CDATA[twitter]]></category><guid
isPermaLink="false">http://shkspr.mobi/blog/?p=1730</guid> <description><![CDATA[This is one of the longest and geekiest posts I've done. It's a work in progress. All comments and abuse welcome. #hashtag – As long has there has been a way to search Tweets* people have been adding information to make the easy to find. The #hashtag syntax has become the standard for attaching a <a
href='http://shkspr.mobi/blog/index.php/2010/02/hashtag-standards/'>[...]</a>]]></description> <content:encoded><![CDATA[<pre>This is one of the longest and geekiest posts I've done.
It's a work in progress.
All comments and abuse welcome.</pre><blockquote><p>#hashtag – As long has there has been a way to search Tweets* people have been adding information to make the easy to find. The #hashtag syntax has become the standard for attaching a succinct tag to Tweets.</p></blockquote><p><a
href="http://engineering.twitter.com/2010/02/introducing-open-source-twitter-text.html">The Twitter Engineering Blog</a></p><p>That&#8217;s all well and good, but <a
href="http://shkspr.mobi/blog/index.php/2010/02/hashtags-and-implicit-knowledge/">as I discovered yesterday</a>, without standardisation the ability to search falls apart.</p><p>I&#8217;m not talking about whether you should use the #<span
style="text-decoration: underline;">LondonFire</span><strong> </strong>tag rather than #<span
style="text-decoration: underline;">FireOfLondon</span><strong> </strong>or #<span
style="text-decoration: underline;">LDNfire</span>. Rather; how does a computer recognise what a <em>valid</em> tag is?</p><h2>Why Does This Matter?</h2><p>Search and tracking quickly break down if they are inconsistent.<br
/> For example, if you are using #<span
style="text-decoration: underline;">Romeo&amp;Juliet</span> to mark all your conversations about the play you are watching, different Twitter clients will link through to either #<span
style="text-decoration: underline;">Romeo</span>, #<span
style="text-decoration: underline;">Romeo&amp;</span>, or #<span
style="text-decoration: underline;">Romeo&amp;Juliet</span>.  Each search returning potentially different conversations.</p><h2>What&#8217;s The Convention?</h2><p>Twitter&#8217;s website <em>ought</em> to be the definitive source of how hashtags work.  This is their main site.</p><div
id="attachment_1738" class="wp-caption aligncenter" style="width: 417px"><img
class="size-full wp-image-1738" title="Twitter Website Hashtag" src="http://shkspr.mobi/blog/wp-content/uploads/2010/02/Twitter-Website-Hashtag.png" alt="Twitter Website Hashtag" width="407" height="214" /><p
class="wp-caption-text">Twitter Website Hashtag</p></div><p>Yet, when we visit their mobile site &#8211; we get a completely different experience.</p><div
id="attachment_1731" class="wp-caption aligncenter" style="width: 330px"><img
class="size-full wp-image-1731" title="Mobile.Twitter's hashtags" src="http://shkspr.mobi/blog/wp-content/uploads/2010/02/snap20100225_151129.png" alt="Mobile.Twitter's hashtags" width="320" height="480" /><p
class="wp-caption-text">Mobile.Twitter&#39;s hashtags</p></div><h2>Application Confusion</h2><p>Because there aren&#8217;t any widely publicised definitions for what hashtags are, some applications have a significantly different attitude to hashtags</p><div
id="attachment_1732" class="wp-caption aligncenter" style="width: 490px"><img
class="size-full wp-image-1732" title="SocialScope Hashtags" src="http://shkspr.mobi/blog/wp-content/uploads/2010/02/Capture8_1_53.jpg" alt="SocialScope Hashtags" width="480" height="320" /><p
class="wp-caption-text">SocialScope Hashtags</p></div><h2><p><div
id="attachment_1771" class="wp-caption aligncenter" style="width: 490px"><img
class="size-full wp-image-1771" title="UberTwitter's Hashtag Support" src="http://shkspr.mobi/blog/wp-content/uploads/2010/02/x2_c38906.jpeg" alt="UberTwitter's Hashtag Support" width="480" height="360" /><p
class="wp-caption-text">UberTwitter&#39;s Hashtag Support</p></div></h2><h2>Standardisation</h2><p>To be fair, the Twitter team do have a standard.  Even if they don&#8217;t use it themselves.</p><p>They even have some <a
href="http://github.com/mzsanford/twitter-text-conformance">limited test cases</a> and libraries in Ruby and Java.</p><p>So, given that Twitter, their implementation and apps all disagree on what a hashtag is, let&#8217;s try to work our what they <em>should</em> be.</p><h2>Anatomy of a Tag</h2><p>To begin at the beginning.  A hashtag starts with a hash. #.  Simple, no? No.</p><p>There are two different hash symbols! There&#8217;s the # we all know and love, and there&#8217;s ＃.  Looks pretty similar, but in fact it&#8217;s the unicode symbol [U+FF03]</p><p>Actually, that&#8217;s not the beginning.  What comes before the # of the hashtag?</p><p>Consider the following examples &#8211; which should be hashtags?</p><ul><li>#tag &#8211; the # starts off the Tweet</li><li>This is my tweet #test &#8211; the # comes after a space.</li><li>This is it.#tag &#8211; the # is pushed against some punctuation, perhaps for reasons of space.</li><li>Here we go-#LiftOff &#8211; the # is pushed against a -</li><li>I&#8217;ve run out of space#OhNo &#8211; the # is pushed against some text</li><li>&amp;#nbsp; &#8211; the # is part of an HTML entity</li><li>text　#hashtag &#8211; the # comes after a &#8220;wide space&#8221; (U+3000)</li><li>Should I use #tag/#hashtag? The # comes after a /</li><li>Is this valid ##tag &#8211; there are two #s</li></ul><p>So, we can see it&#8217;s a little more complicated than we first thought.</p><h2>The End</h2><p>Let&#8217;s skip over what&#8217;s <em>in</em> a hashtag and as &#8220;how do we know that a tag has finished?&#8221;</p><p>Consider the following examples -</p><ul><li>New album #OMG! &#8211; should the ! be part of the hashtag?</li><li>#BreakingNews: dog bites man &#8211; should the : be part of the hashtag?</li><li>(is this a #tag) &#8211; should the ) be part of the hashtag?</li><li>I like #tags#</li></ul><p>We probably don&#8217;t want to have any punctuation at the end of our tag.  Can you think of any counter examples?</p><h2>Yummy Filling</h2><p>Our language is more than just the letters A-Z. We&#8217;ve got punctuation, numbers, symbols and all manner of other glyphs.  Which of them count as part of a hashtag?</p><p>Take a look at these examples</p><ul><li>Vote Bush! #Don&#8217;t</li><li>My dog died #:-(</li><li>Einstein #e=mc^2</li><li>I&#8217;m on bus #123</li><li>I&#8217;m giving #110%</li></ul><p>Using Twitter&#8217;s standards, <strong>none</strong> of the above render as complete tags.</p><h2>Foreign Languages</h2><p>We&#8217;ve mentioned accents above.  As we can see in the first example, &#8220;funny&#8221; characters can cause problems.  Broadly speaking, there are three issues.</p><ol><li>Accents.  Should the é on #Café be linked?</li><li>Accents.  Is #Romeo the same as #Ŕöméø?</li><li>Japanese, and some other languages, don&#8217;t use spaces.  Is #tagの valid? What about # 会議中 ?</li></ol><h2>Exhausted</h2><p>These are a fraction of the possible problems.  It&#8217;s exhausting trying to find all the possible textual combinations and permutations which could lead into a hashtag.  No wonder there is confusion!</p><p>Search is a complex, profitable, and useful business.  It&#8217;s of vital importance that there is a legitimate, comprehensive standard which <strong>all</strong> sites and applications can follow.</p><p><a
href="http://shkspr.mobi/blog/?flattrss_redirect&amp;id=1730&amp;md5=6d8dfcbd0bf2477df441465329d8c17d" title="Flattr" target="_blank"><img
src="http://shkspr.mobi/blog/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded> <wfw:commentRss>http://shkspr.mobi/blog/index.php/2010/02/hashtag-standards/feed/</wfw:commentRss> <slash:comments>2</slash:comments> <atom:link rel="payment" href="http://shkspr.mobi/blog/?flattrss_redirect&amp;id=1730&amp;md5=6d8dfcbd0bf2477df441465329d8c17d" type="text/html" /> </item> <item><title>Hashtags and Implicit Knowledge</title><link>http://shkspr.mobi/blog/index.php/2010/02/hashtags-and-implicit-knowledge/</link> <comments>http://shkspr.mobi/blog/index.php/2010/02/hashtags-and-implicit-knowledge/#comments</comments> <pubDate>Wed, 24 Feb 2010 16:58:27 +0000</pubDate> <dc:creator>Terence Eden</dc:creator> <category><![CDATA[usability]]></category> <category><![CDATA[api]]></category> <category><![CDATA[dabr]]></category> <category><![CDATA[documentation]]></category> <category><![CDATA[hashtags]]></category> <category><![CDATA[tags]]></category> <category><![CDATA[twitter]]></category><guid
isPermaLink="false">http://shkspr.mobi/blog/?p=1706</guid> <description><![CDATA[What is &#8220;Implicit Knowledge&#8221;? Essentially it&#8217;s stuff that everyone knows, but no one has written down. Usually it&#8217;s something that people have worked out through their own experiences. This sort of knowledge is common in life &#8211; but is fatal in computing and design. Take the following tweet I received. The complaint was that #tfm&#38;a <a
href='http://shkspr.mobi/blog/index.php/2010/02/hashtags-and-implicit-knowledge/'>[...]</a>]]></description> <content:encoded><![CDATA[<p>What is &#8220;Implicit Knowledge&#8221;?  Essentially it&#8217;s stuff that everyone knows, but no one has written down.  Usually it&#8217;s something that people have worked out through their own experiences.</p><p>This sort of knowledge is common in life &#8211; but is fatal in computing and design.  Take the following tweet I received.</p><div
class="quotedtweet" id="tw9582463562" style="background-color:#eef;padding:5px;margin-bottom:5px"><div
class="tw_user-info" style="padding:10px 10px 5px 0;float:left;text-align:center;width:100px;"><div
class="tw_thumb"> <a
href="http://twitter.com/Mawkins" title="Mark Hawkins" class="quoting_pic" rel="external"><img
src="http://img.tweetimag.es/i/Mawkins_n" alt="Mawkins" /></a></div><div
class="tw_screen-name"> <em><a
href="http://twitter.com/Mawkins" title="Twitter page : Mark Hawkins" rel="external">Mawkins</a></em></div><div
class="tw_full-name"> <strong>(Mark Hawkins)</strong></div></div><div
class="tw_content" style="float: left; width: 500px; font: 20pt Georgia, Verdana, sans-serif; font-style: normal;"><div
class="tw_entry-content"> <a
href="http://www.twitter.com/edent" rel="external">@edent</a> <a
href="http://www.twitter.com/dabr" rel="external">@dabr</a> you folks aware ampersands / &amp;s don't seem to work as part of hashtag links?</div></div><div
style="clear: both; text-align: left;font-style:italic;margin-left:110px"><p
class="tw_meta tw_entry-meta" style="margin: 0;padding-top:5px"> <small> <span>On <a
href="http://twitter.com/Mawkins/status/9582463562" rel="external">24-2-2010 16:27:19</a></span> <span>from <a
href="http://www.tweetdeck.com" rel="nofollow">TweetDeck</a></span> <span> in reply to <a
href="http://twitter.com/edent/status/9581804744" rel="external">Terence Eden</a></span> </small></p></div></div><p>The complaint was that #tfm&amp;a should be rendered as <span
style="text-decoration: underline;">#tfm&amp;a</span> not <span
style="text-decoration: underline;">#tfm</span>&amp;a.</p><h2>Everyone knows that&#8217;s how hashtags work!</h2><p>On Twitter&#8217;s website, find the page which discusses hashtag syntax.  Find where they explain how they should be styled.</p><p><strong>You can&#8217;t.</strong></p><p>And thus implicit knowledge is born.  Dabr only looks at letters and numbers in a hashtag.  It assumes that any other character is the end of the tag.</p><div
id="attachment_1708" class="wp-caption aligncenter" style="width: 490px"><img
class="size-full wp-image-1708" title="Dabr's Hashtag" src="http://shkspr.mobi/blog/wp-content/uploads/2010/02/Capture16_35_30.jpg" alt="Dabr's Hashtag" width="480" height="320" /><p
class="wp-caption-text">Dabr&#39;s Hashtag</p></div><p>Without official guidance &#8211; implicit knowledge develops.</p><h2>Has Dabr Got It Wrong?</h2><p>No.  I don&#8217;t think so.  Take a look at how Twitter on the web renders hashtags&#8230;</p><div
id="attachment_1710" class="wp-caption aligncenter" style="width: 392px"><img
class="size-full wp-image-1710" title="Twitter's Web Site" src="http://shkspr.mobi/blog/wp-content/uploads/2010/02/Twitters-Web-Site.png" alt="Twitter's Web Site" width="382" height="312" /><p
class="wp-caption-text">Twitter&#39;s Web Site</p></div><p>&#8230;and on the mobile.</p><div
id="attachment_1707" class="wp-caption aligncenter" style="width: 490px"><img
class="size-full wp-image-1707" title="Twitter Mobile" src="http://shkspr.mobi/blog/wp-content/uploads/2010/02/Capture16_34_33.jpg" alt="Twitter Mobile" width="480" height="320" /><p
class="wp-caption-text">Twitter Mobile</p></div><h2>So Where Does Render The Full Tag?</h2><p>Several applications don&#8217;t render tags in the same way as Twitter.  Take a look at SocialScope</p><div
id="attachment_1709" class="wp-caption aligncenter" style="width: 490px"><img
class="size-full wp-image-1709" title="SocialScope Hashtags" src="http://shkspr.mobi/blog/wp-content/uploads/2010/02/Capture16_34_56.jpg" alt="SocialScope Hashtags" width="480" height="320" /><p
class="wp-caption-text">SocialScope Hashtags</p></div><div
id="attachment_1727" class="wp-caption aligncenter" style="width: 330px"><img
src="http://shkspr.mobi/blog/wp-content/uploads/2010/02/jsfe.jpg" alt="Tweetie2" title="Tweetie2" width="320" height="480" class="size-full wp-image-1727" /><p
class="wp-caption-text">Tweetie2</p></div><p>I&#8217;ll upload more screenshots if I find examples of &#8220;badly behaved&#8221; hashtags.  Please let me know if you find any.</p><h2>What Does Twitter Say?</h2><p>Twitter has one page devoted to hashtags.  It is a <a
href="http://help.twitter.com/forums/10711/entries/49309-what-are-hashtags-the-symbol">support page for hashtags</a>.  This explains to people what hashtags are.  There&#8217;s no detail on valid characters, maximum length, or any of the things which might be useful for a developer or designer.</p><h3>Edit 2010-02-25</h3><p>David Dorward has <a
href="http://twitter.com/dorward/status/9584777039">pointed out that there is an official resource</a>. On the Twitter Engineering blog &#8211; which isn&#8217;t linked to from the developer site &#8211; there is a <a
href="http://engineering.twitter.com/2010/02/introducing-open-source-twitter-text.html">page discussing hashtags and how to validate them</a>.  You&#8217;ll notice that they are rather circumspect on what should constitute a hashtag.</p><h2>Conclusion</h2><p>Standards and guidelines allow developers to create compatible applications.</p><p>Without explicit recommendations, developers will diverge as widely as possible.  Twitter &#8211; and everyone with an interest in compatibility and usability &#8211; needs to ensure that the knowledge they impart is <em>explicit</em>.</p><p>Letting people make it up as they go along leads to confusion.</p><p><a
href="http://shkspr.mobi/blog/?flattrss_redirect&amp;id=1706&amp;md5=3da27a57f5bf04e91e228cb51e8ce6b3" title="Flattr" target="_blank"><img
src="http://shkspr.mobi/blog/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded> <wfw:commentRss>http://shkspr.mobi/blog/index.php/2010/02/hashtags-and-implicit-knowledge/feed/</wfw:commentRss> <slash:comments>5</slash:comments> <atom:link rel="payment" href="http://shkspr.mobi/blog/?flattrss_redirect&amp;id=1706&amp;md5=3da27a57f5bf04e91e228cb51e8ce6b3" type="text/html" /> </item> <item><title>Don&#8217;t Let Users Do Things They Can&#8217;t Do</title><link>http://shkspr.mobi/blog/index.php/2010/02/dont-let-users-do-things-they-cant-do/</link> <comments>http://shkspr.mobi/blog/index.php/2010/02/dont-let-users-do-things-they-cant-do/#comments</comments> <pubDate>Mon, 22 Feb 2010 15:05:42 +0000</pubDate> <dc:creator>Terence Eden</dc:creator> <category><![CDATA[usability]]></category> <category><![CDATA[api]]></category> <category><![CDATA[dabr]]></category> <category><![CDATA[twitter]]></category><guid
isPermaLink="false">http://shkspr.mobi/blog/?p=1682</guid> <description><![CDATA[There are many &#8220;rules&#8221; when it comes to User Interface / User Experience design.  One that I try to stick to is &#8220;Don&#8217;t let users do things they can&#8217;t do.&#8221; It&#8217;s one of my gripes with Linux.  If you&#8217;re editing a configuration file, you are relying on yourself to sanity check your input &#8211; often <a
href='http://shkspr.mobi/blog/index.php/2010/02/dont-let-users-do-things-they-cant-do/'>[...]</a>]]></description> <content:encoded><![CDATA[<p>There are many &#8220;rules&#8221; when it comes to User Interface / User Experience design.  One that I try to stick to is &#8220;Don&#8217;t let users do things they can&#8217;t do.&#8221;</p><p>It&#8217;s one of my gripes with Linux.  If you&#8217;re editing a configuration file, you are relying on yourself to sanity check your input &#8211; often without knowing what the limits are.</p><p>Take these two different examples.</p><p>In a text file, we might have:</p><blockquote><pre>#Maximum Widgets to fidget
maxW_to-F = 0
</pre></blockquote><p>Whereas a GUI would show</p><p>How many Widgets do you want to fidget?<br
/> <select><option>1</option><option>2</option><option>3</option><option>5</option> </select><p>Even if you don&#8217;t know the rules behind Widget fidgetting (must be a prime number lower than 7), the GUI won&#8217;t let you choose a value that you can&#8217;t select.  The GUI doesn&#8217;t prevent you setting an innapropriate value &#8211; just an illegal one. Your config file, however, could be set to any crazy value that a user type &#8211; often resulting in &#8220;unpredictable&#8221; results.</p><blockquote><pre>#Maximum Widgets to fidget
maxW_to-F = seventeen
</pre></blockquote><p>It&#8217;s with this in mind that I&#8217;ve made the following <a
href="http://code.google.com/p/dabr/source/detail?r=279">change to Dabr</a> &#8211; the mobile Twitter client.</p><h2>To Auth or Not To Auth? That Is The Question</h2><p>Twitter&#8217;s API has bug / peculiarity (<a
href="http://groups.google.com/group/twitter-development-talk/browse_thread/thread/318a5e820ee73765#">reported to their discussion board</a>) which causes Dabr to log a user out.  Let me explain the steps</p><ul><li>User 1 (@private) has set her tweets to &#8220;protected&#8221;.</li><li>This means no one can see @private&#8217;s tweet unless she allows them.</li><li>@private has not allowed User 2 (@edent) to view her tweets.  She is protect from his view.</li><li>@edent clicks to view @private&#8217;s profile.</li><li>@edent can see that @private has 42 friends, 17 followers and 3 favourites.</li></ul><p>So far, this is the same behaviour on Twitter&#8217;s website as it is through their API.  Here&#8217;s the difference</p><h3>Web</h3><ul><li>@edent tries to see @private&#8217;s followers and can see their names, profile pictures etc.</li><li>@edent can also see @private&#8217;s friends</li><li>@edent <strong>cannot</strong> see @private&#8217;s favourites (or even how many favourites she has)</li></ul><h3>API</h3><ul><li>@edent tries to see @private&#8217;s followers, friends or favourites</li><li>Because @edent isn&#8217;t allowed to see @private&#8217;s info, the API returns <a
href="http://apiwiki.twitter.com/HTTP-Response-Codes-and-Errors">401 Authorisation Required</a>.</li></ul><p>This is where things get tricky. Dabr sees the 401 and concludes that the user has invalid credentials.  It then, as a security measure, clears the user&#8217;s cookie and logs them out.</p><p>This may be a little harsh, but <a
href="http://en.wikipedia.org/wiki/List_of_HTTP_status_codes#4xx_Client_Error">HTTP 401 essentially says that the authorisation has failed</a>.</p><h2>Fixing It</h2><p>There are 3 ways that this could be fixed</p><ol><li>Twitter could rationalise the API to allow access to the same content that a web user gets.</li><li>Twitter could return a different status code.</li><li>Dabr needs fixing.</li></ol><p>So, how do we get Dabr not to log out when it receives a 401 <em>only</em> under these specific circumstances?</p><p><a
href="http://code.google.com/p/dabr/source/browse/trunk/common/twitter.php?r=274#293">Looking at the code</a>, we can see that Dabr simply sees the HTTP response code.  To fix it we&#8217;ll need to pass extra parameters, check where the code was called from, investigate all the edge cases, add more logic to the system, futz around breaking things, etc&#8230; etc&#8230;</p><p>What a pain in the&#8230;</p><h2>Or</h2><p><em>Don&#8217;t let users do things they </em>can&#8217;t<em> do.</em></p><p>If a user can&#8217;t see the information &#8211; why do we even let them <em>try</em> to see the information?  Why can&#8217;t we just get rid of the link?</p><p>This is what a user currently sees:</p><div
id="attachment_1688" class="wp-caption aligncenter" style="width: 364px"><img
class="size-full wp-image-1688" title="Old Style" src="http://shkspr.mobi/blog/wp-content/uploads/2010/02/Old-Style.png" alt="Old Style" width="354" height="73" /><p
class="wp-caption-text">Old Style</p></div><p>We&#8217;ve established that they can&#8217;t view followers, friends and favourites.  So we can get rid of those links (but not the information).</p><div
id="attachment_1687" class="wp-caption aligncenter" style="width: 364px"><img
class="size-full wp-image-1687" title="New Style" src="http://shkspr.mobi/blog/wp-content/uploads/2010/02/New-Style.png" alt="New Style" width="354" height="73" /><p
class="wp-caption-text">New Style</p></div><p>(Incidentally, I&#8217;ve changed the order of the links.  I&#8217;ve tried to group together similar items.  Followers, friends, favourites and lists go together. Then DM. Finally, follow, block, report spam.)</p><p>Now a user cannot click through to an unwanted error message.</p><h2>Or</h2><p>There is another way round this.  With &#8220;Direct Messages&#8221; we could do the same thing &#8211; simply remove the link if you&#8217;re not able to send that user a DM.</p><p>Instead, we&#8217;ve taken the approach of displaying a suitable error message.</p><div
id="attachment_1689" class="wp-caption aligncenter" style="width: 455px"><img
class="size-full wp-image-1689" title="Direct Message Warning" src="http://shkspr.mobi/blog/wp-content/uploads/2010/02/Direct-Message-Warning.png" alt="Direct Message Warning" width="445" height="194" /><p
class="wp-caption-text">Direct Message Warning</p></div><p>The advantage of this is that the user gets an explanation as to <em>why</em> they are unable to complete an action.</p><h2>Your Thought?</h2><p>Which do you prefer? Being unable to click on a link (with no explanation) or clicking on a link only to be given a warning message?</p><p><a
href="http://shkspr.mobi/blog/?flattrss_redirect&amp;id=1682&amp;md5=b886ba243cc96e8f8af7c6865be81c44" title="Flattr" target="_blank"><img
src="http://shkspr.mobi/blog/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded> <wfw:commentRss>http://shkspr.mobi/blog/index.php/2010/02/dont-let-users-do-things-they-cant-do/feed/</wfw:commentRss> <slash:comments>3</slash:comments> <atom:link rel="payment" href="http://shkspr.mobi/blog/?flattrss_redirect&amp;id=1682&amp;md5=b886ba243cc96e8f8af7c6865be81c44" type="text/html" /> </item> <item><title>Twitter For BlackBerry &#8211; Review</title><link>http://shkspr.mobi/blog/index.php/2010/02/twitter-for-blackberry-review/</link> <comments>http://shkspr.mobi/blog/index.php/2010/02/twitter-for-blackberry-review/#comments</comments> <pubDate>Wed, 17 Feb 2010 13:38:57 +0000</pubDate> <dc:creator>Terence Eden</dc:creator> <category><![CDATA[mobile]]></category> <category><![CDATA[blackberry]]></category> <category><![CDATA[review]]></category> <category><![CDATA[RIM]]></category> <category><![CDATA[socialscope]]></category> <category><![CDATA[twitter]]></category> <category><![CDATA[ubertwitter]]></category><guid
isPermaLink="false">http://shkspr.mobi/blog/?p=1650</guid> <description><![CDATA[Blah blah Twitter&#8230;. Blah Blah BlackBerry&#8230; Blah Blah&#8230;. http://www.blackberry.com/twitter NB1: I primarily use SocialScope on my BlackBerry. SocialScope&#8217;s terms of use prohibit me from showing screenshots of their beta. Hey, guys, I want to show everyone how great you are! NB2: Screenshots taken on a BlackBerry 9000 running OS 5.0 First Impressions I&#8217;ve never understood <a
href='http://shkspr.mobi/blog/index.php/2010/02/twitter-for-blackberry-review/'>[...]</a>]]></description> <content:encoded><![CDATA[<p>Blah blah Twitter&#8230;. Blah Blah BlackBerry&#8230; Blah Blah&#8230;. <a
href="http://www.blackberry.com/twitter">http://www.blackberry.com/twitter</a></p><p>NB1: I primarily use SocialScope on my BlackBerry. SocialScope&#8217;s terms of use prohibit me from showing screenshots of their beta. Hey, guys, I want to show everyone how great you are!</p><p>NB2: Screenshots taken on a BlackBerry 9000 running OS 5.0</p><h2>First Impressions</h2><p>I&#8217;ve never understood the need for a EULA. They&#8217;re long, confusing, boring and a <em>terrible </em>way to make a first impression on your customers.  Twitter for Blackberry has a <strong>30 page</strong> monstrosity.</p><div
id="attachment_1652" class="wp-caption aligncenter" style="width: 490px"><img
class="size-full wp-image-1652" title="EULA Hell" src="http://shkspr.mobi/blog/wp-content/uploads/2010/02/Capture7_49_30.jpg" alt="EULA Hell" width="480" height="320" /><p
class="wp-caption-text">EULA Hell</p></div><p>No one reads them, no one cares, find a better way.</p><h2>Good</h2><p>This app really shows off the power of the BlackBerry SDK. It&#8217;s a pity that more developers don&#8217;t make full use of it.</p><p>Tweets show up in your message list&#8230;.</p><div
id="attachment_1654" class="wp-caption aligncenter" style="width: 490px"><img
class="size-full wp-image-1654" title="Message Integration" src="http://shkspr.mobi/blog/wp-content/uploads/2010/02/Capture8_20_4.jpg" alt="Message Integration" width="480" height="320" /><p
class="wp-caption-text">Message Integration</p></div><p>&#8230;and can be opened from there.</p><div
id="attachment_1655" class="wp-caption aligncenter" style="width: 490px"><img
class="size-full wp-image-1655" title="Open From Message" src="http://shkspr.mobi/blog/wp-content/uploads/2010/02/Capture7_55_17.jpg" alt="Open From Message" width="480" height="320" /><p
class="wp-caption-text">Open From Message</p></div><p>Images can be sent directly to TwitPic.</p><div
id="attachment_1653" class="wp-caption aligncenter" style="width: 490px"><img
class="size-full wp-image-1653" title="Send To Twitter" src="http://shkspr.mobi/blog/wp-content/uploads/2010/02/Capture8_3_57.jpg" alt="Send To Twitter" width="480" height="320" /><p
class="wp-caption-text">Send To Twitter</p></div><p>Apps like SocialScope and UberTwitter also hook in to the OS so that you can click on any #hastag and @name and be taken directly to that page within the app. I wasn&#8217;t able to ascertain whether this functionality was available in this app.</p><h2>Bad</h2><p>Limited view space.  At best, you can view 2 tweets at a time before scrolling. That&#8217;s not a very efficient use of space.</p><div
id="attachment_1656" class="wp-caption aligncenter" style="width: 490px"><img
class="size-full wp-image-1656" title="The Tweets Went In Two By Two" src="http://shkspr.mobi/blog/wp-content/uploads/2010/02/Capture7_52_16.jpg" alt="The Tweets Went In Two By Two" width="480" height="320" /><p
class="wp-caption-text">The Tweets Went In Two By Two</p></div><p>Poor navigation.  You can&#8217;t simply scroll left or right to move between pages, you need to scroll all the way to the top, or open the menu.</p><div
id="attachment_1657" class="wp-caption aligncenter" style="width: 490px"><img
class="size-full wp-image-1657" title="Navigation" src="http://shkspr.mobi/blog/wp-content/uploads/2010/02/Capture7_52_32.jpg" alt="Navigation" width="480" height="320" /><p
class="wp-caption-text">Navigation</p></div><p>The software also doesn&#8217;t remember which tweet you were on before you left.  It always refreshes the timeline and jumps to the top.  This is really annoying and it&#8217;s a problem solved in both UberTwitter and SocialScope.</p><h2>Ugly</h2><p>Missing loads of features that many users have become accostomed to.</p><ul><li>URL expansion.  bit.ly/fjhgkdfhg means nothing &#8211; use their API to expand the URL</li><li>Embed images and media. Show a preview of flickr images, YouTube videos etc.  At the moment, it only appears to do TwitPic.</li><li>No OAuth!  This is partly due to Twitter&#8217;s broken mobile OAuth support.</li><li>No autocomplete. SocialScope will show a list of your friends when you type @ to allow you to quickly select them.</li></ul><h2>Conclusion</h2><p>This app is amazing&#8230; if you&#8217;ve never used UberTwitter or SocialScope.  I also found it to be marginally slower than the other apps.</p><p><a
href="http://shkspr.mobi/blog/?flattrss_redirect&amp;id=1650&amp;md5=5f602dbe09fd12c5089eeae77d1261e1" title="Flattr" target="_blank"><img
src="http://shkspr.mobi/blog/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded> <wfw:commentRss>http://shkspr.mobi/blog/index.php/2010/02/twitter-for-blackberry-review/feed/</wfw:commentRss> <slash:comments>1</slash:comments> <atom:link rel="payment" href="http://shkspr.mobi/blog/?flattrss_redirect&amp;id=1650&amp;md5=5f602dbe09fd12c5089eeae77d1261e1" type="text/html" /> </item> <item><title>Twitter and Linebreaks</title><link>http://shkspr.mobi/blog/index.php/2010/02/twitter-and-linebreaks/</link> <comments>http://shkspr.mobi/blog/index.php/2010/02/twitter-and-linebreaks/#comments</comments> <pubDate>Wed, 17 Feb 2010 11:45:21 +0000</pubDate> <dc:creator>Terence Eden</dc:creator> <category><![CDATA[mobile]]></category> <category><![CDATA[aral]]></category> <category><![CDATA[dabr]]></category> <category><![CDATA[feathers]]></category> <category><![CDATA[html]]></category> <category><![CDATA[php]]></category> <category><![CDATA[twitter]]></category><guid
isPermaLink="false">http://shkspr.mobi/blog/?p=1642</guid> <description><![CDATA[As any student of computer science knows, line breaks are confusing. There are styles of line breaks unique to Unix, Mac and Windows &#8211; so what should a web renderer do when faced with a newline command? In HTML, it&#8217;s simple, they should be ignored. But what when it is user generated text, not HTML? <a
href='http://shkspr.mobi/blog/index.php/2010/02/twitter-and-linebreaks/'>[...]</a>]]></description> <content:encoded><![CDATA[<p>As any student of computer science knows, <a
href="http://en.wikipedia.org/wiki/Newline">line breaks are confusing</a>. There are styles of line breaks unique to Unix, Mac and Windows &#8211; so what should a web renderer do when faced with a newline command?  In HTML, it&#8217;s simple, they should be ignored.  But what when it is user generated text, not HTML?</p><p>This was a problem I faced when trying to get Dabr to render the <a
href="http://en.wikipedia.org/wiki/ASCII_art">ASCII* art</a> produced by <a
href="http://aralbalkan.com/">Aral Balkan</a>&#8216;s <a
href="http://feathersapp.com/">Feathers App</a>.  Feathers uses line breaks to achieve images like&#8230;</p><pre>〰❀❃ Introducing ❃❀〰
My new iPhone app,
░░░▒█ Feathers █▒░░░
</pre><p>What&#8217;s confusing to me, as a developer is the inconsistent way Twitter handles line breaks.  For example&#8230;</p><p>Twitter&#8217;s website ignores line breaks.</p><div
id="attachment_1643" class="wp-caption aligncenter" style="width: 410px"><img
class="size-full wp-image-1643" title="Desktop Spacing" src="http://shkspr.mobi/blog/wp-content/uploads/2010/02/Desktop-Spacing.png" alt="Desktop Spacing" width="400" height="178" /><p
class="wp-caption-text">Desktop Spacing</p></div><p>Twitter Mobile, however, does line breaking correctly.</p><div
id="attachment_1644" class="wp-caption aligncenter" style="width: 330px"><img
class="size-full wp-image-1644" title="Android Spacing" src="http://shkspr.mobi/blog/wp-content/uploads/2010/02/Android-Spacing.png" alt="Android Spacing" width="320" height="480" /><p
class="wp-caption-text">Android Spacing</p></div><p>Twitter has no style guide for rendering and &#8211; if it did &#8211; appears to render inconsistently.  So, what&#8217;s the correct thing to do?</p><p>In my opinion, <strong>respect the user</strong>. If a user has indicted that they want something, it is a developer&#8217;s role to implement it (unless it causes severe problems for the system).</p><h2>How to achieve it?</h2><p>You could use all sorts of complex regular expressions to get line breaks and convert them.<br
/> Thankfully, PHP has this function built in with <a
href="http://uk.php.net/manual/en/function.nl2br.php">nl2br()</a> which will give you (X)HTML line breaks wherever a break occurs in the text.</p><h3>Footnote</h3><p>*Technically, Unicode Art. But that doesn&#8217;t have the same ring to it.</p><p><a
href="http://shkspr.mobi/blog/?flattrss_redirect&amp;id=1642&amp;md5=0d3aa180d4ac52bae4d97a8b448c8fc3" title="Flattr" target="_blank"><img
src="http://shkspr.mobi/blog/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded> <wfw:commentRss>http://shkspr.mobi/blog/index.php/2010/02/twitter-and-linebreaks/feed/</wfw:commentRss> <slash:comments>6</slash:comments> <atom:link rel="payment" href="http://shkspr.mobi/blog/?flattrss_redirect&amp;id=1642&amp;md5=0d3aa180d4ac52bae4d97a8b448c8fc3" type="text/html" /> </item> <item><title>Twitter&#8217;s new OAuth Problem</title><link>http://shkspr.mobi/blog/index.php/2010/02/twitter-oauth-problem/</link> <comments>http://shkspr.mobi/blog/index.php/2010/02/twitter-oauth-problem/#comments</comments> <pubDate>Fri, 12 Feb 2010 12:10:07 +0000</pubDate> <dc:creator>Terence Eden</dc:creator> <category><![CDATA[mobile]]></category> <category><![CDATA[politics]]></category> <category><![CDATA[usability]]></category> <category><![CDATA[dabr]]></category> <category><![CDATA[oauth]]></category> <category><![CDATA[security]]></category> <category><![CDATA[twitter]]></category><guid
isPermaLink="false">http://shkspr.mobi/blog/?p=1627</guid> <description><![CDATA[Twitter have announced that all third party site will have to use OAuth.  You will no longer be able to just type in your username and password to get access to Twitter via your favourite web client. Usually, I would be a big fan of this move &#8211; especially if it forces password anti-pattern sites <a
href='http://shkspr.mobi/blog/index.php/2010/02/twitter-oauth-problem/'>[...]</a>]]></description> <content:encoded><![CDATA[<p><a
href="http://groups.google.com/group/twitter-api-announce/browse_thread/thread/c2c4963061422f28?hl=en&amp;pli=1">Twitter have announced that all third party site will have to use OAuth</a>.  You will no longer be able to just type in your username and password to get access to Twitter via your favourite web client.</p><p>Usually, I would be a big fan of this move &#8211; especially if it forces <a
href="http://adactio.com/journal/1357">password anti-pattern</a> sites like <a
href="http://getsatisfaction.com/twitpic/topics/when_will_twitpic_implement_oauth">TwitPic to implement the new, secure standard</a>.</p><p>This means that you won&#8217;t be able to log in to a third party site by giving them your username and  password.  You will have to use OAuth to securely validate with the main Twitter site.</p><p>But &#8211; as ever &#8211; there&#8217;s a dark side to OAuth.</p><h2>Repressive Regimes</h2><p>One of the joys of Twitter is that its clients are decentralised from the main site.</p><p>This means that if Twitter is blocked in your country, you can use a third party client (like <a
href="http://dabr.co.uk/">Dabr</a>) to access it.</p><blockquote><pre>Twitter User -&gt; Dabr -&gt; Twitter API -&gt; Dabr -&gt; User</pre></blockquote><p>If Dabr became sufficiently popular to be blocked by an oppressive regime, you can switch to any one of the thousands of Twitter web clients.</p><p>OAuth <strong>forces </strong>you to the main Twitter site.  While you may visit Dabr to start with, you would be redirected to Twitter to complete OAuth.  If Twitter is blocked, you can&#8217;t connect.</p><h3>At a stroke, Twitter has shut itself off to anyone in a repressive country.</h3><p><a
href="http://groups.google.com/group/twitter-development-talk/browse_thread/thread/39b8b326d8b679c6">This has been picked up by some concerned users</a>.</p><h2>A (Hacky) Way Around It</h2><p>There&#8217;s really only one way around this problem.  The third party web client has to act as a man-in-the-middle.  There&#8217;s a patch for Dabr &#8211; developed by <a
href="http://code.google.com/u/cnyegle/" class="broken_link">cnyegle</a> &#8211; which will ask for a username and password, then proxy it to Twitter, get the OAuth token and tweet on behalf of the user.</p><p>From the user&#8217;s point of view, they are still giving the (potentially untrusted) site the username and password.</p><h2>Challenge Response</h2><p>This could be solved by implemented a challenge / response system.</p><ol><li>Alice visits the Dabr website.</li><li>Dabr asks Alice for her username (and <em>only</em> her username)</li><li>Dabr asks Twitter for the challenge associated with Alice&#8217;s username.</li><li>Twitter checks that Dabr is an authorised website (i.e. has signed up for OAuth).</li><li>Twitter returns the response:  A secret phrase which Alice has previously chosen.</li><li>Dabr displays this phrase to Alice.</li><li>Alice knows that Twitter trusts Dabr</li><li>Dabr asks Twitter for the password challenge.</li><li>Twitter returns that it requires the 3rd, 5th and last character from Alice&#8217;s password (the characters requested change randomly).</li><li>Dabr asks Alice for <em>only</em> those characters.</li><li>If Alice provides the correct characters, an OAuth token is granted to Dabr to tweet on behalf of Alice.</li></ol><p>This has the advantage of proving that Dabr is trusted (by displaying Alice&#8217;s pre-defined secret phrase) and mitigating the risk that Dabr is untrusted (by only revealing part of the password).</p><h2>Conclusion</h2><p>This is a very new area, and I&#8217;ve not had a chance to read through all of the proposals.  Nevertheless, it remains a fundamental problem that, if you can&#8217;t access a site, you need to delegate your trust to someone else.</p><p>I&#8217;m not a security expert &#8211; so I would appreciate someone pointing out the flaws in my reasoning.</p><p><a
href="http://shkspr.mobi/blog/?flattrss_redirect&amp;id=1627&amp;md5=3e2818252192289b33db318f3f3a2b2f" title="Flattr" target="_blank"><img
src="http://shkspr.mobi/blog/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded> <wfw:commentRss>http://shkspr.mobi/blog/index.php/2010/02/twitter-oauth-problem/feed/</wfw:commentRss> <slash:comments>4</slash:comments> <atom:link rel="payment" href="http://shkspr.mobi/blog/?flattrss_redirect&amp;id=1627&amp;md5=3e2818252192289b33db318f3f3a2b2f" type="text/html" /> </item> <item><title>Twitter OAuth &#8211; Mobile Failures</title><link>http://shkspr.mobi/blog/index.php/2010/02/twitter-oauth-mobile-failures/</link> <comments>http://shkspr.mobi/blog/index.php/2010/02/twitter-oauth-mobile-failures/#comments</comments> <pubDate>Sun, 07 Feb 2010 15:06:26 +0000</pubDate> <dc:creator>Terence Eden</dc:creator> <category><![CDATA[mobile]]></category> <category><![CDATA[usability]]></category> <category><![CDATA[dabr]]></category> <category><![CDATA[oauth]]></category> <category><![CDATA[security]]></category> <category><![CDATA[twitter]]></category><guid
isPermaLink="false">http://shkspr.mobi/blog/?p=1606</guid> <description><![CDATA[I&#8217;m a big fan of OAuth &#8211; despite some claims to the contrary. It&#8217;s an excellent way of teaching people not to stick their username and password into any old site which asks for it. Which is why I&#8217;m so incredibly disappointed in Twitter&#8217;s implementation of mobile OAuth. For a service which started out operating <a
href='http://shkspr.mobi/blog/index.php/2010/02/twitter-oauth-mobile-failures/'>[...]</a>]]></description> <content:encoded><![CDATA[<p>I&#8217;m a big fan of OAuth &#8211; <a
href="http://www.theregister.co.uk/2009/11/04/oauth_dark_side/">despite some claims to the contrary</a>.  It&#8217;s an excellent way of teaching people not to stick their username and password into any old site which asks for it.  Which is why I&#8217;m so incredibly disappointed in Twitter&#8217;s implementation of mobile OAuth.</p><p>For a service which started out operating by SMS, Twitter takes a surprisingly unenlightened view of mobile.  It&#8217;s main mobile service &#8211; <a
href="http://m.twitter.com/">http://m.twitter.com/</a> &#8211; is almost completely devoid of useful features.  That&#8217;s one of the main impetuses behind the development of <a
href="http://dabr.co.uk/">Dabr</a>.  Their latest mobile site &#8211; <a
href="http://mobile.twitter.com/">http://mobile.twitter.com/</a> &#8211; is really only suitable for the tiny minority of people who have smartphones.</p><p>So, understandably, many people use 3rd party sites like Dabr.  They are now faced with a dilemma &#8211; give an untrusted site their username and password or try to use OAuth on the mobile.</p><p>A few weeks ago came the <a
href="http://groups.google.com/group/twitter-development-talk/browse_thread/thread/084f57349587b3d2/">announcement that OAuth was finally ready for mobile</a>&#8230; Was it? No.  Once again a &#8220;mobile friendly&#8221; site designed with masses of JavaScript and guaranteed not to work with the majority of phones on the market.</p><p>Here&#8217;s how mobile OAuth looks on a variety of popular mobile phones.</p><h2>BlackBerry</h2><div
id="attachment_1607" class="wp-caption aligncenter" style="width: 480px"><img
class="size-full wp-image-1607" title="BlackBerry Twitter OAuth" src="http://shkspr.mobi/blog/wp-content/uploads/2010/02/BlackBerry-Twitter-OAuth.png" alt="BlackBerry Twitter OAuth" width="470" height="695" /><p
class="wp-caption-text">BlackBerry Twitter OAuth</p></div><p>While this looks pretty enough, it doesn&#8217;t work.  The buttons <em>aren&#8217;t clickable</em>.  I&#8217;ve tried with and without JavaScript.  No matter where I click, nothing happens.</p><h2>Android</h2><p>The Android&#8217;s User-Agent isn&#8217;t detected by Twitter as being a mobile phone.  While it&#8217;s true that the browser is very capable &#8211; the OAuth screen is a lot more usable when it&#8217;s in mobile mode.</p><div
id="attachment_1610" class="wp-caption aligncenter" style="width: 330px"><img
class="size-full wp-image-1610" title="Android Twitter OAuth" src="http://shkspr.mobi/blog/wp-content/uploads/2010/02/android2.png" alt="Android Twitter OAuth" width="320" height="480" /><p
class="wp-caption-text">Android Twitter OAuth</p></div><p>So, it works, but it doesn&#8217;t look nice.</p><h2>N95</h2><p>The N95 makes a good test phone because it&#8217;s popular.  Probably more popular than the iPhone.</p><div
id="attachment_1612" class="wp-caption aligncenter" style="width: 250px"><img
class="size-full wp-image-1612" title="N95 Twitter OAuth" src="http://shkspr.mobi/blog/wp-content/uploads/2010/02/Screenshot0106.png" alt="N95 Twitter OAuth" width="240" height="320" /><p
class="wp-caption-text">N95 Twitter OAuth</p></div><div
id="attachment_1613" class="wp-caption aligncenter" style="width: 250px"><img
class="size-full wp-image-1613" title="N95 Twitter OAuth" src="http://shkspr.mobi/blog/wp-content/uploads/2010/02/Screenshot0108.png" alt="N95 Twitter OAuth" width="240" height="320" /><p
class="wp-caption-text">N95 Twitter OAuth</p></div><p>It&#8217;s not pretty &#8211; but at least it works.</p><h2>Others</h2><p>The Sharp GX-10 is my default test phone.  One of the first phones with a colour HTML browser.  If your site can work on this phone, it will work on any phone.  There are no screenshot capabilities for this phone &#8211; but rest assured, it does not work.</p><p>The three phones I&#8217;ve demo&#8217;d above are very popular modern phones &#8211; AKA the minority.  If they don&#8217;t work well, what chance for the people using older phones?</p><p>Useless!  How hard can it be?  All it needs is a username field, a password field and a button.  That&#8217;s just about the most basic page imaginable.  It should be child&#8217;s play to make it work on mobile.</p><p>This was <a
href="http://code.google.com/p/twitter-api/issues/detail?id=395">first raised in March 2009 on Twitter&#8217;s issues list</a>. It&#8217;s currently the <em>most popular</em> bug.</p><p>So, we&#8217;re stuck in a dire situation.  Third-Party mobile sites get access to Twitter users&#8217; passwords because Twitter are unable or unwilling to develop a <em>simple</em> OAuth form.  It would be fascinating to know how many of Twitter&#8217;s security breaches are down to corrupt or insecure 3rd party sites which leak passwords.</p><p><a
href="http://shkspr.mobi/blog/?flattrss_redirect&amp;id=1606&amp;md5=de898d729cb42f915edb82f089063071" title="Flattr" target="_blank"><img
src="http://shkspr.mobi/blog/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded> <wfw:commentRss>http://shkspr.mobi/blog/index.php/2010/02/twitter-oauth-mobile-failures/feed/</wfw:commentRss> <slash:comments>4</slash:comments> <atom:link rel="payment" href="http://shkspr.mobi/blog/?flattrss_redirect&amp;id=1606&amp;md5=de898d729cb42f915edb82f089063071" type="text/html" /> </item> <item><title>Dabr Widget for 360 H1</title><link>http://shkspr.mobi/blog/index.php/2010/01/dabr-widget-for-360-h1/</link> <comments>http://shkspr.mobi/blog/index.php/2010/01/dabr-widget-for-360-h1/#comments</comments> <pubDate>Thu, 21 Jan 2010 11:30:38 +0000</pubDate> <dc:creator>Terence Eden</dc:creator> <category><![CDATA[mobile]]></category> <category><![CDATA[360]]></category> <category><![CDATA[dabr]]></category> <category><![CDATA[jil]]></category> <category><![CDATA[limo]]></category> <category><![CDATA[twitter]]></category> <category><![CDATA[vodafone]]></category> <category><![CDATA[widgets]]></category><guid
isPermaLink="false">http://shkspr.mobi/blog/?p=1557</guid> <description><![CDATA[I&#8217;ve written a very basic JIL widget to launch dabr.  You can grab it from http://shkspr.mobi/Dabr.wgt I&#8217;ve tested this to work on the Vodafone 360 H1 &#8211; but it should work with any JIL handset. Because it isn&#8217;t certified, you may need to dial *#35767# to remove the H1&#8242;s security check. The code is very <a
href='http://shkspr.mobi/blog/index.php/2010/01/dabr-widget-for-360-h1/'>[...]</a>]]></description> <content:encoded><![CDATA[<p>I&#8217;ve written a very basic JIL widget to launch <a
href="http://m.dabr.co.uk/">dabr</a>.  You can grab it from <a
href="http://shkspr.mobi/Dabr.wgt" class="broken_link">http://shkspr.mobi/Dabr.wgt</a></p><p><a
href="http://shkspr.mobi/blog/wp-content/uploads/2010/01/Dabr-on-360.jpg"><img
class="aligncenter size-full wp-image-1559" title="Dabr on 360" src="http://shkspr.mobi/blog/wp-content/uploads/2010/01/Dabr-on-360.jpg" alt="" width="400" height="315" /></a></p><p>I&#8217;ve tested this to work on the Vodafone 360 H1 &#8211; but it should work with any <a
href="http://www.jil.org/">JIL</a> handset.</p><p>Because it isn&#8217;t certified, you may need to dial</p><pre>*#35767#</pre><p>to remove the <a
href="http://www.jil.org/jil-forums/posts/list/176.page#525">H1&#8242;s security check</a>.</p><p>The code is very simple.  The JIL SDK allows you to call specific phone application &#8211; in this case, all I&#8217;ve done is invoked the browser.</p><pre>&lt;body&gt;
   &lt;script type="text/javascript"&gt;
      Widget.openURL("http://m.dabr.co.uk/");
   &lt;/script&gt;
   &lt;div&gt;
      Launching Dabr!
   &lt;/div&gt;
&lt;/body&gt;</pre><p>One thing to note, if you&#8217;re deploying the widgets from your website, ensure you have set the MIME type to &#8220;application/widget&#8221; &#8211; as per the <a
href="http://www.w3.org/TR/widgets/#media-type-registration-for-applicationw">W3C standards</a> &#8211; otherwise many devices won&#8217;t recognise it as a valid widget.</p><p>If you&#8217;re interest in developing for this platform, there&#8217;s a <a
href="http://widget.developer.vodafone.com/en/" class="broken_link">€1,000,000 bounty up for grabs</a>.  There&#8217;s also a <a
href="http://jil.vodafone.com/app_planet/" class="broken_link">Dev Camp at Mobile World Congress</a> this year.</p><p>I work for Vodafone &#8211; this is my personal blog, I don&#8217;t to speak for them.  All opinions, claims and mistakes are my own.</p><p><a
href="http://shkspr.mobi/blog/?flattrss_redirect&amp;id=1557&amp;md5=50fd357feb69187aafe89fbea5478d3d" title="Flattr" target="_blank"><img
src="http://shkspr.mobi/blog/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded> <wfw:commentRss>http://shkspr.mobi/blog/index.php/2010/01/dabr-widget-for-360-h1/feed/</wfw:commentRss> <slash:comments>1</slash:comments> <atom:link rel="payment" href="http://shkspr.mobi/blog/?flattrss_redirect&amp;id=1557&amp;md5=50fd357feb69187aafe89fbea5478d3d" type="text/html" /> </item> <item><title>Tweeting via QR</title><link>http://shkspr.mobi/blog/index.php/2009/12/tweeting-via-qr/</link> <comments>http://shkspr.mobi/blog/index.php/2009/12/tweeting-via-qr/#comments</comments> <pubDate>Fri, 18 Dec 2009 10:00:03 +0000</pubDate> <dc:creator>Terence Eden</dc:creator> <category><![CDATA[mobile]]></category> <category><![CDATA[qr]]></category> <category><![CDATA[qr code]]></category> <category><![CDATA[twitter]]></category><guid
isPermaLink="false">http://shkspr.mobi/blog/?p=1418</guid> <description><![CDATA[BBH Labs &#8211; a marketing agency&#8217;s &#8220;Skunkworks&#8221; &#8211; recently blogged about using QR Codes to send messages via Twitter. There approach was interesting, but as I commented, there are ways to improve it. If you scan in the above QR code, it will take you to Twitter and pre-populate your status with &#8220;@edent&#8221;. You can, <a
href='http://shkspr.mobi/blog/index.php/2009/12/tweeting-via-qr/'>[...]</a>]]></description> <content:encoded><![CDATA[<p>BBH Labs &#8211; a marketing agency&#8217;s &#8220;Skunkworks&#8221; &#8211; recently <a
href="http://bbh-labs.com/using-qr-codes-to-update-twitter">blogged about using QR Codes to send messages via Twitter</a>.<br
/> There approach was interesting, but as <a
href="http://bbh-labs.com/using-qr-codes-to-update-twitter/comment-page-1#comment-1868">I commented</a>, there are ways to improve it.</p><p
style="text-align: center;"><a
title="Tweet Me Via QR by terenceeden, on Flickr" href="http://www.flickr.com/photos/edent/4189333623/"><img
class="aligncenter" src="http://farm3.static.flickr.com/2606/4189333623_6c7e6b18e1_o.png" alt="Tweet Me Via QR" width="148" height="148" /></a></p><p>If you scan in the above QR code, it will take you to Twitter and pre-populate your status with &#8220;@edent&#8221;.  You can, of course, set it to be any message you like.</p><p>There are two key things to remember with QR codes.</p><ol><li>Keep the information in them short to ensure readability.  The more characters you use, the larger the code and the harder it is to scan.  You can use URL shortners to do this if you have a long message.</li><li>Make it mobile. QR codes are scanned by mobile phones. The information is looked at on a phone screen.  You should always direct people to the mobile version of your site.  In this case &#8211; <a
href="http://m.twitter.com">m.twitter.com</a></li></ol><p><a
href="http://shkspr.mobi/blog/?flattrss_redirect&amp;id=1418&amp;md5=b908ca0c47a2c11f8ff0d8143aa7dfa7" title="Flattr" target="_blank"><img
src="http://shkspr.mobi/blog/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded> <wfw:commentRss>http://shkspr.mobi/blog/index.php/2009/12/tweeting-via-qr/feed/</wfw:commentRss> <slash:comments>1</slash:comments> <atom:link rel="payment" href="http://shkspr.mobi/blog/?flattrss_redirect&amp;id=1418&amp;md5=b908ca0c47a2c11f8ff0d8143aa7dfa7" type="text/html" /> </item> <item><title>Seesmic Twitter Client for BlackBerry</title><link>http://shkspr.mobi/blog/index.php/2009/11/seesmic-twitter-client-for-blackberry/</link> <comments>http://shkspr.mobi/blog/index.php/2009/11/seesmic-twitter-client-for-blackberry/#comments</comments> <pubDate>Sun, 22 Nov 2009 07:00:04 +0000</pubDate> <dc:creator>Terence Eden</dc:creator> <category><![CDATA[mobile]]></category> <category><![CDATA[usability]]></category> <category><![CDATA[blackberry]]></category> <category><![CDATA[dabr]]></category> <category><![CDATA[nablopomo]]></category> <category><![CDATA[twitter]]></category> <category><![CDATA[ubertwitter]]></category><guid
isPermaLink="false">http://shkspr.mobi/blog/?p=1232</guid> <description><![CDATA[Seesmic, a service I&#8217;ve not tried before, have released a Twitter client for the BlackBerry. Is it any good? How does it compare with the features of Dabr or the usability of UberTwitter? Find out! Getting the client was fairly simple, but could be better. Simply visiting http://seesmic.com was enough to bring up a mobile <a
href='http://shkspr.mobi/blog/index.php/2009/11/seesmic-twitter-client-for-blackberry/'>[...]</a>]]></description> <content:encoded><![CDATA[<p><a
href="http://seesmic.com/">Seesmic</a>, a service I&#8217;ve not tried before, have released a Twitter client for the BlackBerry.  Is it any good? How does it compare with the features of <a
href="http://m.dabr.co.uk/">Dabr</a> or the usability of <a
href="http://www.ubertwitter.com/">UberTwitter</a>? Find out!</p><p>Getting the client was fairly simple, but could be better.  Simply visiting <a
href="http://seesmic.com">http://seesmic.com</a> was enough to bring up a mobile friendly page with download instructions.<br
/> <a
href="http://shkspr.mobi/blog/wp-content/uploads/2009/11/Capture9_25_27.jpg"><img
class="aligncenter size-full wp-image-1233" title="Capture9_25_27" src="http://shkspr.mobi/blog/wp-content/uploads/2009/11/Capture9_25_27.jpg" alt="Capture9_25_27" width="480" height="320" /></a><br
/> However, scrolling down presented this mess.<br
/> <a
href="http://shkspr.mobi/blog/wp-content/uploads/2009/11/Capture9_25_41.jpg"><img
class="aligncenter size-full wp-image-1234" title="Capture9_25_41" src="http://shkspr.mobi/blog/wp-content/uploads/2009/11/Capture9_25_41.jpg" alt="Capture9_25_41" width="480" height="320" /></a><br
/> You simply can&#8217;t rely on users to know what make, model or firmware version they have.  Use the user-agent string to do as much of the hard work as possible.  If a user tries to install an incompatible version, it won&#8217;t work and they&#8217;ll blame you.</p><p>The download itself is a sprightly 172KB and installs very quickly &#8211; it also doesn&#8217;t require a reboot.<br
/> <a
href="http://shkspr.mobi/blog/wp-content/uploads/2009/11/Capture9_26_9.jpg"><img
class="aligncenter size-full wp-image-1235" title="Capture9_26_9" src="http://shkspr.mobi/blog/wp-content/uploads/2009/11/Capture9_26_9.jpg" alt="Capture9_26_9" width="480" height="320" /></a><br
/> Once you&#8217;ve signed in, the main interface is very simple.  UberTwitter, for example, presents the user with complex set-up options on the first run.  Seesmic gets straight to the action.<br
/> <a
href="http://shkspr.mobi/blog/wp-content/uploads/2009/11/Capture9_27_55.jpg"><img
class="aligncenter size-full wp-image-1236" title="Capture9_27_55" src="http://shkspr.mobi/blog/wp-content/uploads/2009/11/Capture9_27_55.jpg" alt="Capture9_27_55" width="480" height="320" /></a><br
/> Seesmic is entirely menu driven &#8211; there are no shortcut keys.  UberTwitter allows me to hit R for reply &#8211; on Seesmic, I have to delve into the menus.  Luckily, they&#8217;re short and have obvious names.<br
/> <a
href="http://shkspr.mobi/blog/wp-content/uploads/2009/11/Capture9_28_1.jpg"><img
class="aligncenter size-full wp-image-1237" title="Capture9_28_1" src="http://shkspr.mobi/blog/wp-content/uploads/2009/11/Capture9_28_1.jpg" alt="Capture9_28_1" width="480" height="320" /></a><br
/> Reading a tweet gives the usual option, hashtags and @s are hyperlinked &#8211; as are web addresses.<br
/> <a
href="http://shkspr.mobi/blog/wp-content/uploads/2009/11/Capture9_29_20.jpg"><img
class="aligncenter size-full wp-image-1238" title="Capture9_29_20" src="http://shkspr.mobi/blog/wp-content/uploads/2009/11/Capture9_29_20.jpg" alt="Capture9_29_20" width="480" height="320" /></a><br
/> On usability flaw, the cursor is at the top of the screen.  A user has to scroll through the &#8220;Web&#8221; hyperlink before getting to the links within the tweet.</p><p>Again, because there are no keyboard shortcuts, everything has to go through the menu.<br
/> <a
href="http://shkspr.mobi/blog/wp-content/uploads/2009/11/Capture9_29_46.jpg"><img
class="aligncenter size-full wp-image-1240" title="Capture9_29_46" src="http://shkspr.mobi/blog/wp-content/uploads/2009/11/Capture9_29_46.jpg" alt="Capture9_29_46" width="480" height="320" /></a><br
/> Searching is problematic.<br
/> <a
href="http://shkspr.mobi/blog/wp-content/uploads/2009/11/Capture9_31_8.jpg"><img
class="aligncenter size-full wp-image-1241" title="Capture9_31_8" src="http://shkspr.mobi/blog/wp-content/uploads/2009/11/Capture9_31_8.jpg" alt="Capture9_31_8" width="480" height="320" /></a><br
/> Pressing enter doesn&#8217;t start a search, it inserts a new line.<br
/> The search button isn&#8217;t the first thing you get to when you scroll down.<br
/> While the results are standard, this odd error message kept popping up.<br
/> <a
href="http://shkspr.mobi/blog/wp-content/uploads/2009/11/Capture9_31_27.jpg"><img
class="aligncenter size-full wp-image-1242" title="Capture9_31_27" src="http://shkspr.mobi/blog/wp-content/uploads/2009/11/Capture9_31_27.jpg" alt="Capture9_31_27" width="480" height="320" /></a><br
/> I encountered this error several times.</p><p>Writing new tweet has some great usability touches &#8211; and some real clunkers.<br
/> <a
href="http://shkspr.mobi/blog/wp-content/uploads/2009/11/Capture9_42_13.jpg"><img
class="aligncenter size-full wp-image-1245" title="Capture9_42_13" src="http://shkspr.mobi/blog/wp-content/uploads/2009/11/Capture9_42_13.jpg" alt="Capture9_42_13" width="480" height="320" /></a><br
/> The closer a user gets to filling the 140 characters, the more red the screen turns.<br
/> <a
href="http://shkspr.mobi/blog/wp-content/uploads/2009/11/Capture9_42_35.jpg"><img
class="aligncenter size-full wp-image-1246" title="Capture9_42_35" src="http://shkspr.mobi/blog/wp-content/uploads/2009/11/Capture9_42_35.jpg" alt="Capture9_42_35" width="480" height="320" /></a><a
href="http://shkspr.mobi/blog/wp-content/uploads/2009/11/Capture9_47_4.jpg"><img
class="aligncenter size-full wp-image-1252" title="Capture9_47_4" src="http://shkspr.mobi/blog/wp-content/uploads/2009/11/Capture9_47_4.jpg" alt="Capture9_47_4" width="480" height="320" /></a><br
/> URLs can be automatically shortened and images can be added.  This shows one of the great usability failures of Seesmic.<br
/> <a
href="http://shkspr.mobi/blog/wp-content/uploads/2009/11/Capture9_38_58.jpg"><img
class="aligncenter size-full wp-image-1243" title="Capture9_38_58" src="http://shkspr.mobi/blog/wp-content/uploads/2009/11/Capture9_38_58.jpg" alt="Capture9_38_58" width="480" height="320" /></a><br
/> Rather than use the BlackBerry&#8217;s file select utility, it uses its own &#8211; and it&#8217;s dreadful.  Ugly looking, no ability to search, slow, no preview.  Overall, a real let-down.</p><p>I don&#8217;t know why companies often insist on creating their own versions of well established system functions.  Especially when they add nothing and remove plenty.</p><p>Sending a tweet was continually problematic for me.<br
/> <a
href="http://shkspr.mobi/blog/wp-content/uploads/2009/11/Capture9_43_55.jpg"><img
class="aligncenter size-full wp-image-1250" title="Capture9_43_55" src="http://shkspr.mobi/blog/wp-content/uploads/2009/11/Capture9_43_55.jpg" alt="Capture9_43_55" width="480" height="320" /></a><br
/> Although it eventually relented.<br
/> <a
href="http://shkspr.mobi/blog/wp-content/uploads/2009/11/Capture9_44_18.jpg"><img
class="aligncenter size-full wp-image-1251" title="Capture9_44_18" src="http://shkspr.mobi/blog/wp-content/uploads/2009/11/Capture9_44_18.jpg" alt="Capture9_44_18" width="480" height="320" /></a><br
/> Seesmic also makes great use of notifies, showing you on your home screen how many unread tweets you have.<br
/> <a
href="http://shkspr.mobi/blog/wp-content/uploads/2009/11/Capture9_40_42.jpg"><img
class="aligncenter size-full wp-image-1244" title="Capture9_40_42" src="http://shkspr.mobi/blog/wp-content/uploads/2009/11/Capture9_40_42.jpg" alt="Capture9_40_42" width="480" height="320" /></a><br
/> Overall, Seesmic isn&#8217;t a bad client.  There are a few rough-around-the-edges bugs and the file selection is atrocious but other than that, it works.  Power users like me will miss the shortcut keys of UberTwitter, and UT&#8217;s system-wide integration (uploading photos, capturing hashtags in emails etc.).  It lacks other features such as in-line photos, ability to see followers and friends, it also has no way of marking a tweet as a favourite or seeing favourites.</p><p>One feature it does have &#8211; a first in mobile twitter clients &#8211; is the ability to view lists.  You can&#8217;t add, edit or create &#8211; but you can see the lists you have created or are following.</p><p><a
href="http://shkspr.mobi/blog/wp-content/uploads/2009/11/Capture9_32_49.jpg"><img
class="aligncenter size-full wp-image-1266" title="Capture9_32_49" src="http://shkspr.mobi/blog/wp-content/uploads/2009/11/Capture9_32_49.jpg" alt="Capture9_32_49" width="480" height="320" /></a></p><h2>Conclusion</h2><p>Seesmic works well enough as a basic twitter client for BlackBerry &#8211; but there&#8217;s nothing exciting about it.</p><p><a
href="http://shkspr.mobi/blog/?flattrss_redirect&amp;id=1232&amp;md5=af5d1db65822ba52cc4cb37b09ea3864" title="Flattr" target="_blank"><img
src="http://shkspr.mobi/blog/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded> <wfw:commentRss>http://shkspr.mobi/blog/index.php/2009/11/seesmic-twitter-client-for-blackberry/feed/</wfw:commentRss> <slash:comments>2</slash:comments> <atom:link rel="payment" href="http://shkspr.mobi/blog/?flattrss_redirect&amp;id=1232&amp;md5=af5d1db65822ba52cc4cb37b09ea3864" type="text/html" /> </item> <item><title>Gig Review &#8211; Mitch Benn</title><link>http://shkspr.mobi/blog/index.php/2009/11/gig-review-mitch-benn/</link> <comments>http://shkspr.mobi/blog/index.php/2009/11/gig-review-mitch-benn/#comments</comments> <pubDate>Mon, 09 Nov 2009 12:18:41 +0000</pubDate> <dc:creator>Terence Eden</dc:creator> <category><![CDATA[/etc/]]></category> <category><![CDATA[comedy]]></category> <category><![CDATA[music]]></category> <category><![CDATA[nablopomo]]></category> <category><![CDATA[twitter]]></category><guid
isPermaLink="false">http://shkspr.mobi/blog/?p=1034</guid> <description><![CDATA[When I was a fresher at university, Mitch Benn played the union.  I don&#8217;t remember why I didn&#8217;t go.  I do remember being woken up by the guys in my halls banging on my door telling me that I&#8217;d missed a brilliant evening.  The CDs that they bought back from the gig were hilarious &#8211; <a
href='http://shkspr.mobi/blog/index.php/2009/11/gig-review-mitch-benn/'>[...]</a>]]></description> <content:encoded><![CDATA[<p
style="text-align: left;"><a
title="An awesome @mitchbenn gig at Bloomsbury Theatre tonight, pic ... on Twitpic" href="http://twitpic.com/ojxgm"><img
class="aligncenter" src="http://twitpic.com/show/thumb/ojxgm.jpg" alt="An awesome @mitchbenn gig at Bloomsbury Theatre tonight, pic ... on Twitpic" width="150" height="150" /></a><br
/> When I was a fresher at university, <a
href="http://www.mitchbenn.com/">Mitch Benn</a> played the union.  I don&#8217;t remember why I didn&#8217;t go.  I <em>do</em> remember being woken up by the guys in my halls banging on my door telling me that I&#8217;d missed a brilliant evening.  The CDs that they bought back from the gig were hilarious &#8211; the perfect antidote to looming finals.</p><p>Since missing him play <a
href="http://www.ueaticketbookings.co.uk/venues/uea-lcr1.aspx">10 years ago</a>, I&#8217;ve caught up with him on <a
href="http://www.bbc.co.uk/programmes/b006qgt7">The Now Show</a> and <a
href="http://twitter.com/MitchBenn">Twitter</a> (where I&#8217;m happy to report he&#8217;s a user of <a
href="http://m.dabr.co.uk/">Dabr</a> &#8211; the mobile <a
href="http://code.google.com/p/dabr/">Twitter client I code for</a>).</p><p>So now, on to his <a
href="http://www.thebloomsbury.com/event/run/1233">gig at The Bloomsbury Theatre</a>.  A few hundred people made it through the driving rain on a cold November night &#8211; and they were rewarded with the funniest set I&#8217;ve seen since&#8230; well&#8230; since Boffoonery earlier in the week!</p><p>The audience were, as Benn put it, a right bunch of weirdoes. A mixture of Radio 4 fans, prog-rockers, students, comedy buffs and &#8211; fairly obviously by the way they wooped during the opening bars of every song &#8211; some die-hard groupies.</p><p>As much as I love The Now Show, it&#8217;s obvious that Mitch is much better when freed from the constraints of the 90-second-topical-song format &#8211; his long form work is energetic, funny and surprising caustic.  That said, he skilfully took audience suggestions and composed a short topical song &#8211; <a
href="http://news.bbc.co.uk/2/hi/europe/8345550.stm">Nudey Bear</a> &#8211; during the interval.</p><p>For me, the highlight of the evening was &#8220;<a
href="http://www.we7.com/track/IKEA?trackId=1253796&amp;m=0">IKEA</a>&#8221; &#8211; hearing a hall full of people sing like demented Vikings while the band turned the volume up to 11 is a memory I&#8217;ll treasure forever.  You can <a
href="http://www.we7.com/track/IKEA?trackId=1253796&amp;m=0">listen to the track for free</a> at We7.</p><p>His <a
href="http://www.mitchbenn.com/gigs">current tour runs until the 27th of November</a> &#8211; walk, hitch-hike or drive to your nearest venue; Mitch Benn shouldn&#8217;t be missed.  I know I&#8217;m not going to leave it ten years before I next see him.</p><p><a
href="http://shkspr.mobi/blog/?flattrss_redirect&amp;id=1034&amp;md5=88664914aaf16c9d1dfd8673862e233c" title="Flattr" target="_blank"><img
src="http://shkspr.mobi/blog/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded> <wfw:commentRss>http://shkspr.mobi/blog/index.php/2009/11/gig-review-mitch-benn/feed/</wfw:commentRss> <slash:comments>1</slash:comments> <atom:link rel="payment" href="http://shkspr.mobi/blog/?flattrss_redirect&amp;id=1034&amp;md5=88664914aaf16c9d1dfd8673862e233c" type="text/html" /> </item> <item><title>Twitter, OAuth and Passwords &#8211; Oh My!</title><link>http://shkspr.mobi/blog/index.php/2009/11/twitter-oauth-and-passwords-oh-my/</link> <comments>http://shkspr.mobi/blog/index.php/2009/11/twitter-oauth-and-passwords-oh-my/#comments</comments> <pubDate>Wed, 04 Nov 2009 13:04:57 +0000</pubDate> <dc:creator>Terence Eden</dc:creator> <category><![CDATA[usability]]></category> <category><![CDATA[nablopomo]]></category> <category><![CDATA[oauth]]></category> <category><![CDATA[security]]></category> <category><![CDATA[twitter]]></category><guid
isPermaLink="false">http://shkspr.mobi/blog/?p=994</guid> <description><![CDATA[Twitter has a gaping security hole.  Changing your password won&#8217;t stop malicious users logging in as you! I received a rather worrying email from Twitter.  Apparently they thought my password had been compromised and needed to be reset. After checking to see if it was valid, I went and changed my password.  Any site which <a
href='http://shkspr.mobi/blog/index.php/2009/11/twitter-oauth-and-passwords-oh-my/'>[...]</a>]]></description> <content:encoded><![CDATA[<p>Twitter has a gaping security hole.  Changing your password <strong>won&#8217;t stop malicious users logging in as you!</strong></p><p>I received a rather worrying email from Twitter.  Apparently they thought my password had been compromised and needed to be reset.</p><div
id="attachment_996" class="wp-caption aligncenter" style="width: 310px"><img
class="size-medium wp-image-996" title="twitpass" src="http://shkspr.mobi/blog/wp-content/uploads/2009/11/twitpass-300x192.jpg" alt="Reset Your Twitter Password" width="300" height="192" /><p
class="wp-caption-text">Reset Your Twitter Password</p></div><p>After checking to see if it was valid, I went and changed my password.  Any site which relied on a cookie to post to Twitter would have been blocked out. Ha! Gotcha, suckers!</p><h2>The OAuth Problem</h2><p>OAuth tokens are <strong>not</strong> revoked when the master password is changed.</p><p><a
href="http://oauth.net/">OAuth </a>is a great idea &#8211; rather than give your username and password to any random site, you log on to Twitter and tell them that you authorise the refering site.  The site gets an OAuth token and never gets to see your password.  Great! Right? Not really.</p><p>Let&#8217;s consider the following scenario.</p><p>Alice has a Twitter username and password.</p><p>Bob runs a Twitter site.</p><p>Alice visits Bob&#8217;s site.  Alice is security conscious and uses OAuth.</p><p>Eve somehow discovers Alice&#8217;s password.</p><p>Eve also visits Bob&#8217;s site and uses OAuth.</p><p>Alice gets suspicious about strange activity on her account and changes her password.</p><p>Because Bob&#8217;s site uses OAuth, it <strong>does not require</strong> either Alice <em>or</em> Eve to re-enter Alice&#8217;s password.</p><p>In this scenario, Alice has to visit <a
href="http://twitter.com/account/connections">Twitter&#8217;s OAuth Connections page</a> and revoke access to <em>all</em> the sites she has previously connected to.  Alice has no way of knowing when each site was last accessed.  She also doesn&#8217;t know which site Eve is using.</p><div
id="attachment_995" class="wp-caption aligncenter" style="width: 310px"><img
class="size-medium wp-image-995" title="twitoauth" src="http://shkspr.mobi/blog/wp-content/uploads/2009/11/twitoauth-300x192.jpg" alt="Twitter's OAuth Page" width="300" height="192" /><p
class="wp-caption-text">Twitter&#39;s OAuth Page</p></div><h2>The Problem</h2><p>Changing a password should &#8211; in the minds of most people &#8211; mean that you need to re-enter your password even if you have previously authenticated yourself.</p><p>In this scenario, changing the password does not revoke access to malicious users who have previously used your credentials.</p><p>Twitter should revoke all OAuth tokens when a user&#8217;s password is changed. It is the only way to ensure that stolen credentials cannot continue to be used after a user has changed their password.</p><h2>Addendum</h2><p>As I&#8217;ve made clear in the comments &#8211; this <em>isn&#8217;t</em> a vulnerability within OAuth per se.  It&#8217;s a usability issue which has strong security implications.</p><p>I spoke to Eran Hammer-Lahav (listed as <a
href="http://oauth.net/advisories">OAuth&#8217;s advisory contact</a>) who said:</p><blockquote><p>If you suspect someone stole your password, you should revoke any tokens you did not personally authorized. But there is no reason to revoke tokens just because you are changing password.</p></blockquote><p>While I appreciate this as the official line from those in the know, it does nothing to prevent a user who uses the same sites as you.  For example, I can see on every tweet that you use Dabr.  Therefore, I can safely OAuth myself as you on Dabr.  You&#8217;ll change your password, but you <em>won&#8217;t</em> revoke Dabr&#8217;s token because <strong>you personally authorised it</strong>.</p><h2>Continuing The Conversation</h2><p>Heise Online <a
href="http://www.heise.de/newsticker/meldung/Hintertuer-bei-Twitter-schliessen-850287.html">provides comentary in German</a> (<a
href="http://www.h-online.com/security/news/item/Shutting-Twitter-backdoors-850717.html">English version</a>)</p><p>El Reg has a <a
href="http://www.theregister.co.uk/2009/11/04/oauth_dark_side/">feature about Twitter and OAuth</a>.</p><p>There&#8217;s also an <a
href="http://news.ycombinator.com/item?id=921619">interesting discussion over at Hacker News</a>.</p><p><a
href="http://shkspr.mobi/blog/?flattrss_redirect&amp;id=994&amp;md5=08426006de3bc0e8ec4dff9ff967a391" title="Flattr" target="_blank"><img
src="http://shkspr.mobi/blog/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded> <wfw:commentRss>http://shkspr.mobi/blog/index.php/2009/11/twitter-oauth-and-passwords-oh-my/feed/</wfw:commentRss> <slash:comments>39</slash:comments> <atom:link rel="payment" href="http://shkspr.mobi/blog/?flattrss_redirect&amp;id=994&amp;md5=08426006de3bc0e8ec4dff9ff967a391" type="text/html" /> </item> <item><title>Twitter Favourites</title><link>http://shkspr.mobi/blog/index.php/2009/10/twitter-favourites/</link> <comments>http://shkspr.mobi/blog/index.php/2009/10/twitter-favourites/#comments</comments> <pubDate>Wed, 28 Oct 2009 14:18:30 +0000</pubDate> <dc:creator>Terence Eden</dc:creator> <category><![CDATA[/etc/]]></category> <category><![CDATA[cwu]]></category> <category><![CDATA[fail]]></category> <category><![CDATA[favourites]]></category> <category><![CDATA[royal mail]]></category> <category><![CDATA[twitter]]></category><guid
isPermaLink="false">http://shkspr.mobi/blog/?p=871</guid> <description><![CDATA[What Are Twitter Favourites? Twitter allows you to mark certain posts as favourites.  You may do this for a number of reasons &#8211; because you thought it was funny or interesting, because you want to reply to it later, or as a general bookmark feature They&#8217;re Private, Right? Wrong. You can see any Twitter user&#8217;s <a
href='http://shkspr.mobi/blog/index.php/2009/10/twitter-favourites/'>[...]</a>]]></description> <content:encoded><![CDATA[<h2>What Are Twitter Favourites?</h2><p><a
href="http://help.twitter.com/forums/10711/entries/14214">Twitter allows you to mark certain posts as favourites</a>.  You may do this for a number of reasons &#8211; because you thought it was funny or interesting, because you want to reply to it later, or as a general bookmark feature</p><h2>They&#8217;re Private, Right?</h2><p>Wrong. You can see any Twitter user&#8217;s favourites &#8211; even if they&#8217;ve protected their tweets. You can&#8217;t see the <em>tweets</em> of protected users.  Here are my favourites <a
href="http://twitter.com/edent/favorites">http://twitter.com/edent/favorites</a></p><p>You can also see <a
href="http://favotter.matope.com/en/user.php?user=edent" class="broken_link">who has marked your tweets as their favourites</a>.</p><h2>What Do Your Twitter Favourites Say About You?</h2><p>Let&#8217;s take a &#8220;random&#8221; example &#8211; <a
href="http://twitter.com/RoyalMailGroup">The Royal Mail</a>.  They only have <a
href="http://twitter.com/RoyalMailGroup/favorites">one favourite</a>.<br
/><div
class="quotedtweet" id="tw2632625416" style="background-color:#eef;padding:5px;margin-bottom:5px"><div
class="tw_user-info" style="padding:10px 10px 5px 0;float:left;text-align:center;width:100px;"><div
class="tw_thumb"> <a
href="http://twitter.com/njsykora" title="Francis Lambourne" class="quoting_pic" rel="external"><img
src="http://img.tweetimag.es/i/njsykora_n" alt="njsykora" /></a></div><div
class="tw_screen-name"> <em><a
href="http://twitter.com/njsykora" title="Twitter page : Francis Lambourne" rel="external">njsykora</a></em></div><div
class="tw_full-name"> <strong>(Francis Lambourne)</strong></div></div><div
class="tw_content" style="float: left; width: 500px; font: 20pt Georgia, Verdana, sans-serif; font-style: normal;"><div
class="tw_entry-content"> It is written into the CWU constitution that Royal Mail must go on strike once every 4 months. Whiny fucks.</div></div><div
style="clear: both; text-align: left;font-style:italic;margin-left:110px"><p
class="tw_meta tw_entry-meta" style="margin: 0;padding-top:5px"> <small> <span>On <a
href="http://twitter.com/njsykora/status/2632625416" rel="external">14-7-2009 14:15:53</a></span> <span>from <a
href="http://echofon.com/" rel="nofollow">Echofon</a></span> <span></span> </small></p></div></div></p><p>Nice.</p><p>If you&#8217;re advising on social media policy &#8211; be sure to tell your clients that what they mark as a favourite are open for all to see.  What they bookmark may not create a favourable impression.</p><p>Now, there may be perfectly legitimate reasons for clicking &#8220;favourite&#8221; on an obnoxious or offensive tweet. You may want to mark it so you can show your lawyers, blog about nasty people on the Internet or even a simple mis-click with the mouse.  But in the highly fraught world of social media &#8211; it pays to think twice about how your actions may be perceived by others.</p><p><a
href="http://shkspr.mobi/blog/?flattrss_redirect&amp;id=871&amp;md5=9e8e71776ecd8707b2aa019c2563a84f" title="Flattr" target="_blank"><img
src="http://shkspr.mobi/blog/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded> <wfw:commentRss>http://shkspr.mobi/blog/index.php/2009/10/twitter-favourites/feed/</wfw:commentRss> <slash:comments>1</slash:comments> <atom:link rel="payment" href="http://shkspr.mobi/blog/?flattrss_redirect&amp;id=871&amp;md5=9e8e71776ecd8707b2aa019c2563a84f" type="text/html" /> </item> </channel> </rss>
<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using disk: basic
Page Caching using disk: enhanced (Requested URI is rejected)

Served from: www.shkspr.mobi @ 2012-02-09 00:32:43 -->
