Wednesday 24 October 2012

Sending "Tweets" via ColdFusion (via Twitter4J)

G'day:
I'm writing an application than needs to send Twitter status updates.  This is an augmentation of the ColdFusion Bugs RSS feeds I have (in the box on the right); I'm gonna send tweets out when a new bug is raised as well.  Or that's the idea.

To do this, I need to work out how to send Twitter status updates (which sounds much less daft than "tweets") from ColdFusion somehow.

This is probably well-trod ground, but the CF-based resources I initially found are all out of date, so I thought I'd post the results of my investigations here in case they're helpful to anyone.



Firstly I googled about for stuff like "coldfusion twitter" and that sort of thing, and came across Ray's article on the same topic from a coupla years ago. This also linked to Rob O'Brien's article on same.

These pointed me to Twitter4J, which I downloaded, and slapped the enclosed twitter4j-core-2.2.6.jar file into my WEB-INF\lib directory.

Before any of this is going to work, I needed to set up an "application" with Twitter.  This is done via the Twitter developers site, on the "Create an app" page. This is a simple form which one needs to fill out with fairly obvious details.  One thing that threw me initially here is that one needs to set the "Application Type" to "Read/Write".  This is obvious now that I think about it, but I missed it the first time around, and I spent about half an hour puzzling over error messages before actually reading what they said an changed my setting.  And then another 15min puzzling over why I was getting the same error message still, until I realised I had to regenerate my auth details.  But I'm getting ahead of myself...

Having configured all that stuff, one has the four bits of info one needs to authenticate to the Twitter API, and do stuff:
  • Consumer key
  • Consumer secret
  • Access token
  • Access token secret
Before doing anything via the API, one needs to pass these credentials.  See below for how to do this.

With Twitter4J installed, and my secret login details at hand, I ran Ray's code.  Well a modification of it that didn't use Java loader (which I saw as an unnecessary convolution to just putting the files where CF would automatically find them without special code to locate them).

Unfortunately Ray's code didn't work, I assume because Twitter4J has moved on since he wrote it.  My version of Ray's code was thus:

include "./auth.cfm";
twitter = createObject("java", "twitter4j.Twitter");
twitter.setOAuthConsumer(auth.consumerKey, auth.consumerSecret);
twitter.setOAuthAccessToken(auth.accessToken, auth.accessTokenSecret);
twit_result = twitter.statuses_update("Hello World");

(I've abstracted the auth stuff out of the way so you can't see 'em!)

This gave this error:

The setOAuthConsumer method was not found.

[...]
The error occurred in D:\websites\www.scribble.local\shared\git\apps\bugTweet\ray.cfm: line 4
2 : include "./auth.cfm";
3 : twitter = createObject("java", "twitter4j.Twitter");
4 : twitter.setOAuthConsumer(auth.consumerKey, auth.consumerSecret);

I looked at the API, and Twitter.class is just an interface rather than a class, so this wasn't gonna work.  I presume it used to be a class when Ray wrote his code.

I spent some time looking through the Twitter4J API, trying to work out what the equivalent code would be now, but I couldn't work it out... My Java is not much beyond "Hello World", and whilst I made some headway, I could not work out how to get the authorisation stuff into an object and authorised.

I decided I'd spent enough time trying to reinvent the wheel, and googled for inspiration.  I found a page on the Twitter4J site (which I did not find when just drilling down through it, previously!), which explained how to set the auth properties.  This was easy as an easy thing, and I ended up with this ColdFusion code:

include "./auth.cfm";

configBuilder = createObject("java", "twitter4j.conf.ConfigurationBuilder");
configBuilder.setOAuthConsumerKey(auth.consumerKey);
configBuilder.setOAuthConsumerSecret(auth.consumerSecret);
configBuilder.setOAuthAccessToken(auth.accessToken);
configBuilder.setOAuthAccessTokenSecret(auth.accessTokenSecret);
config = configBuilder.build();

twitterFactory = createObject("java", "twitter4j.TwitterFactory").init(config);
twitter = twitterFactory.getInstance();

twitter.updateStatus("Hello World 1");

And... bam... my "tweet" was sent:



Cool  I was quite pleased with that (easily impressed, me).

After finishing up I googled some more, and found Matt Gifford's monkehTweets CFC, which I will look at a bit later.  There was a lot to wade through, and for my immediate requirements half a dozen lines of code suit me more than a thumping great CFC, 95% of which I don't need (this is no reflection on Matt's work; it just covers a lot more than I need).

I suppose I need to see if CFML Developer will let me install that Jar file though.  If not... I will be having a closer look at Matt's work.

Anyway, that's that. I'll probably have the new-bug-tweeterer-thingey done within the next day or so, and will advise when done so you can "follow" it if you so choose.

Cheers.

--
Adam