Cache and display multiple Twitter feeds in ColdFusion – CFC

Friday, November 19th, 2010

I’ve worked on a few sites recently that have required Twitter feeds to be pulled in and displayed on the homepage.
Thanks to the awesome <cffeed> tag this is a relatively easy task, but I’ve noticed a bit of an overhead when pulling the data in from Twitter’s servers.

I had a look around and came across this post by Simon Bingham, showing how to cache the results of a Twitter feed in the Application scope.

This worked well, but I needed to be able to pull in both outgoing tweets (using the Twitter ID) and incoming tweets (using a search string). This meant not only updating the CFC to take both types of argument and act accordingly, but also to allow mutiple feeds to be cached.
Building on Simon’s original, I’ve created a new CFC that does just that, and even has a bit of error handling for good measure.

<cffunction name="getTweets" access="public" returntype="query" hint="Pulls contents of a Twitter feed by ID or search string, and caches results in the Application scope">
	<cfargument name="sTwitterString" type="string" required="yes" hint="Pass a Twitter ID or search string" />
	<cfargument name="iType" type="numeric" required="yes" hint="Select type of query - 1 = Twitter ID, 2 = Search string" />
	<cfargument name="iCachedFor" type="numeric" default="60" hint="How long to cache results" />
	<cfargument name="sStructureName" type="string" default="defaultCache" hint="Choose a name for the cached structure, to allow for multiple sets of cached data to be stored" />

	<!--- First we want to check there's a structure to hold our cached tweets --->
	<cfif NOT StructKeyExists(Application, 'stTwitterFeedCache')>	
		<!--- Lock the Application scope --->
		<cflock scope="Application" timeout="60" type="exclusive">
			<!--- Create structure --->
			<cfset Application.stTwitterFeedCache = {} />			
		</cflock>
	</cfif>

	<!--- If no structure exists in application scope, or if the structure exists, but is older than the 'CachedFor' setting --->	
	<cfif NOT StructKeyExists(Application.stTwitterFeedCache, '#Arguments.sStructureName#' ) OR DateDiff( "n", Application.stTwitterFeedCache&#91;Arguments.sStructureName&#93;.dtCreated, Now() ) GT Arguments.iCachedFor>

		<!--- Lock the Application scope --->
		<cflock scope="Application" timeout="60" type="exclusive">

			<!--- Create the application structure --->
			<cfset Application.stTwitterFeedCache&#91;Arguments.sStructureName&#93; = {} />
			
			<!--- Pull the feed in, wrap in a cftry block --->
			<cftry>

				<!--- Choose the feed source based on the query type selected --->
				<cfif Arguments.iType EQ 1>
					<cffeed source="http://twitter.com/statuses/user_timeline/#Arguments.sTwitterString#.rss" properties="feedmeta" query="Application.stTwitterFeedCache&#91;Arguments.sStructureName&#93;.data" />
				<cfelseif Arguments.iType EQ 2>
					<cffeed source="http://search.twitter.com/search.atom?q=#Arguments.sTwitterString#" properties="feedmeta" query="Application.stTwitterFeedCache&#91;Arguments.sStructureName&#93;.data" />
				<cfelse>

					<!--- Incorrect query type--->
					<cfscript>
						Application.stTwitterFeedCache[Arguments.sStructureName].data = QueryNew("Error");
						newRow = QueryAddRow(Application.stTwitterFeedCache[Arguments.sStructureName].data);
						QuerySetCell(Application.stTwitterFeedCache[Arguments.sStructureName].data, "Error", "Invalid query type entered. Please choose 1 for a Twitter ID, or 2 for a Search string.");
					</cfscript>

				</cfif>

				<!--- Catch any errors with the feed --->
				<cfcatch type="any">

					<cfscript>
						Application.stTwitterFeedCache[Arguments.sStructureName].data = QueryNew("Error");
						newRow = QueryAddRow(Application.stTwitterFeedCache[Arguments.sStructureName].data);
						QuerySetCell(Application.stTwitterFeedCache[Arguments.sStructureName].data, "Error", "Unable to pull in feed. We all know ColdFusion is awesome, so it's probably Twitter's fault.");
					</cfscript>

				</cfcatch>

			</cftry>

			<!--- Update the timestamp for the data --->
			<cfset Application.stTwitterFeedCache&#91;Arguments.sStructureName&#93;.dtCreated = Now() />

		</cflock>

	</cfif>

	<!--- Return the data --->
	<cfreturn Application.stTwitterFeedCache&#91;Arguments.sStructureName&#93;.data />

</cffunction>

Feasibly, this could be adjusted to cache any kind of feed – the trick is in the dynamic naming of the structures to allow for multiple feeds.

Hope someone out there finds it useful!

Tags:

Filed under: ColdFusion, Railo.

2 Comments

  1. Sebastiaan

    May 18th, 2011
    12:22 pm

    Hi, used this as a basis for showing our Twitter feeds on our new website. Tweaked it a bit but still the grunt of it is yours 😉 Thanx!

  2. Ron

    Jun 8th, 2012
    1:34 am

    I really want to know how the entire thing works from scratch. I keep getting simple to sophisticated errors and I don’t know where to begin.

About

Simian Enterprises is the trading name of Gary Stanton, a freelance web developer working by the sea in Brighton, UK. Gary's been creating websites since 1996 and still loves it. Read more

Contact

Gary Stanton

Email:

Tel:
01273 775522

Twitter

No public Twitter messages.

Delicious Feed

Website Design & Development