<?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>Jisc CETIS MASHe &#187; Google Apps</title>
	<atom:link href="http://mashe.hawksey.info/category/google-apps+twitter/feed/" rel="self" type="application/rss+xml" />
	<link>http://mashe.hawksey.info</link>
	<description>The musing of Martin Hawksey (EdTech Explorer)</description>
	<lastBuildDate>Mon, 10 Jun 2013 01:18:19 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
	<atom:link rel='hub' href='http://mashe.hawksey.info/?pushpress=hub'/>
		<item>
		<title>Notes on extracting the JISC CETIS twitter follower network</title>
		<link>http://mashe.hawksey.info/2012/03/notes-on-extracting-the-jisc-cetis-twitter-follower-network/</link>
		<comments>http://mashe.hawksey.info/2012/03/notes-on-extracting-the-jisc-cetis-twitter-follower-network/#comments</comments>
		<pubDate>Fri, 30 Mar 2012 15:13:51 +0000</pubDate>
		<dc:creator>Martin Hawksey</dc:creator>
				<category><![CDATA[Analytics]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[Google Apps]]></category>
		<category><![CDATA[Google Spreadsheet]]></category>
		<category><![CDATA[JISC CETIS]]></category>
		<category><![CDATA[Twitter]]></category>

		<guid isPermaLink="false">http://mashe.hawksey.info/?p=13130</guid>
		<description><![CDATA[As recently mentioned on Sheila&#8217;s work blog the way the @jisccetis twitter account is evolving. Up until recently this account was used as a broadcast channel, pushing out latest news to followers and not following back. This was balanced by members of staff having personal twitter accounts, engaging with the community. As with any community [...]]]></description>
				<content:encoded><![CDATA[<p>As recently mentioned on Sheila&#8217;s work blog the way <a href="http://blogs.cetis.ac.uk/sheilamacneill/2012/03/22/jisccetis-how-others-see-us/">the @jisccetis twitter account is evolving</a>. Up until recently this account was used as a broadcast channel, pushing out latest news to followers and not following back. This was balanced by members of staff having personal twitter accounts, engaging with the community. As with any community there’s going to be overlap with common friendships and Phil Barker (<a href="http://twitter.com/philbarker">@philbarker</a>) suggested it would be good to see the extended JISC CETIS twitter follower network.</p>
<p>In this post I’ll introduce some sketches* with results to explore and show you how the data was extracted.</p>
<p>*this is a term I’ve picked up from Tony Hirst along with explanatory and exploratory visualisations both presented in <a href="http://blog.ouseful.info/2012/02/29/more-thoughts-on-a-content-strategy-for-data-many-eyes-and-google-fusion-tables/">More Thoughts on a Content Strategy for Data</a>. The other thing I have sitting heavily in my thoughts is <a href="http://www.youtube.com/watch?v=UB2iYzKeej8">Eric Berlow’s TEDTalk</a> where he shows complex doesn’t always mean complicated (H/T <a href="http://twitter.com/PaulHollins">@PaulHollins</a>). My fear is I’m going to dump you with complicated exploratory sketches, when I should be giving you a simple explanatory answers.</p>
<h3>Dump #1 Blooming great</h3>
<p><a class="thickbox" href="http://mashe.hawksey.info/wp-content/uploads/2012/03/cetisStaffFollowersSml.jpg"><img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="cetisStaffFollowersSml" src="http://mashe.hawksey.info/wp-content/uploads/2012/03/cetisStaffFollowersSml_thumb.jpg" alt="Blooming great" width="704" height="494" border="0" /></a></p>
<p>For this first dump I’ve deliberately left it as low resolution as I only want to give you an overview and not analyse each node. In the graph you’ll spot dense patches of purple [A] these are made of the individual twitter screen names of people following one of the CETIS twitter accounts. So at the very top of the image there is a cluster of people following just me [B]. Other dense patches represents other groups of people following other CETIS Twitter accounts. In the centre of the main group [C] are Twitter users who follow 2 or more CETIS accounts. In Gephi by rolling over nodes it’s easy to explore who people follow. To the right of the graph [D] is the <a href="http://twitter.com/ArchimateTool">@ArchimateTool</a> account. This cluster has fewer connections to the main CETIS following. Finally around the centre of the graph are loose groups [E] of users who follow 2 CETIS staff.</p>
<p><strong>Update:</strong>&nbsp;Some other stats.&nbsp;The average out-degree in the network is 1.424 and 81% of the people in graph only follow one of the CETIS accounts. It would be interesting to see how this compares with other organisations. It&#8217;s important to also remember it&#8217;s not just about twitter (email probably still has the best reach and conversion)</p>
<p>[If you are desperate to explore an interactive version of this I’ve <a href="http://hawksey.info/gexf-js/index.html#cetisStaffFollowers.gexf">put a copy on my install of Gexf-JS viewer</a>.<a class="thickbox" href="http://mashe.hawksey.info/wp-content/uploads/2012/03/image16.png"><img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="image" src="http://mashe.hawksey.info/wp-content/uploads/2012/03/image_thumb8.png" alt="image" width="704" height="564" border="0" /></a></p>
<h3>Dump #2 Many Eyes</h3>
<p>Overall there are over 3,500 unique Twitter accounts that follow one or more CETIS staff accounts. 3,500 pairs of eyes looking at what CETIS or staff members are doing, with the potential to spread our message even further through their own networks. Here’s what a lot of those eyes look like (<a href="http://zoom.it/mgQg">click for larger version on zoom.it</a>):</p>
<p><a href="http://zoom.it/mgQg"><img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="image" src="http://mashe.hawksey.info/wp-content/uploads/2012/03/image17.png" alt="Many eyes (click to see on zoom.it)" width="704" height="392" border="0" /></a></p>
<p>I suppose the next question is do we have the right Twitter audience watching us.&nbsp; A quick wordcloud of the profile description of the staff following us:</p>
<p><a href="http://www.wordle.net/thumb/wrdl/5087157/JISC_CETIS_Followers"><img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="image" src="http://mashe.hawksey.info/wp-content/uploads/2012/03/image18.png" alt="CETIS Follower Description Wordle" width="704" height="444" border="0" /></a></p>
<h3>Getting the data</h3>
<p>My regular top traffic generating blog post is <a href="http://mashe.hawksey.info/2011/03/export-twitter-followers/">Export Twitter Followers and Friends using a Google Spreadsheet</a> which allows users to easily grab details of up to 5,000 (more if you don’t mind some code tinkering) Twitter account friend/followers. I don’t know how widely known it is but Twitter doesn’t just let you get your own friends/followers, you can get the data for any public Twitter account. So that’s what I did, snaffled details of who was following @jisccetis and JISC CETIS staff with public twitter accounts.</p>
<p>The way the spreadsheet is set up it generates a separate sheet for each persons follower details. To make it easy to import into Gephi/NodeXL I wrote <a href="https://gist.github.com/2252211">this short script</a>:</p>
<p><script src="https://gist.github.com/2252211.js?file=gistfile1.js"></script></p>
<p>Here’s <a href="https://docs.google.com/spreadsheet/ccc?key=0AqGkLMU9sHmLdE9HSDNOMmxneFpUZHdZd2pnS1BUb1E">a copy of the modded spreadsheet</a>. To use File &gt; Make a copy, run through the authentication instructions, grab some follower details from different accounts then run Twitter &gt; Combine follower sheets. If you’re going to be using Gephi last thing you should do before downloading as csv is change the column heading on the ‘combined’ sheet from screen_name to source.</p>
<h4>Using Gephi</h4>
<p>The best way I’ve found to get the data in Gephi is start a new project and then use the Import Spreadsheet option in the Data Laboratory pointing it to the csv file downloaded from Google Spreadsheet. I’ll let you play with manipulating the data. If you come up with any nice recipes please share ;)</p>
<h4>Using NodeXL</h4>
<p>Open a blank NodeXL template and then open the downloaded csv in Excel as a new workbook, then from the NodeXL ribbon Import &gt; Open workbook. Its worth ticking the extra columns as vertex 1 properties. Again I’ll let you play, any recipes please share (the many eyes image was generated by switching the nodes to image and using the profile_image_url extracted using the Google Spreadsheet and using a grid layout. If anyone has worked out how to using images as nodes in Gephi I’d be very interested to hear).</p>
<h3>So what</h3>
<p>I avoided going into any deep analysis with this as there are probably internal discussions to be had, such as, should we be targeting college staff more? What I hope this posts illustrates is it’s relatively easy to extract this type of data and start to get the very beginnings of some answers (e.g. how many unique followers do we have). There still a lot to unpick in this area so I’m sure I’ll be revisiting. My question to you is if you were doing this type of study what answers would you be looking for?</p>
]]></content:encoded>
			<wfw:commentRss>http://mashe.hawksey.info/2012/03/notes-on-extracting-the-jisc-cetis-twitter-follower-network/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Bye-bye Protovis Twitter Community Visualizer: Hello D3 Twitter Community Visualizer with EDGESExplorer Gadget</title>
		<link>http://mashe.hawksey.info/2011/12/edgesexplorer-gadget-twitter-community-visualizer/</link>
		<comments>http://mashe.hawksey.info/2011/12/edgesexplorer-gadget-twitter-community-visualizer/#comments</comments>
		<pubDate>Sun, 11 Dec 2011 22:53:07 +0000</pubDate>
		<dc:creator>Martin Hawksey</dc:creator>
				<category><![CDATA[Analytics]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[Google Apps]]></category>
		<category><![CDATA[Google Apps Script]]></category>
		<category><![CDATA[Google Spreadsheet]]></category>
		<category><![CDATA[Twitter]]></category>

		<guid isPermaLink="false">http://mashe.hawksey.info/?p=12729</guid>
		<description><![CDATA[The problem with starting my new OER Visualisation job is I’ve got less time to explorer my own little projects. This may be a blessing for some of my readers as it means I can do less waffling. So in brief: Tony came up with this brilliant solution for plotting twitter hashtag community graphs (it [...]]]></description>
				<content:encoded><![CDATA[<p><a href="http://mashe.hawksey.info/wp-content/uploads/2011/12/image2.png"><img src="http://mashe.hawksey.info/wp-content/uploads/2011/12/image2-300x181.png" alt="" title="image.png" width="300" height="181" class="alignright size-medium wp-image-12727" /></a>The problem with starting my <a href="http://mashe.hawksey.info/category/ooh-er/">new OER Visualisation job</a> is I’ve got less time to explorer my own little projects. This may be a blessing for some of my readers as it means I can do less waffling. So in brief:</p>
<p><a href="http://blog.ouseful.info/2011/04/12/using-protovis-to-visualise-connections-between-people-tweeting-a-particular-term/">Tony came up with this brilliant solution for plotting twitter hashtag community graphs</a> (it was brilliant because it used Google Social Graph API to get friend/follower relationships, no authentication required). Then I came along and <a href="http://mashe.hawksey.info/2011/06/friendviz/">dumped his code into Google Spreadsheet and wrapped the output in an embeddable gadget</a>. Google then launched Google Plus which appears to coincide with a deterioration in friend/follower information in Social Graph (one presumes my social network is better than yours type posturing).</p>
<p>So now here’s a new version of my spreadsheet which plays nice with Twitter and uses API authentication to get friend follower information:</p>
<p align="center"><strong>*** </strong><a href="https://docs.google.com/spreadsheet/ccc?key=0AqGkLMU9sHmLdEZ1WXczU05Lam5ESzgzMGFncWREM3c#gid=2"><strong>D3 Twitter Community Visualizer</strong></a><strong> ***</strong></p>
<p>The big news probably isn’t the spreadsheet (yawn), but how the data,shown below if your RSS reader hasn’t stripped it, is rendered. It was achieved by wrapping a version of my <a href="http://mashe.hawksey.info/2011/11/edgesexplorer-simple-force-layout-diagrams-from-edge-lists-stored-in-google-spreadsheets-nodexl-gephi/">EDGESExplorer tool</a> in a Google Gadget. This means if you’ve got any Google Spreadsheet with two columns of edge data (target/source) you can insert this gadget, display the data and embed elsewhere (if your host allows &lt;script&gt; inserts).</p>
<p><script src="https://docs.google.com/spreadsheet/gpub?url=http%3A%2F%2Frunjftm8i1lnoqdt9p75h42kvdsj4fdc-ss-opensocial.googleusercontent.com%2Fgadgets%2Fifr%3Fup_title%26up__table_query_url%3Dhttps%253A%252F%252Fdocs.google.com%252Fspreadsheet%252Ftq%253Fgid%253D5%2526range%253DA%25253AB%2526key%253D0AqGkLMU9sHmLdEZ1WXczU05Lam5ESzgzMGFncWREM3c%2526pub%253D1%26url%3Dhttp%253A%252F%252Fhosting.gmodules.com%252Fig%252Fgadgets%252Ffile%252F108150762089462716664%252Fedgeexplorer.xml%26spreadsheets%3Dspreadsheets&#038;height=334&#038;width=711"></script></p>
<p>To use the gadget in other Google Spreadsheets select Insert &gt; Gadget &gt; Custom then enter the url <a title="http://hosting.gmodules.com/ig/gadgets/file/108150762089462716664/edgeexplorer.xml" href="http://hosting.gmodules.com/ig/gadgets/file/108150762089462716664/edgeexplorer.xml">http://hosting.gmodules.com/ig/gadgets/file/108150762089462716664/edgeexplorer.xml</a></p>
<p>One thing to bear in mind in the gadget is unverified. The main impact of this is if you ‘Publish to the web’ or ‘File &gt; Share’ viewers won’t see anything (but as can seen above publish embed works). I’ve tried to <a href="https://support.google.com/docs/bin/answer.py?hl=en-GB&amp;answer=160111">get the gadget verified</a> but the <a href="http://code.google.com/apis/visualization/documentation/submitgadget.html">send it to us</a> link is broken (I’ve logged it as an issue so hopefully it will be fixed soon).</p>
<p>I have a job to go to in the morning so I’m going to let you ask/tell me it doesn’t work using the comments ;)</p>
]]></content:encoded>
			<wfw:commentRss>http://mashe.hawksey.info/2011/12/edgesexplorer-gadget-twitter-community-visualizer/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Sentiment Analysis of tweets: Comparison of ViralHeat and Text-Processing Sentiment APIs</title>
		<link>http://mashe.hawksey.info/2011/11/sentiment-analysis-of-tweets-comparison-of-viralheat-and-text-processing-sentiment-api/</link>
		<comments>http://mashe.hawksey.info/2011/11/sentiment-analysis-of-tweets-comparison-of-viralheat-and-text-processing-sentiment-api/#comments</comments>
		<pubDate>Thu, 10 Nov 2011 15:24:48 +0000</pubDate>
		<dc:creator>Martin Hawksey</dc:creator>
				<category><![CDATA[Analytics]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[Google Apps]]></category>
		<category><![CDATA[Google Spreadsheet]]></category>
		<category><![CDATA[Twitter]]></category>

		<guid isPermaLink="false">http://mashe.hawksey.info/?p=12629</guid>
		<description><![CDATA[So I make yet another foray into a world that I know little about, potentially making statements that are factually incorrect or just stupid, but I do so hoping that I can share some of my discoveries. All the data is available for your own analysis and comments are open if you want to put [...]]]></description>
				<content:encoded><![CDATA[<p>So I make yet another foray into a world that I know little about, potentially making statements that are factually incorrect or just stupid, but I do so hoping that I can share some of my discoveries. All the data is available for your own analysis and comments are open if you want to put me in my place <strong>&lt;-that was my disclaimer</strong></p>
<p>In this post I’m going to have another look at getting sentiment analysis data for a tweet stream and make a comparison between two free APIs (ViralHeat and Text-Processing) with some manually sentiment analysed data. In conclusion the Text-Processing Sentiment API data proved to be more accurate at calculating overall sentiment than ViralHeat, but both had a 18% probability of detecting the right sentiment within a tweet.&#160;&#160;&#160;&#160; </p>
<h3>Method</h3>
<p>Having already looked at <a href="http://mashe.hawksey.info/2011/09/viralheat-sentiment-api-and-a-google-spreadsheet/">Using the Viralheat Sentiment API and a Google Spreadsheet of conference tweets to find out how that keynote went down</a> I decided to reuse the data obtained from the tweet stream during Donald Clark’s ALT-C 2010 keynote. </p>
<h4>ViralHeat</h4>
<p>This data was generated my sending individual tweets (n. 561) to the ViralHeat Sentiment API, getting a <tt>positive</tt> or <tt>negative</tt> classification combined with a probability factor between 0 and 1 indicating confidence level. The positive/negative classifications were turned into numeric values by converting ‘<tt>positive</tt>’ to +1 and ‘<tt>negative</tt>’ to –1 and multiplying by probability. These values were accumulated and graphed to plot how tweet sentiment changed over time.</p>
<h4>Text-Processing</h4>
<p>Using a slight modification to the Google Apps Script used to collect ViralHeat data the same set of tweets were based to the <a href="http://www.mashape.com/apis/Text-Processing#sentiment">Text-Processing Sentiment API</a>. The data returned for each tweet consisted of the label ‘<tt>pos</tt>’ (positive), ‘<tt>neg</tt>’ (negative) or ‘<tt>neutral</tt>’ and probability for all of the labels. The label returned was determined by the API using a hierarchical classification whereby neutrality is calculated as a standalone value. If neutrality has a probability greater than 0.5 then the label returned is ‘neutral’. Positive and negative sentiment probability are balanced to add up to 1. To illustrate this below is an example of the data returned:</p>
<pre>{
        &quot;probability&quot;: {
                &quot;neg&quot;: 0.39680315784838732,
                &quot;neutral&quot;: 0.28207586364297021,
                &quot;pos&quot;: 0.60319684215161262
        },
        &quot;label&quot;: &quot;pos&quot;
} </pre>
<p>Similar to the ViralHeat data positive and negative labels were turned into numeric values by multiplying probability by +1 for positive and –1 for negative labels (neutral labels were ignored n.161). These values were also accumulated&#160;&#160; </p>
<h4>Manual Analysis</h4>
<p>The 561 tweets were printed off as a table with no extra data. Each tweet was individually assessed (by me – not trained in social research in anyway, btw) and marked as having positive, negative or neutral sentiment. These values were entered into the spreadsheet and converted to 1, –1 or 0 for positive, negative and neutral. Like the Text-Processing data neutral tweets were ignored (n. 422) leaving 139 data points</p>
<h3>Results</h3>
<p>The graph below shows the accumulated sentiment scores for the manual analysis compared to the results from Text-Processing and ViralHeat plotted against the time the tweet was made (09/07/2010 09:20:12 to 09/07/2010 10:21:55) [<a href="https://docs.google.com/spreadsheet/ccc?key=0AqGkLMU9sHmLdGVVVHBrYlB5ejhTb3lqMlhicTV0UGc&amp;hl=en_GB#gid=1" target="_blank">click to see interactive version</a> – takes a couple of seconds to appear]. </p>
<p>The graph shows that the ViralHeat scores display an overall positive trend whilst the manual analysis and Text-Processing scores show an overall negative sentiment in the tweets, perhaps suggesting that the Text-Processing data is more accurate at calculating overall sentiment than ViralHeat with the given data.<a href="https://docs.google.com/spreadsheet/ccc?key=0AqGkLMU9sHmLdGVVVHBrYlB5ejhTb3lqMlhicTV0UGc&amp;hl=en_GB#gid=1" target="_blank"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="1st Pass of Manual, Text-Porcessing and ViralHeat Sentiment Plotted Against Tweet Time" src="http://mashe.hawksey.info/wp-content/uploads/2011/11/image4.png" width="714" height="424" /></a>&#160;</p>
<p>As the ViralHeat data doesn’t appear to have hierarchical classification, which indicates if text is neutral, I decided to filter the data and only use results which had a probability factor within the top 10%. This resulted in a subset of ViralHeat data (n.56) which had a probability of greater than 0.987 and Text-Processing (n.40*) with a probability greater than 0.867. </p>
<p>*less because 161 data points were already excluded as they were neutral&#160;&#160;&#160; </p>
<p>The graph which includes only the top 10% of sentiment scores from ViralHeat and Text-Processing is shown below [<a href="https://docs.google.com/spreadsheet/ccc?key=0AqGkLMU9sHmLdGVVVHBrYlB5ejhTb3lqMlhicTV0UGc&amp;hl=en_GB#gid=11" target="_blank">click to see interactive version</a> – takes a couple of seconds to appear]. The overall effect of this filter is the overall positive and negative sentiment scores for both ViralHeat and Text-Processing are reduced (this is expected as their are less data points).&#160; </p>
<p><a href="https://docs.google.com/spreadsheet/ccc?key=0AqGkLMU9sHmLdGVVVHBrYlB5ejhTb3lqMlhicTV0UGc&amp;hl=en_GB#gid=11"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="Manual, Text-Processing and ViralHeat Top 10% Sentiment Plotted Against Tweet Time" src="http://mashe.hawksey.info/wp-content/uploads/2011/11/image5.png" width="714" height="418" /></a></p>
<p>Whilst it looks like Text-Processing is more accurate at detecting sentiment within a tweet on a tweet-by-tweet basis it’s a different story. When I manual recorded sentiment data for each tweet within the dataset I was able to assign 139 with either positive (n.56) or negative (n.83) sentiment. Text-Processing returned positive (n.81) and negative (n.319) for 400 tweets and ViralHeat returned positive (n.296) and negative (n.265) for 561 of the tweets. When comparing the returned sentiment with the manually processed tweets Text-processing returned 72 (18%) results&#160; with matching sentiment and ViralHeat 99 (18%).</p>
<p><iframe height="200" src="https://docs.google.com/spreadsheet/pub?hl=en_GB&amp;hl=en_GB&amp;key=0AqGkLMU9sHmLdGVVVHBrYlB5ejhTb3lqMlhicTV0UGc&amp;single=true&amp;gid=15&amp;output=html&amp;widget=true" frameborder="0" width="710"></iframe></p>
<h3>Conclusion</h3>
<p>Hmm. Sentiment analysis of individual tweets might only be 20% accurate using off the self tools with the data I looked at. This however might be enough if you are looking to filter large volumes of data. Both ViralHeat and Text-Processing have options that could potentially increase the accuracy by for example using a different text classification (it also worth noting that Text-Processing is built using the open source <a href="http://www.nltk.org/" target="_blank">Python Natural Language Toolkit</a> so even more tweaking is possible).&#160; </p>
<p>I’m sure more conclusion can be made so why not have a <a href="https://docs.google.com/spreadsheet/ccc?key=0AqGkLMU9sHmLdGVVVHBrYlB5ejhTb3lqMlhicTV0UGc&amp;hl=en_GB#gid=0" target="_blank">look at the data I’ve captured</a> and leave some notes in the comments ;)</p>
]]></content:encoded>
			<wfw:commentRss>http://mashe.hawksey.info/2011/11/sentiment-analysis-of-tweets-comparison-of-viralheat-and-text-processing-sentiment-api/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Twitter: How to archive event hashtags and create an interactive visualization of the conversation</title>
		<link>http://mashe.hawksey.info/2011/11/twitter-how-to-archive-event-hashtags-and-visualize-conversation/</link>
		<comments>http://mashe.hawksey.info/2011/11/twitter-how-to-archive-event-hashtags-and-visualize-conversation/#comments</comments>
		<pubDate>Mon, 07 Nov 2011 08:25:49 +0000</pubDate>
		<dc:creator>Martin Hawksey</dc:creator>
				<category><![CDATA[Google]]></category>
		<category><![CDATA[Google Apps]]></category>
		<category><![CDATA[Google Spreadsheet]]></category>
		<category><![CDATA[TAGSExplorer]]></category>
		<category><![CDATA[Twitter]]></category>
		<category><![CDATA[Visualisation]]></category>
		<category><![CDATA[#TAGSExplorer]]></category>

		<guid isPermaLink="false">http://mashe.hawksey.info/?p=12598</guid>
		<description><![CDATA[The use of Twitter to collecting tweets around an event hashtag allowing participants to share and contribute continues to grow and has even become part of mass media events, various TV shows now having and publicising their own tag. This resource is often lost in time, only tiny snippets being captured in blog posts or [...]]]></description>
				<content:encoded><![CDATA[<p>The use of Twitter to collecting tweets around an event hashtag allowing participants to share and contribute continues to grow and has even become part of mass media events, various TV shows now having and publicising their own tag. This resource is often lost in time, only tiny snippets being captured in blog posts or summaries using tools like Storify, which often loose the richness of individual conversations between participants.</p>
<p>It doesn’t have to be this way. Using a combination of Google Spreadsheets as a data source and a simple web interface to add interactivity it’s possible to let users explorer your entire event hashtag and replay any of conversations.</p>
<p style="text-align: center;"><a href="http://www.youtube.com/watch?v=ugayHzLnptE"><img class="aligncenter size-full wp-image-12618" title="Click to see example replay" src="http://mashe.hawksey.info/wp-content/uploads/2011/11/tw-tags.gif" alt="" width="700" height="541" /><br />
View example conversation replay</a></p>
<p style="text-align: center; font-weight: bold;"><a href="http://hawksey.info/tagsexplorer/?key=0AqGkLMU9sHmLdDJYMDZYR3FUcnVwWTkwLWpScnFIUXc&amp;sheet=ob7">Try out a LIVE version</a></p>
<p><strong>Update:</strong> If you are still struggling to understand the concept <a href="http://www.youtube.com/watch?v=LEj4d-IGERc&amp;feature=colike">Radical Punch have done a overview of this tool</a></p>
<p>Here&#8217;s how to archive event hashtags and create an interactive visualization of the conversation (written instructions below):</p>
<p align="center"><iframe src="http://www.youtube.com/embed/ZAiPoq2YWvA?rel=0&amp;hd=1" frameborder="0" width="710" height="391"></iframe><br />
<a href="http://www.youtube.com/watch?v=ZAiPoq2YWvA">Twitter: How to archive event hashtags and create an interactive visualization of the conversation</a></p>
<h3>Capturing the tweets</h3>
<p>Use <a href="https://docs.google.com/spreadsheet/ccc?key=0AqGkLMU9sHmLdFVzSzdXY0RxN211b1k0Uks3Z1hWYUE&amp;hl=en_GB&amp;newcopy">this Google Spreadsheet template</a>.</p>
<p>For more reliable data collection it&#8217;s recommended that you follow the steps to get authenticated API access to Twitter search results and setup a &#8216;script trigger&#8217; to automate collection. Here are instructions on how to do it:</p>
<ol>
<li>Open the <a href="https://docs.google.com/spreadsheet/ccc?key=0AqGkLMU9sHmLdFVzSzdXY0RxN211b1k0Uks3Z1hWYUE&amp;hl=en_GB&amp;newcopy" target="_blank">TAGS Google Spreadsheet</a> making a copy</li>
<li>Register for an API key with Twitter at <a href="http://dev.twitter.com/apps/new" target="_blank">http://dev.twitter.com/apps/new</a>. In the form these are the important bits:</li>
<ul>
<li><strong>Application Website</strong> = anything you like</li>
<li><strong>Application Type</strong> = Browser</li>
<li><strong>Callback URL</strong> = https://spreadsheets.google.com/macros</li>
<li><strong>Default Access type</strong> = Read-only</li>
</ul>
<li>Once finished filling in the form and accepting Twitter&#8217;s terms and conditions you&#8217;ll see a summary page which includes a <strong>Consumer Key and Consumer Secret</strong></li>
<li>Back in the Google Spreadsheet select <strong>Twitter &gt; API Authentication</strong> (you&#8217;ll need to select this option twice, the first time to authorise read/write access to the spreadsheet). Paste in your Consumer Key and Secret from the previous step and click &#8216;Save&#8217; (if the Twitter menu is not visible click on the blue button to show it)</li>
<li>From the spreadsheet select <strong>Tools &gt; Script Editor</strong> &#8230; and then <strong>Run &gt; authenticate</strong> and Authorize the script with Twitter using your Twitter account</li>
<li>While still in the Script Editor window select <strong>Triggers &gt; Current script&#8217;s triggers&#8230;</strong> and <strong>Add a new trigger</strong>. Select to run &#8216;collectTweets&#8217; as a &#8216;Time-driven&#8217; choosing a time period that suits your search (I usually collect 1500 tweets once a day, but increase to hourly during busy periods eg during a conference). Click &#8216;Save&#8217;<a href="http://mashe.hawksey.info/wp-content/uploads/2011/11/Capture.png"><img class="aligncenter size-full wp-image-12606" title="Script trigger settings" src="http://mashe.hawksey.info/wp-content/uploads/2011/11/Capture.png" alt="" width="603" height="172" /></a></li>
<li>Now close the Script Editor window. Back in the main spreadsheet on the <strong>Readme/Settings sheet</strong> enter the following settings (starting in cell B9):</li>
<ul>
<li><strong>Who are you =</strong> any web address that identifies you or your event</li>
<li><strong>Search term =</strong> what you are looking for eg <strong>#jiscel11</strong></li>
<li><strong>Period = default</strong></li>
<li><strong>No. results = 1500</strong> (this is the maximum Twitter allows)</li>
<li><strong>Continuous/paged = continuous</strong></li>
</ul>
<li>Click <strong>TAGS &gt; Run Now!</strong> to check you are collecting results into a &#8216;Archive&#8217; sheet</li>
<li>To allow the results to be visualised from the spreadsheet select <strong>File &gt; Publish to the web&#8230; </strong>You can choose to <strong>Publish All sheets</strong> or just the  Archive sheet. Make sure <strong>Automatically republish when changes are made is ticked</strong> and click <strong>Start publishing</strong></li>
</ol>
<h3>Creating a public interactive visualisation of the archived tweets</h3>
<ol>
<li><strong>Copy the url of the spreadsheet</strong> you just created</li>
<li>Visit <a href="http://hawksey.info/tagsexplorer" target="_blank">http://hawksey.info/tagsexplorer</a> and <strong>paste your spreadsheet url in the box</strong>, then click <strong>&#8216;get sheet names&#8217;</strong></li>
<li>When it loads the sheet names leave it on the default<strong> &#8216;Archive&#8217;</strong> and click <strong>&#8216;go&#8217;</strong></li>
<li>You now have a visualisation of your spreadsheet archive (click on nodes to delve deeper)</li>
<li><strong>To share the visualisation at the top right-click &#8216;link for this&#8217; which is a permanent link </strong>(as your archive grows and the spreadsheet is republished this visualisation will automatically grow)</li>
</ol>
<p><span style="font-family: 'Lucida Grande', 'Lucida Sans', 'Lucida Sans Unicode', Verdana, Helvetica, Arial, sans-serif;"><strong><br />
</strong></span></p>
]]></content:encoded>
			<wfw:commentRss>http://mashe.hawksey.info/2011/11/twitter-how-to-archive-event-hashtags-and-visualize-conversation/feed/</wfw:commentRss>
		<slash:comments>152</slash:comments>
		</item>
		<item>
		<title>Live Twitter data from FOTE #fote11 [Top Tweeters, Sentiment, Hashtag Network Diagram, Conversation Diagram]</title>
		<link>http://mashe.hawksey.info/2011/10/live-twitter-data-from-fote-fote11/</link>
		<comments>http://mashe.hawksey.info/2011/10/live-twitter-data-from-fote-fote11/#comments</comments>
		<pubDate>Fri, 07 Oct 2011 11:29:09 +0000</pubDate>
		<dc:creator>Martin Hawksey</dc:creator>
				<category><![CDATA[Analytics]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[Google Apps]]></category>
		<category><![CDATA[Google Spreadsheet]]></category>
		<category><![CDATA[Twitter]]></category>
		<category><![CDATA[#fote11]]></category>

		<guid isPermaLink="false">http://mashe.hawksey.info/?p=12464</guid>
		<description><![CDATA[Not at FOTE11 today (you can follow the live stream) but was interested in what data I could extract from the #fote11 twitter stream and process as the event unfolds. Most of the data here comes from a mashup of my Google Spreadsheet mashup. (This is perhaps putting Google Spreadsheets to the limit in terms [...]]]></description>
				<content:encoded><![CDATA[<p>Not at <a href="http://fote-conference.com/wordpress/" target="_blank">FOTE11 today</a> (you can <a href="http://fote11.kuluvalley.com/" target="_blank">follow the live stream</a>) but was interested in what data I could extract from the <a href="http://twitter.com/#!/search/%23fote11" target="_blank">#fote11 twitter stream</a> and process as the event unfolds. Most of the data here comes from a mashup of my <a href="http://mashe.hawksey.info/2011/02/twitteralyticsv2/" target="_blank">Google Spreadsheet mashup</a>. (This is perhaps putting Google Spreadsheets to the limit in terms of fetching data but lets see how it goes) </p>
<p><strong>Update:</strong> Some of these graphs may take a couple of seconds to appear [H/T <a href="http://twitter.com/johnmclear" target="_blank">@johnmclear</a>]</p>
<p><strong>Update 2:</strong> The interactive #fote community was freezing Internet Explorer so click through to see interactive version [H/T James Swansburg]</p>
<p><strong>Update 3:</strong> Added a second snapshot of the Twitter conversations to cover whole day</p>
<p><strong>Update 4:</strong> Coded the last snapshot with sentiment data from ViralHeat</p>
<h3>Summary Data</h3>
<p><iframe height="210" src="https://docs.google.com/spreadsheet/pub?key=0AqGkLMU9sHmLdFhoRVNwTDhKR09PUVdGaElVYWlZbEE&amp;single=true&amp;gid=72&amp;range=C1%3AH9&amp;output=html&amp;widget=true" frameborder="0" width="700"></iframe></p>
<h3>Guages</h3>
<table border="0" cellspace="3">
<tbody>
<tr>
<td><script src="https://docs.google.com/spreadsheet/gpub?url=http%3A%2F%2F0ktjprp9lkdpl36tkqilnfo7sutd589j-ss-opensocial.googleusercontent.com%2Fgadgets%2Fifr%3Fup_title%3DTweets%252Fmin%26up_minvalue%3D0%26up_maxvalue%3D15%26up_greenrange%3D0%253A10%26up_yellowrange%3D10%253A12%26up_redrange%3D12%253A15%26up_minorticks%3D5%26up__table_query_url%3Dhttps%253A%252F%252Fdocs.google.com%252Fspreadsheet%252Ftq%253Frange%253DF9%25253AG9%2526key%253D0AqGkLMU9sHmLdFhoRVNwTDhKR09PUVdGaElVYWlZbEE%2526gid%253D72%2526pub%253D1%26url%3Dhttp%253A%252F%252Fwww.google.com%252Fig%252Fmodules%252Fgauge.xml%26spreadsheets%3Dspreadsheets&amp;height=200&amp;width=100"></script></td>
<td><script src="https://docs.google.com/spreadsheet/gpub?url=http%3A%2F%2F0ktjprp9lkdpl36tkqilnfo7sutd589j-ss-opensocial.googleusercontent.com%2Fgadgets%2Fifr%3Fup_title%26up_minvalue%3D0%26up_maxvalue%3D1%26up_greenrange%3D0%253A0.2%26up_yellowrange%3D0.2%253A0.3%26up_redrange%3D0.3%253A1%26up_minorticks%3D5%26up__table_query_url%3Dhttps%253A%252F%252Fdocs.google.com%252Fspreadsheet%252Ftq%253Frange%253DF10%25253AG10%2526key%253D0AqGkLMU9sHmLdFhoRVNwTDhKR09PUVdGaElVYWlZbEE%2526gid%253D72%2526pub%253D1%26url%3Dhttp%253A%252F%252Fwww.google.com%252Fig%252Fmodules%252Fgauge.xml%26spreadsheets%3Dspreadsheets&amp;height=200&amp;width=100"></script></td>
</tr>
</tbody>
</table>
<h3>Archive of Tweets</h3>
<p>Here&#8217;s a <a href="https://docs.google.com/spreadsheet/ccc?key=0AqGkLMU9sHmLdFhoRVNwTDhKR09PUVdGaElVYWlZbEE&#038;hl=en_GB#gid=73">archive of the tweets from the event captured in a Google Spreadsheet</a>.<br />
<h3>Sentiment</h3>
<p><iframe height="500" src="https://docs.google.com/spreadsheet/pub?key=0AqGkLMU9sHmLdFhoRVNwTDhKR09PUVdGaElVYWlZbEE&amp;single=true&amp;gid=77&amp;output=html&amp;widget=true" frameborder="0" width="700"></iframe><a href="https://docs.google.com/spreadsheet/ccc?key=0AqGkLMU9sHmLdFhoRVNwTDhKR09PUVdGaElVYWlZbEE#gid=77" target="_blank">Open in new window</a></p>
<h3>#fote11 community</h3>
<p><a href="http://mashe.hawksey.info/fote11-community/" target="_blank"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto; padding-top: 0px" title="image" border="0" alt="#fote11 community [click for interactive version]" src="http://mashe.hawksey.info/wp-content/uploads/2011/10/image1.png" width="709" height="533" /></a></p>
<p>[The interactive version was freezing Internet Explorer so click through to see interactive version H/T James Swansburg]</p>
<h3>#fote11 conversations (made with NodeXL)</h3>
<p>Snapshot below taken at midday    <br />Node size = number of tweets with #fote11     <br />Graphing 1622 tweets</p>
<p><a class="thickbox" href="http://mashe.hawksey.info/wp-content/uploads/2011/10/fote11.jpg"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="fote11" border="0" alt="fote11 conversation network 1622 tweets" src="http://mashe.hawksey.info/wp-content/uploads/2011/10/fote11_thumb.jpg" width="704" height="468" /></a></p>
<p> Snapshot below taken post event  <br />Node size = number of tweets with #fote11   <br />Graphing 2649 tweets
<p><a class="thickbox" href="http://mashe.hawksey.info/wp-content/uploads/2011/10/fote11-all-day.jpg"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto; padding-top: 0px" title="fote11-all-day" border="0" alt="fote11 conversation network 2649 tweets" src="http://mashe.hawksey.info/wp-content/uploads/2011/10/fote11-all-day_thumb.jpg" width="704" height="415" /></a></p>
<h3>#fote11 conversations coded with sentiment data from ViralHeat</h3>
<p><a href="http://mashe.hawksey.info/wp-content/uploads/2011/10/fote11-all-day-sentiment.jpg" class="thickbox"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="fote11-all-day-sentiment" border="0" alt="#fote11 Twitter conversations coded with sentiment data from ViralHeat" src="http://mashe.hawksey.info/wp-content/uploads/2011/10/fote11-all-day-sentiment_thumb.jpg" width="704" height="415" /></a></p>
<p>Last graph for now. Using a combination of my <a href="http://mashe.hawksey.info/2011/10/using-google-spreadsheet-to-feed-nodexl/">Using Google Spreadsheets as a data source to analyse extended Twitter conversations in NodeXL (and Gephi)</a> and <a href="http://mashe.hawksey.info/2011/09/viralheat-sentiment-api-and-a-google-spreadsheet/">Using the Viralheat Sentiment API and a Google Spreadsheet of conference tweets to find out how that keynote went down</a> I was able to import sentiment data for each tweet (edge). I then accumulated the sentiment probability for each twitterer (vertex), -1 = 100% probability of negative sentiment +1 = 100% probability of positive sentiment, and averaged the overall sentiment by the number of tweets that person (vertex) made. Using the autofill the vertices were coloured by average sentiment probability (green = +ve, red = –ve) and grouped by overall positive sentiment, overall negative sentiment and no data. </p>
<p>The graph shows that over 80% (n.296) of #fote11 hash taggers (n.355) posted tweets with an overall positive sentiment detection. </p>
<p>Somethings worth noting with this data. Sentiment analysis is being analysed using machine detection (ie it might be wrong). Someone with overall negative sentiment doesn’t necessarily indicate that they had a bad event experience. If the person was reflecting on issues being presented or quoting others who had a negative experience this will be reflected in their sentiment score. The bottom line is the graph gives an overview of a more complex story. If you want to start unpicking that story yourself the <a href="http://nodexlgraphgallery.org/Pages/Graph.aspx?graphID=213" target="_blank">GraphML data is available on the NodeXL GraphGallery</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://mashe.hawksey.info/2011/10/live-twitter-data-from-fote-fote11/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ported: Tony Hirst&#8217;s Using Protovis to Visualise Twitter Connections to Google Spreadsheet with Embeddable Gadget</title>
		<link>http://mashe.hawksey.info/2011/06/friendviz/</link>
		<comments>http://mashe.hawksey.info/2011/06/friendviz/#comments</comments>
		<pubDate>Mon, 06 Jun 2011 19:57:37 +0000</pubDate>
		<dc:creator>Martin Hawksey</dc:creator>
				<category><![CDATA[Deprecated]]></category>
		<category><![CDATA[Featured]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[Google Apps]]></category>
		<category><![CDATA[Google Apps Script]]></category>
		<category><![CDATA[Google Spreadsheet]]></category>
		<category><![CDATA[Twitter]]></category>

		<guid isPermaLink="false">http://mashe.hawksey.info/?p=11979</guid>
		<description><![CDATA[Update: The Social Graph API has been deprecated by Google and Protovis is no longer being developed. I&#8217;ve revisited this recipe using new tools in Deprecated Bye-bye Protovis Twitter Community Visualizer: Hello D3 Twitter Community Visualizer with EDGESExplorer Gadget RT @psychemedia: How do folk who send you twitter messages connect? http://bit.ly/dNoKGK &#60; see address bar [...]]]></description>
				<content:encoded><![CDATA[<p><strong>Update:</strong> The Social Graph API has been deprecated by Google and Protovis is no longer being developed. I&#8217;ve revisited this recipe using new tools in Deprecated <a href="http://mashe.hawksey.info/2011/12/edgesexplorer-gadget-twitter-community-visualizer/">Bye-bye Protovis Twitter Community Visualizer: Hello D3 Twitter Community Visualizer with EDGESExplorer Gadget </a></p>
<p><em>RT @psychemedia: How do folk who send you twitter messages connect? <a href="http://bit.ly/dNoKGK">http://bit.ly/dNoKGK</a> &lt; see address bar (this is depressingly good)</em></p>
<p>Was what I tweeted on the 13th April 2011. What Tony had managed to do was use the Protovis JavaScript library to let people make their own network visualizations for Twitter search terms (if you haven’t seen Tony’s other work on <a href="http://blog.ouseful.info/?s=hashtag+community">hashtag communities</a>, mainly using Gephi, its well worth a read). The concept for the latest iteration was explained in more detail by Tony in&nbsp; <a href="http://blog.ouseful.info/2011/04/12/using-protovis-to-visualise-connections-between-people-tweeting-a-particular-term/">Using Protovis to Visualise Connections Between People Tweeting a Particular Term</a>.</p>
<p>Two limitations of this solution are: it relies on a current Twitter search which will disappear after 7 days; and it’s difficult to embed elsewhere. Tony and I had discussed collecting the data in a Google Spreadsheet using one of my many <a href="http://mashe.hawksey.info/category/google-apps-script+twitter-web-apps/">Twitter/Spreadsheet mashups</a> and then draw the network visualization from the data.</p>
<p>I thought I would go one step further not only collecting the data in the Spreadsheet but then also generate the Protovis visualization in the sheet by making a gadget for it. The reason for going down the gadget route is in theory they provide an easy way to embed the visualization in other webpages and web apps.</p>
<p>This wouldn’t be my first foray into gadgets having already done <a href="http://mhawksey.tumblr.com/post/3326036799/my-first-google-gadget-to-embed-a-flickr-photoset-with">My first Google Gadget to embed a flickr photoset with Galleria navigation</a>, and I already knew that to gadgetize Tony’s original code just needed some xml wrapping and a dash of the Google Visualization API. In fact because I used Google Apps Script to collect the data there was very little needed to do with Tony’s code as both used JavaScript syntax.</p>
<p>So here it is the:</p>
<p style="text-align: center;"><strong>*** </strong><a href="https://docs.google.com/templates?q=Protovis+Twitter+Community+Visualizer&amp;category=19&amp;sort=hottest&amp;view=public&amp;authorId=07313114692192153679"><strong>Protovis Twitter Community Visualizer</strong></a><strong> ***<br />
</strong>[If the link above doesn't work open <a href="https://spreadsheets.google.com/spreadsheet/ccc?key=0AqGkLMU9sHmLdEo2TWNsTk9wX3JrY0V0R3NoOHV1RUE&amp;hl=en_GB#gid=2">this version</a> and File &gt; Make a copy (make sure you are signed in)]</p>
<p>and here is some output from it (if you are reading this in an RSS&nbsp;aggregator you&#8217;ll need to visit <a href="http://mashe.hawksey.info/2011/06/friendviz/">this post</a>) <strong>Update: </strong>Turns out the Protovis library doesn&#8217;t work with IE so you&#8217;ll just have to use a proper browser instead:</p>
<p><script src="https://spreadsheets.google.com/gpub?url=http%3A%2F%2F84jfcmfbboruil7k6lvfn8cs1l91mnes-ss-opensocial.googleusercontent.com%2Fgadgets%2Fifr%3Fup_title%26up__table_query_url%3Dhttps%253A%252F%252Fspreadsheets.google.com%252Fspreadsheet%252Ftq%253Fauthkey%253DCOPS15ID%2526gid%253D0%2526range%253DA1%25253AB2%2526key%253D0AqGkLMU9sHmLdEo2TWNsTk9wX3JrY0V0R3NoOHV1RUE%2526pub%253D1%26url%3Dhttp%253A%252F%252Fhosting.gmodules.com%252Fig%252Fgadgets%252Ffile%252F108150762089462716664%252Ffriendviz.xml%26spreadsheets%3Dspreadsheets&amp;height=320&amp;width=450"></script></p>
<p>PS you can interact with the diagram by click-dragging nodes, using your mousescroll for zoom and click-drag empty parts to pan</p>
<p>Life is so much easier when you stand on the shoulders of giants ;)</p>
]]></content:encoded>
			<wfw:commentRss>http://mashe.hawksey.info/2011/06/friendviz/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>Google Spreadsheets and floating point errors aka when is 65078736491511804 + 1 = 65078736491511808 (and automatically archiving your Twitter Status Updates)</title>
		<link>http://mashe.hawksey.info/2011/05/export-twitter-status-updates/</link>
		<comments>http://mashe.hawksey.info/2011/05/export-twitter-status-updates/#comments</comments>
		<pubDate>Tue, 03 May 2011 09:57:25 +0000</pubDate>
		<dc:creator>Martin Hawksey</dc:creator>
				<category><![CDATA[Google]]></category>
		<category><![CDATA[Google Apps]]></category>
		<category><![CDATA[Google Apps Script]]></category>
		<category><![CDATA[Google Spreadsheet]]></category>
		<category><![CDATA[Twitter]]></category>

		<guid isPermaLink="false">http://mashe.hawksey.info/2011/05/export-twitter-status-updates/</guid>
		<description><![CDATA[Update: You can ignore most of this post as I noticed the Twitter API can return ids as a string. Here is the updated Export/Archive Twitter Status Updates Spreadsheet I used to use my TwitterPad wordpress plugin to archive everything I said on Twitter. The main reason was often I find myself trying to remember [...]]]></description>
				<content:encoded><![CDATA[<p><strong>Update:</strong> You can ignore most of this post as I noticed the Twitter API can return ids as a string. Here is the <a href="https://docs.google.com/spreadsheet/ccc?key=0AqGkLMU9sHmLdFJnMXFwVkFNenVWYmxkdUw0X2NDLUE">updated Export/Archive Twitter Status Updates Spreadsheet</a></p>
<p>I used to use my <a href="http://mashe.hawksey.info/wordpress-plugins/twitterpad-plugin/">TwitterPad wordpress plugin</a> to archive everything I said on Twitter. The main reason was often I find myself trying to remember links/resources I’ve previously tweeted. It worked well but every month I had to manually paginate my tweets to prevent the post getting too long.</p>
<p>Having got bored with this chore I wrote a Google Spreadsheet which interacts with the Twitter API to pull my timeline <a href="http://dev.twitter.com/doc/get/statuses/user_timeline">grabbing the last 3200 tweets</a>. Part of this API allows you to just grab new updates since a tweet id (a similar parameter is available in the Twitter Search API used in <a href="http://mashe.hawksey.info/2011/05/collectbackup-tweets-in-one-sheet/">Collect/backup tweets in a Google Spreadsheet on one sheet</a>). Using this means I can setup a trigger in Google Apps Script to refresh my archive.</p>
<p>All was going well until I noticed it was pulling in duplicate entries. Part of the problem is Google Spreadsheet thinks 65078736491511804 is 65078736491511808. This meant the script was passing the wrong since id.</p>
<p>You can test this yourself by creating a new Google Spreadsheet and in the first cell [A1] enter 65078736491511804. With this cell highlighted if you select Format &gt; Number and try to change it to nothing happens. This is because Google know there is a floating-point error and store the value as a text string.</p>
<p>If in the cell beneath the number (uh string ;) [A2] you enter the formula =A1+1 you get 65,078,736,491,511,808 (if you get 6.51E+16 with the cell highlighted change Format &gt; Number to Normal)</p>
<p>So if you want to start archiving your or someone else&#8217;s tweets you can make a copy of my <a href="https://spreadsheets.google.com/ccc?key=0AqGkLMU9sHmLdEROVlViSnhMeDZ5RExxQWU0WGZjbGc&amp;hl=en_GB">Export/Archive Twitter Status Updates Google Spreadsheet</a>. The health warning is there maybe missing or duplicates tweets. I have <a href="http://www.google.com/support/forum/p/apps-script/thread?tid=4ced8c7a01afdd36&amp;hl=en&amp;fid=4ced8c7a01afdd360004a25ae6200edf">posted on the Google Apps Script forum</a> to see if there is a way around this.</p>
]]></content:encoded>
			<wfw:commentRss>http://mashe.hawksey.info/2011/05/export-twitter-status-updates/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Collect/backup tweets in a Google Spreadsheet on one sheet</title>
		<link>http://mashe.hawksey.info/2011/05/collectbackup-tweets-in-one-sheet/</link>
		<comments>http://mashe.hawksey.info/2011/05/collectbackup-tweets-in-one-sheet/#comments</comments>
		<pubDate>Mon, 02 May 2011 11:15:48 +0000</pubDate>
		<dc:creator>Martin Hawksey</dc:creator>
				<category><![CDATA[Google]]></category>
		<category><![CDATA[Google Apps]]></category>
		<category><![CDATA[Google Apps Script]]></category>
		<category><![CDATA[Google Spreadsheet]]></category>
		<category><![CDATA[Twitter]]></category>

		<guid isPermaLink="false">http://mashe.hawksey.info/?p=11881</guid>
		<description><![CDATA[A quick recap in June 2010 I hastily threw together a way to archive tweets using Google Spreadsheets. This was okay but a bit flaky. In February (2011) having learned a lot more about Google Spreadsheets and Google Apps Script I reworked the solution producing version 2 Collect/backup tweets in a Google Spreadsheet. I would [...]]]></description>
				<content:encoded><![CDATA[<p>A quick recap in June 2010 I hastily threw together a way to <a href="http://mashe.hawksey.info/2010/06/using-google-spreadsheet-to-automatically-monitor-twitter/" target="_blank">archive tweets using Google Spreadsheets</a>. This was okay but a bit flaky. In February (2011) having learned a lot more about Google Spreadsheets and Google Apps Script I reworked the solution producing <a href="http://mashe.hawksey.info/2011/02/twitteralyticsv2/">version 2 Collect/backup tweets in a Google Spreadsheet. </a></p>
<p>I would like to say that this idea has gone down like a storm, but … well according to the Docs Template Gallery its got 17 users &#8211; 5 star rating though ;) that might be my vote :( I wonder if this is so low because people can make a copy of the spreadsheet from the link in the original post?</p>
<p><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px; padding-top: 0px" title="Thank you the 17 users of Twitteralytics" border="0" alt="Thank you the 17 users of Twitteralytics" src="http://mashe.hawksey.info/wp-content/uploads/2011/05/image.png" width="400" height="163" /></p>
<p>Ignoring this overwhelming success there was one tweak I was meaning to do for a while. Currently the Spreadsheet dumps the results from it’s search into a new sheet each time it runs. This means you can end up with lots of duplicate tweets across different sheets. So when Tony Hirst recently asked:</p>
<blockquote><p><img style="display: inline; float: left" alt="Tony Hirst" align="left" src="https://si1.twimg.com/profile_images/1195013164/Picture_23_normal.png" /><em>@</em><a href="http://twitter.com/mhawksey"><em>mhawksey</em></a><em> do you have a twitterlytics archiver that appends tweets to one sheet rather than form a new sheet for each run? <a href="https://twitter.com/#!/psychemedia/status/63545476250742784">28 Apr 2011</a></em></p>
</blockquote>
<p>the time felt right to do something about this. To get the ball rolling Tony also kindly contributed a <a href="http://tinypaste.com/cc83f4">coding snippet</a> which finds new tweets from the search results. This solution is a bit greedy running a search collecting up to 1500 items then comparing with what is already there. Meanwhile I was looking at the <a href="http://dev.twitter.com/doc/get/search">Twitter Search API documentation</a> to see if I could filter the results to remove previous results (the answer was yes). The disadvantage of this solution is the results can’t be paged so you are limited to 100 results.&#160; </p>
<p>The latest version of the spreadsheet has been included in the <a href="http://mashe.hawksey.info/2011/02/twitteralyticsv2/">Collect/backup tweets in a Google Spreadsheet </a>post (it defaults to using the twitter API to work out the last tweet, but the greedy version is included in the source code). Below is a copy of the main bits of the code. Thanks to Tony for the prod and code suggestion!</p>
<pre class="brush: js">
function collectTweets() {
  // if continuous sheetname = archive else make a name
  if (RESULT_TYPE == "continuous"){
    var sheetName = "Archive";
  } else {
    var sheetName = Utilities.formatDate(new Date(), "GMT", "dd-MMM-yy hh:mm"); //make a new sheet name based on todays date
  }
  // if sheetname doesn't exisit make it
  if (!ss.getSheetByName(sheetName)){
    var temp = ss.getSheetByName("TMP");
    var sheet = ss.insertSheet(sheetName, {template:temp});
  } else {
    var sheet = ss.getSheetByName(sheetName);
  }
  // else if already have archive get since id
  var stored = getRowsData(sheet);
  if (stored.length >0 ){
    var sinceid = stored[0]["id"];
  } 
  // prepare search term
  var myUntil=new Date();
  myUntil.setDate(myUntil.getDate()-1);
  var mySince = new Date(myUntil);
  if (SEARCH_DURATION == " weekly"){
    myUntil.setDate(myUntil.getDate()+1);
    mySince.setDate(mySince.getDate()-6);
  }
  //if no since id grab search results
  if (sinceid){
    var data = getTweets(SEARCH_TERM, mySince, myUntil, NUMBER_OF_TWEETS, sinceid); // get results from twitter sinceid
  } else {
    var data = getTweets(SEARCH_TERM, mySince, myUntil, NUMBER_OF_TWEETS); // get results from twitter
  }
  // if some data insert rows
  if (data.length > 0){
    sheet.insertRowsAfter(1, data.length);
    setRowsData(sheet, data);
  }

  /*
  // This is a very greedy grab (the limit of since id is it has max of 100 results, this method gives you 1500)
  var data = [];  
  if (sinceid){  
    for (var i = 0; i < objects.length; i++){
      var row = objects[i];
      if (row.id > sinceid){
        data.push(row);
      }
    }
    if (data.length > 0){
      sheet.insertRowsAfter(1, data.length);
    }
  } else {
    data = objects;
  }
  */
}

function getTweets(searchTerm, since, until, maxResults, sinceid, languageCode) {
    //Based on Mikael Thuneberg getTweets - mod by mhawksey to convert to json
    // if you include setRowsData this can be used to output chosen entries
    try {
        var pagenum = 1;
      var data =[];
      var idx = 0;
      var sinceurl ="";
        if (typeof maxResults == "undefined") {
            maxResults = 100;
        }
        if (maxResults > 1500) {
            maxResults = 1500;
        }
        if (maxResults > 100) {
            resultsPerPage = 100;
            maxPageNum = maxResults / 100;
        } else {
            resultsPerPage = maxResults;
            maxPageNum = 1;
        }
        if (typeof sinceid != "undefined") {
            if (sinceid.length > 0) {
                resultsPerPage = 100;
                maxPageNum = 1;
                sinceurl = "&#038;since_id=" + sinceid;
            }
        }
        Logger.log(twDate(since)+" "+twDate(until));
        searchTerm = encodeURIComponent(searchTerm);
        for (pagenum = 1; pagenum <= maxPageNum; pagenum++) {
            var URL = "http://search.twitter.com/search.json"
            URL = URL + "?q=" + searchTerm;
            URL = URL + "&#038;since=" + twDate(since);
            URL = URL + "&#038;until=" + twDate(until);
            URL = URL + "&#038;rpp=" + resultsPerPage;
            URL = URL + "&#038;page=" + pagenum;
            URL = URL + "&#038;result_type=recent";
            URL = URL + sinceurl;
            if (typeof languageCode != "undefined") {
                if (languageCode.length > 0) {
                    URL = URL + "&#038;lang=" + languageCode;
                }
            }
            
            var response = UrlFetchApp.fetch(URL, {method:'get', headers: { "User-Agent": REFERER}});
     
            if (response.getResponseCode() == 200) {
              var objects = Utilities.jsonParse(response.getContentText()).results;
              
              for (i in objects){ // not pretty but I wanted to extract geo data
                if (objects[i].geo != null){
                  objects[i]["geo_coordinates"] = "loc: "+objects[i].geo.coordinates[0]+","+objects[i].geo.coordinates[1];
                }
                objects[i]["status_url"] = "http://twitter.com/"+objects[i].from_user+"/statuses/"+objects[i].id_str;
                data[idx]=objects[i];
                idx ++;
              }
            }      
          }         
    return data;
    } catch (e) {
        return e.message;
    }
} 
</pre>
]]></content:encoded>
			<wfw:commentRss>http://mashe.hawksey.info/2011/05/collectbackup-tweets-in-one-sheet/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Export Twitter Followers and Friends using a Google Spreadsheet</title>
		<link>http://mashe.hawksey.info/2011/03/export-twitter-followers/</link>
		<comments>http://mashe.hawksey.info/2011/03/export-twitter-followers/#comments</comments>
		<pubDate>Tue, 08 Mar 2011 13:57:31 +0000</pubDate>
		<dc:creator>Martin Hawksey</dc:creator>
				<category><![CDATA[Google]]></category>
		<category><![CDATA[Google Apps]]></category>
		<category><![CDATA[Google Apps Script]]></category>
		<category><![CDATA[Google Spreadsheet]]></category>
		<category><![CDATA[Twitter]]></category>

		<guid isPermaLink="false">http://mashe.hawksey.info/2011/03/export-twitter-followers/</guid>
		<description><![CDATA[Note: Twitter recently wrote to me reminding me that methods of obtaining and exporting Twitter content obtained via the Twitter API is prohibited by section I.4.A of our API Terms of Service (https://dev.twitter.com/terms/api-terms ), specifically: You will not attempt or encourage others to sell, rent, lease, sublicense, redistribute, or syndicate access to the Twitter API or [...]]]></description>
				<content:encoded><![CDATA[<div style="padding: 8px; background-color: #f9edbe; border-radius: 1px; -moz-border-radius: 1px; border: #ddd 1px solid;">
<p><strong>Note:</strong> Twitter recently wrote to me reminding me that</p>
<blockquote><p>methods of obtaining and exporting Twitter content obtained via the Twitter API is prohibited by section I.4.A of our API Terms of Service (<a href="https://dev.twitter.com/terms/api-terms" target="_blank">https://dev.twitter.com/terms/<wbr />api-terms</a> ), specifically:</p>
<p>You will not attempt or encourage others to sell, rent, lease, sublicense, redistribute, or syndicate access to the Twitter API or Twitter Content to any third party without prior written approval from Twitter. If you provide an API that returns Twitter data, you may only return IDs (including tweet IDs and user IDs). You may export or extract non-programmatic, GUI-driven Twitter Content as a PDF or spreadsheet by using &#8220;save as&#8221; or similar functionality. Exporting Twitter Content to a datastore as a service or other cloud based service, however, is not permitted.</p></blockquote>
<p>Following clarification from Twitter I making this template available again but please note.</p>
<p style="text-align: center;"><strong>By using this template you agree it is for personal use only and the data is not made publicly available</strong>.</p>
</div>
<p>Recently I’ve noticed a growing number of people arrive at this blog having searched for ‘export twitter followers’. Rather than them leaving disappointed here’s a Google Spreadsheet I threw together which allows you to grab a copy of your friends/followers:</p>
<p style="text-align: center;">*** <a href="https://docs.google.com/spreadsheet/ccc?key=0AqGkLMU9sHmLdFl6bUh0WXJKUXRKWGt5bGxtMHlCZkE#gid=25"><strong>Google Spreadsheet to Export Twitter Friends and Followers</strong></a> ***</p>
<h3>Benefits of using Google Spreadsheet</h3>
<ul>
<li>
<div>Control &#8211; You register for your own API key with Twitter so you have full control of the account</div>
</li>
<li>
<div>Playing with the data – as you are importing straight into a spreadsheet you can do all of your own data manipulation like sorting, filtering and creating your own formula for things like follow/follower ratios</div>
</li>
<li>
<div>Backup – Google Spreadsheets allow you to download copies of spreadsheets in different formats</div>
</li>
<li>
<div><del>Share – You can make your lists of friends/followers easily viewable</del></div>
</li>
</ul>
<h3>Where’s this all going?</h3>
<p>Having already done other things with the Twitter API and Google Spreadsheets (See <a href="http://mashe.hawksey.info/2010/11/auto-twitter-list/">Populating a Twitter List via Google Spreadsheet … Automatically!</a>, <a href="http://mashe.hawksey.info/2011/02/twitteralyticsv2/">Collect/backup tweets in a Google Spreadsheet</a>, <a href="http://mashe.hawksey.info/2011/02/guug11/">Google Apps Script, Spreadsheets, Twitter and Gadgets</a>) the Twitter/Google Spreadsheet back is well and truly broken. You’ll probably see fewer posts one this area with new stuff instead I’ll probably start properly documenting the little code snippets I use (but if you have any interesting ideas you want help with get in touch).</p>
<p>This doesn’t mean I’ll be walking away from Google Spreadsheets. As recent posts like <a href="http://mashe.hawksey.info/2011/03/google-spreadsheet-bookmark/">Turning Google Spreadsheets into a personal or group bookmarking service</a>, show there is huge scope in using Spreadsheets as a very flexible rapid development platform.</p>
<p>Below are some bits of the code used in my new spreadsheet (all the code is viewable via the Script Editor in the Spreadsheet):</p>
<pre class="brush: js">function tw_request(method, api_request){
  // general purpose function to interact with twitter API
  // for method and api_request doc see http://dev.twitter.com/doc/
  // retuns object
  var oauthConfig = UrlFetchApp.addOAuthService("twitter");
  oauthConfig.setAccessTokenUrl(
      "https://api.twitter.com/oauth/access_token");
  oauthConfig.setRequestTokenUrl(
      "https://api.twitter.com/oauth/request_token");
  oauthConfig.setAuthorizationUrl(
      "https://api.twitter.com/oauth/authorize");
  oauthConfig.setConsumerKey(getConsumerKey());
  oauthConfig.setConsumerSecret(getConsumerSecret());
  var requestData = {
        "method": method,
        "oAuthServiceName": "twitter",
        "oAuthUseToken": "always"
      };
   try {
      var result = UrlFetchApp.fetch(
          "https://api.twitter.com/1/"+api_request,
          requestData);
      var o  = Utilities.jsonParse(result.getContentText());
    } catch (e) {
      Logger.log(e);
    }
   return o;
}

function getFriendAndFo(sheetName){
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = ss.getSheetByName(sheetName);
  sheet.getRange(2, 1, sheet.getLastRow(), sheet.getMaxColumns()).clear({contentsOnly:true}); //clear sheet
  var cursor = "-1";
  while(cursor != "none"){ // while twitter returns data loop
    try {
      var o = tw_request("GET", "statuses/"+sheetName+".json?cursor="+cursor); // note using sheetname to build api request
      var data = o.users;
      for (i in data){ // extracting some subobjects to top level (makes it easier to setRowsData)
        if (data[i].status){
          for (j in data[i].status){
            data[i]["status_"+j] = data[i].status[j];
          }
        }
        if (data[i].screen_name){ // also build url to jump to profile page
          data[i]["profile_link"] = "http://twitter.com/"+data[i].screen_name;
        }
      }
      var headRange = sheet.getRange(1, 1, 1, sheet.getMaxColumns());
      var rowIndex = sheet.getLastRow()+1;
      setRowsData(sheet, data, headRange, rowIndex); // dump data for this loop to sheet
      if (o.next_cursor!="0"){
        cursor = o.next_cursor; // get next cursor
      } else {
        cursor = "none"; // break
      }
    }  catch (e) {
      Logger.log(e);
    }

  }
}</pre>
]]></content:encoded>
			<wfw:commentRss>http://mashe.hawksey.info/2011/03/export-twitter-followers/feed/</wfw:commentRss>
		<slash:comments>153</slash:comments>
		</item>
		<item>
		<title>TwapperKeeper looses API access, iTitle turns to the cloud with Twitter Search from Google Spreadsheets</title>
		<link>http://mashe.hawksey.info/2011/02/twapperkeeper-looses-api-access-ititle-turns-to-the-cloud-with-twitter-search-from-google-spreadsheets/</link>
		<comments>http://mashe.hawksey.info/2011/02/twapperkeeper-looses-api-access-ititle-turns-to-the-cloud-with-twitter-search-from-google-spreadsheets/#comments</comments>
		<pubDate>Tue, 22 Feb 2011 23:26:48 +0000</pubDate>
		<dc:creator>Martin Hawksey</dc:creator>
				<category><![CDATA[Google]]></category>
		<category><![CDATA[Google Apps]]></category>
		<category><![CDATA[Google Apps Script]]></category>
		<category><![CDATA[Google Spreadsheet]]></category>
		<category><![CDATA[iTitle]]></category>
		<category><![CDATA[Twitter]]></category>
		<category><![CDATA[uTitle]]></category>

		<guid isPermaLink="false">http://mashe.hawksey.info/2011/02/twapperkeeper-looses-api-access-ititle-turns-to-the-cloud-with-twitter-search-from-google-spreadsheets/</guid>
		<description><![CDATA[Recently Twitter has been paying close attention to 3rd party developer use of their API. First they stopped whitelisting new applications, then UberSocial and Twitdroid were suspended for terms of service violations, now the popular tweet archiving service TwapperKeeper announced that they will be removing export and API access in response to a request from [...]]]></description>
				<content:encoded><![CDATA[<div style="float:right; text-align:center; margin-left:4px;"><img src="http://farm5.static.flickr.com/4060/4273873244_cd1bb6a4dc_m.jpg" alt="Empty Archive" class="flickr_img small photo"  title="Empty Archive"/><br /><a href="http://www.flickr.com/photos/44824500@N05/4273873244/" class="flickr">Empty Archive</a><br />Originally uploaded by <a href="http://www.flickr.com/photos/44824500@N05/">brokenview</a></div>
<p>Recently Twitter has been paying close attention to 3rd party developer use of their API. First they <a href="http://www.readwriteweb.com/archives/twitter_kills_the_api_whitelist_what_it_means_for.php">stopped whitelisting new applications</a>, then <a href="http://support.twitter.com/articles/452648-i-m-having-problems-logging-in-to-ubertwitter-or-twidroyd">UberSocial and Twitdroid were suspended</a> for terms of service violations, now the popular tweet archiving service TwapperKeeper <a href="http://twapperkeeper.wordpress.com/2011/02/22/removal-of-export-and-download-api-capabilities/">announced that they will be removing export and API access</a> in response to a request from Twitter. </p>
<p>Fortunately TwapperKeeper has been given until the 20th March to comply, but this is still a blow for 4th party developers, like myself, who build applications around the TwapperKeeper archive/API and will no longer have an easy way to grab historic tweets. Part of the problem is Twitter provides no easy access to collections of tweets over 5 days old necessitating the need for services like TwapperKeeper, so it’s discontinuation is going to cause headaches for some.</p>
<p>Personally, when developing my <a href="http://hawksey.info/ititle/">Twitter Subtitling service iTitle</a> I was keen to make sure data could be used from various sources starting with the official Twitter Search results and TwapperKeeper integration, later adding support for .CSV file upload. Most recently I added support for my <a href="http://mashe.hawksey.info/2011/02/twitteralyticsv2/">Google Spreadsheet/Twitter Search collection mashup</a> [BTW after feedback from @AJCann there is now a <a href="http://www.youtube.com/watch?v=vpckqM0acaQ">setup video for this on YouTube</a>]. So hopefully iTitle will live for a little longer.</p>
<p>So what about other services like my other Twitter mashup <a href="http://www.rsc-ne-scotland.org.uk/mashe/utitle/">uTitle</a> and Andy Powell’s <a href="http://summarizr.labs.eduserv.org.uk/">Summarizr</a>, which rely on the TwapperKeeper service. There are obviously other Twitter archive services out there, TwapperKeeper even has the <a href="http://twapperkeeper.wordpress.com/2010/08/25/announcing-yourtwapperkeeper-archive-your-own-tweets-on-your-own-server/">JISC funded open source version yourTwapperKeeper</a>, but all the online services potentially face the same problem of being prevented from making archived tweets reusable. One solution might be to develop a distributed cloud based archive. For example, initially I thought of using <a href="http://mashe.hawksey.info/2011/02/twitteralyticsv2/">Google Spreadsheet hack for capturing tweets</a>, and then sharing these archives with the community as a searchable index. Anyone fancy building an interface for this?</p>
]]></content:encoded>
			<wfw:commentRss>http://mashe.hawksey.info/2011/02/twapperkeeper-looses-api-access-ititle-turns-to-the-cloud-with-twitter-search-from-google-spreadsheets/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>
