Monday, May 4, 2009

Twittering from U2: How and Why? Part 1

This is the first of several posts, where I plan to indicate how and why one would access Twitter from a U2 (Universe or Unidata) system.

For those who don't know what Twitter is, I'll provide two links that will help you to understand it. Wikipedia has a good explanation here: http://en.wikipedia.org/wiki/Twitter And here is Twitter's own page explaining what they are: http://twitter.com/about#about

So, if you've read these links, or if you're already familiar with Twitter, you've realized that this is primarily a social networking application, but that people have found other uses for it.

So, for starters, why would you want to do this?

Several uses that might be of interest to a U2 programmer include:
  • Sending messages from a system and being able to monitor them elsewhere. A powerful and simple publish/subscribe model (with some limitations).
  • Keeping customers or prospects aware of promotions, events and offers.
  • Filtering Twitter Searches programmatically, to provide a short-list of interesting messages.

There's bound to be more, but that's a good starting point.

Next, I'm going to show how to get/put updates from/to Twitter directly from a UniBASIC program on Universe on *nix. The same concept will work on Universe on Windows, Unidata on anything and for that matter, any MultiValue (PICK) platform that lets you run a cmd line application and capture the results.

To get the maximum reusability, I've done much of the UniBASIC code as subroutines, effectively an API that you can call.

I've created a directory named "TWITTER" as a subdirectory in the same directory as your account VOC resides. In actual fact, I created a type 19 file called TWITTER (DIR file type in Unidata), which automatically created the TWITTER directory for me, but we won't need the U2 file pointer at this time. I use this directory as a scratch area, a place for the java classes that I use. On non-U2 systems you might need a MultiValue file called TWITTER and a directory called TWITTER.

The java components that I use are a command line java program called FWTwitterDirect.java and an open source library that I found referenced on the Twitter developer pages, called jtwitter.jar. You can see more about this library at http://www.winterwell.com/software/jtwitter.php. Our java file is listed below:



import java.util.*;
import winterwell.jtwitter.*;

/**
* FusionWare Twitter Direct
* Copyright (c) 2009 FusionWare Corporation
* This code is released as open-source under the LGPL license.
* This code comes with no warranty or support.
* The LGPL license text can be reviewed here:
* http://www.gnu.org/licenses/lgpl.html
*
* To see info about our Twitter Gateway that provides for guaranteed
* delivery of automated tweets, filtering of incoming tweets, and more
* See FusionWare Twitter Gateway (TRILL) at http://www.fusionware.net
* Phone: 1-866-266-2326 or 604-777-4254 or email info@fusionware.net
*
* This class is a command-line utility to interface with Twitter from within
* Legacy LOB systems.
*/
public class FWTwitterDirect
{
final static char LOW_VM = (char)29;
/**
* @param args
* Syntax comes in two forms:
* Get:
*
* java FWTwitterDirect userId password
*

* Put:
*
* java FWTwitterDirect userId password "Update text"
* (Note last parameter should have quotes if it contains spaces.)
*

*/
public static void main(String[] args)
{
try
{
if (args.length == 2)
{
// Get
Twitter twitter = new Twitter(args[0], args[1]);
twitter.updateStatus(args[2]);
}
else if (args.length == 3)
{
// Put
Twitter twitter = new Twitter(args[0], args[1]);
List statuses = twitter.getFriendsTimeline();
Iterator it = statuses.iterator();
while(it.hasNext())
{
Twitter.Status status = (Twitter.Status)it.next();
System.out.println(
status.user.screenName + LOW_VM +
status.user.name + LOW_VM +
status.createdAt.toString() + LOW_VM +
status.getText());
}
}
else
{
// No good
System.out.println("Invalid Syntax:\njava FWTwitterDirect userid password [\"text\"]");
System.exit(2);
}
}
catch (Exception e)
{
e.printStackTrace();
System.exit(1);
}
}
}


The syntax for the command, when run from the directory where your VOC resides, and with no CLASSPATH environment variable set, is as follows:



java -classpath TWITTER:TWITTER/jtwitter.jar FWTwitterDirect userId password ["text"]



Note that if the text contains spaces you'll need quotes around it. If you omit the text, we retrieve the last 20 tweets for the user and the user's friends.

Now for the UniBASIC API code:



SUBROUTINE FWTWEET.DIRECT.API(DIRECTION, USERID, PASSWORD, TEXT)
*
* Author: Robert Houben
* Version: 1.0
*
* FusionWare Twitter Direct
* Copyright (c) 2009 FusionWare Corporation
* This code is released as open-source under the LGPL license.
* This code comes with no warranty or support.
* The LGPL license text can be reviewed here:
* http://www.gnu.org/licenses/lgpl.html
*
* To see info about our Twitter Gateway that provides for guaranteed
* delivery of automated tweets, filtering of incoming tweets, and more
* See FusionWare Twitter Gateway (TRILL) at http://www.fusionware.net
* Phone: 1-866-266-2326 or 604-777-4254 or email info@fusionware.net
*
EQU TRUE TO 1, FALSE TO 0
EQU AM TO CHAR(254), VM TO CHAR(253), SVM TO CHAR(252)
EQU LOW.VM TO CHAR(29)
EQU LF TO CHAR(10)
EQU CR TO CHAR(13)
*
CMD = 'sh -c "'
CMD = CMD : 'java -classpath TWITTER:TWITTER/jtwitter.jar '
CMD = CMD : 'FWTwitterDirect '
CMD = CMD : USERID:' '
CMD = CMD : PASSWORD
IF DIRECTION EQ "PUT" THEN
CMD = CMD : ' '
CMD = CMD : '""':TEXT:'""'
END
CMD = CMD : '"'
EXECUTE CMD CAPTURING TEXT
CONVERT LF TO AM IN TEXT
CONVERT CR TO "" IN TEXT
CONVERT LOW.VM TO VM IN TEXT
LOOP
WHILE TEXT[LEN(TEXT),1] EQ AM DO
TEXT=TEXT[1,LEN(TEXT)-1]
REPEAT
*
RETURN
*
END


Note that DIRECTION is passed in as either "GET" or "PUT".

For PUT, you must provide the value of your tweet in the TEXT variable. Remember to keep it to 140 bytes or we will truncate.

For GET, TEXT will be overwritten with a dynamic array containing up to 20 attributes. Each attribute is a tweet from the user themselves or from their friends, in date/time order, with the first one being the newest. For each line, it will be divided into multivalues where they are laid out as follows:

Multivalue 1 is the Twitter user name of the user that sent the tweet.

Multivalue 2 is the Twitter user's display name.

Multivalue 3 is the datetime of the tweet.

Multivalue 4 is the text of the tweet.

So, here is an example program that uses the API. Note that while this program is interactive, you can call the API from a program running in a phantom.



*
* Author: Robert Houben
* Version: 1.0
*
* FusionWare Twitter Direct
* Copyright (c) 2009 FusionWare Corporation
* This code is released as open-source under the LGPL license.
* This code comes with no warranty or support.
* The LGPL license text can be reviewed here:
* http://www.gnu.org/licenses/lgpl.html
*
* To see info about our Twitter Gateway that provides for guaranteed
* delivery of automated tweets, filtering of incoming tweets, and more
* See FusionWare Twitter Gateway (TRILL) at http://www.fusionware.net
* Phone: 1-866-266-2326 or 604-777-4254 or email info@fusionware.net
*
EQU TRUE TO 1, FALSE TO 0
EQU AM TO CHAR(254)
*
PRINT "Enter user id":
INPUT USERID
IF USERID EQ "" THEN STOP
*
PRINT "Enter password":
ECHO OFF
INPUT PASSWORD
ECHO ON
IF PASSWORD EQ '' THEN STOP
PRINT
*
LOOP
PRINT "Enter update text ('.' to retrieve)":
INPUT TEXT
UNTIL TEXT EQ '' DO
IF TEXT EQ '.' THEN
DIRECTION="GET"
END ELSE
DIRECTION="PUT"
END
CALL API.FWTWEET.DIRECT(DIRECTION, USERID, PASSWORD, TEXT)
IF DIRECTION EQ "GET" THEN
ACNT=DCOUNT(TEXT,AM)
FOR A=1 TO ACNT
LINE=TEXT<A>
IF TRIM(LINE) NE "" THEN
NAME=LINE<1,1>
DISPLAYNAME=LINE<1,2>
TIME=LINE<1,3>
MSG=LINE<1,4>
PRINT "NAME=":NAME
PRINT "DISP=":DISPLAYNAME
PRINT "TIME=":TIME
PRINT "TEXT=":MSG
PRINT
END
NEXT A
END
REPEAT
STOP
*
END



So, here are the pros and the cons:

On the pro side, you don't need any additional infrastructure, you can do everything from UniBASIC. We could extend the class file to provide different types of retrievals, in addition to the GET retrieval.

On the con side, your Universe server has to have Internet access (possible security issues), any temporary failure on Twitter's part will result in an error and a lost communication, and when you pull back tweets, you have to do your own parsing.

In my next post, I'm going to be removing the cons using FusionWare Integration Server with our Twitter Gateway technology preview. The new product is named FusionWare TRILL ™ (Twitter Reliable Intelligent Live Link).



No comments:

Post a Comment