Skip to content

Instantly share code, notes, and snippets.

@wellercs
Created November 4, 2013 04:46
Show Gist options
  • Save wellercs/7298192 to your computer and use it in GitHub Desktop.
Save wellercs/7298192 to your computer and use it in GitHub Desktop.
Twitter CFC
<cfcomponent displayname="Twitter" output="false" hint="I provide functions for interacting with the Twitter API.">
<cfscript>
this.name = "Twitter";
variables.baseURI = "https://api.twitter.com/";
variables.charset = "UTF-8";
variables.version = "1.1";
</cfscript>
<cffunction name="init" access="public" output="false" returntype="any" hint="I initialize the component">
<cfargument name="apiKey" required="false" type="string" default="" hint="I am the API key to the Twitter API that was provided to us by Twitter.">
<cfargument name="secretKey" required="false" type="string" default="" hint="I am the secret key between us and Twitter.">
<cfscript>
variables.apiKey = arguments.apiKey;
variables.secretKey = arguments.secretKey;
return this;
</cfscript>
</cffunction>
<cffunction name="getApplicationRateLimitStatus" access="public" returntype="any" output="false" hint="I return a collection of the current rate limits for methods belonging to the specified resource families.">
<cfargument name="fullURI" required="false" type="string" default="#variables.baseURI##variables.version#/application/rate_limit_status.json" hint="I am the full URI to Twitter's rate limit data." />
<cfargument name="http_method" required="false" type="string" default="GET" hint="I am either POST or GET" />
<cfargument name="resources" type="string" required="false" default="search" hint="A comma-separated list of resource families you want to know the current rate limit disposition for. Example Values: statuses,friends,trends,help,users,search">
<cfset var local = {}>
<cftry>
<cfscript>
local.bearerToken = getBearerToken();
local.authHeader = "Bearer #local.bearerToken#";
local.fullURI = "#arguments.fullURI#?resources=#arguments.resources#";
local.httpFileContent = makeHttpCall(fullURI=local.fullURI, authHeader=local.authHeader, http_method=arguments.http_method);
local.deserializedContent = deserializeJSON(local.httpFileContent);
return local.deserializedContent;
</cfscript>
<cfcatch type="any">
<cfreturn "">
</cfcatch>
</cftry>
</cffunction>
<cffunction name="getBearerToken" access="public" returntype="string" output="false" hint="I get the bearer token.">
<cfargument name="fullURI" required="false" type="string" default="#variables.baseURI#oauth2/token" hint="I am the full URI to Twitter's oauth2 token." />
<cfargument name="authCode" required="false" type="string" default="#ToBase64("#variables.apiKey#:#variables.secretKey#")#" hint="I am the OAuth authorization code in HTTP" />
<cfargument name="authHeader" required="false" type="string" default="Basic #arguments.authCode#" hint="I am the OAuth header in HTTP" />
<cfargument name="http_method" required="false" type="string" default="POST" hint="I am either POST or GET" />
<cfargument name="http_body" required="false" type="string" default="grant_type=client_credentials" hint="I am the body of the http call" />
<cfargument name="content_type" required="false" type="string" default="application/x-www-form-urlencoded;charset=#variables.charset#" hint="I am the content type of the call"/>
<cfset var local = {}>
<cftry>
<cfscript>
local.bearerToken = "";
local.httpFileContent = makeHttpCall(fullURI=arguments.fullURI, authHeader=arguments.authHeader, http_method=arguments.http_method, http_body=arguments.http_body, content_type=arguments.content_type);
local.deserializedContent = deserializeJSON(local.httpFileContent);
local.tokenType = local.deserializedContent.token_type;
local.accessToken = local.deserializedContent.access_token;
if ( local.tokenType IS "bearer" ) {
local.bearerToken = local.accessToken;
}
return local.bearerToken;
</cfscript>
<cfcatch type="any">
<cfreturn "">
</cfcatch>
</cftry>
</cffunction>
<cffunction name="getSearchTweets" access="public" returntype="any" output="false" hint="I return a collection of relevant Tweets matching a specified query.">
<cfargument name="fullURI" required="false" type="string" default="#variables.baseURI##variables.version#/search/tweets.json" hint="I am the full URI to Twitter's search tweets data." />
<cfargument name="http_method" required="false" type="string" default="GET" hint="I am either POST or GET" />
<cfargument name="searchQuery" type="string" required="false" default="" hint="A UTF-8, URL-encoded search query of 1,000 characters maximum, including operators.">
<cfargument name="resultType" type="string" required="false" default="mixed" hint="Specifies what type of search results you would prefer to receive. Valid values include: mixed (Include both popular and real time results in the response), recent (return only the most recent results in the response), popular (return only the most popular results in the response)">
<cfargument name="resultsPerPage" type="numeric" required="false" default="15" hint="The number of tweets to return per page, up to a maximum of 100.">
<cfargument name="until" type="date" required="false" hint="Returns tweets generated before the given date. Date should be formatted as YYYY-MM-DD.">
<cfargument name="sinceID" type="numeric" required="false" hint="Returns results with an ID greater than (that is, more recent than) the specified ID.">
<cfargument name="maxID" type="numeric" required="false" hint="Returns results with an ID less than (that is, older than) or equal to the specified ID.">
<cfset var local = {}>
<cftry>
<cfscript>
local.querystring = "q=#arguments.searchQuery#&result_type=#arguments.resultType#&count=#arguments.resultsPerPage#";
if ( StructKeyExists(arguments,"until") ) {
local.querystring &= "&until=#arguments.until#";
}
if ( StructKeyExists(arguments,"sinceID") ) {
local.querystring &= "&since_id=#arguments.sinceID#";
}
if ( StructKeyExists(arguments,"maxID") ) {
local.querystring &= "&max_id=#arguments.maxID#";
}
local.bearerToken = getBearerToken();
local.authHeader = "Bearer #local.bearerToken#";
local.fullURI = "#arguments.fullURI#?#local.querystring#";
local.httpFileContent = makeHttpCall(fullURI=local.fullURI, authHeader=local.authHeader, http_method=arguments.http_method);
local.deserializedContent = deserializeJSON(local.httpFileContent);
return local.deserializedContent;
</cfscript>
<cfcatch type="any">
<cfreturn "">
</cfcatch>
</cftry>
</cffunction>
<cffunction name="makeTweetTextClickable" access="public" returntype="string" output="false" hint="I make a link or hashtag clickable.">
<cfargument name="tweetText" type="string" required="true" hint="I am the tweet text to make clickable.">
<cfset var local = {}>
<cftry>
<cfscript>
local.tweetText = arguments.tweetText;
// Make links clickable
local.tweetText = REReplaceNoCase(local.tweetText, '[[:alpha:]]+://[^<>[:space:]]+[[:alnum:]]+[a-zA-Z0-9_-]', '<a href="\0" title="\0" class="twitterlink" data-ajax="false">\0</a>', 'all');
// Make hashtags clickable
local.tweetText = REReplaceNoCase(local.tweetText, '##[^<>[:space:]]+[[:alnum:]]+[a-zA-Z0-9_-]', '<a href="http://twitter.com/search?q=\0" title="\0" class="twitterlink" data-ajax="false">\0</a>', 'all');
local.tweetText = replace(local.tweetText, 'http://twitter.com/search?q=##', 'http://twitter.com/search?q=%23', 'all');
return local.tweetText;
</cfscript>
<cfcatch type="any">
<cfreturn arguments.tweetText>
</cfcatch>
</cftry>
</cffunction>
<cffunction name="makeHttpCall" access="public" output="no" returntype="any" hint="I call the LinkedIN API via CFHTTP it works half the time">
<cfargument name="fullURI" required="true" type="string" hint="I am the full URI to call into Twitter" />
<cfargument name="authHeader" required="true" type="string" hint="I am the OAuth header in HTTP" />
<cfargument name="http_method" required="false" type="string" default="POST" hint="I am either POST or GET" />
<cfargument name="http_body" required="false" type="string" default="" hint="I am the body of the http call" />
<cfargument name="content_type" required="false" type="string" default="application/x-www-form-urlencoded" hint="I am the content type of the call"/>
<cfscript>
var header = "";
var result = {};
header = header & "Content-Type: #arguments.content_type##Chr(13)##Chr(10)#";
header = header & "Authorization: #arguments.authheader##Chr(13)##Chr(10)#";
</cfscript>
<cfhttp url="#arguments.fullURI#" method="#arguments.http_method#" resolveurl="no">
<cfhttpparam type="header" name="Content-Type" value="#arguments.content_type#" />
<cfhttpparam type="header" name="Authorization" value="#trim(arguments.authheader)#" />
<cfhttpparam type="body" value="#arguments.http_body#" encoded="no" />
</cfhttp>
<cfset result = cfhttp.FileContent />
<cfreturn result />
</cffunction>
<cffunction name="parseTwitterDateFormat" access="public" returntype="date" output="false" hint="I parse the Twitter date into a usable format.">
<cfargument name="twitterDate" type="date" required="true" hint="I am the twitter date for which to format.">
<cfargument name="dateMask" type="string" required="true" hint="I am the mask for the date format.">
<cfargument name="timeMask" type="string" required="true" hint="I am the mask for the time format.">
<cfset var local = {}>
<cftry>
<cfscript>
local.twitterDate = arguments.twitterDate;
local.formatter = createObject("java", "java.text.SimpleDateFormat").init("EEE MMM d kk:mm:ss Z yyyy");
local.formatter.setLenient(true);
local.twitterDate = local.formatter.parse(local.twitterDate);
local.twitterDate = DateFormat(local.twitterDate, arguments.dateMask) & ' ' & TimeFormat(local.twitterDate, arguments.timeMask);
return local.twitterDate;
</cfscript>
<cfcatch type="any">
<cfreturn arguments.twitterDate>
</cfcatch>
</cftry>
</cffunction>
<cffunction name="onMissingMethod" hint="I catch it if someone passes in a bad method name">
<cfargument name="missingMethodName" type="string">
<cfargument name="missingMethodArguments" type="struct">
<!--- handle missing method --->
</cffunction>
</cfcomponent>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment