Simple Twitter Agent For The Google Wave Federation Server
This week some code was push to the repository to implement some kind of agents for the federation server. A simple EchoAgent was added to demonstrate the code.
With this as starting point I implemented a small TwitterAgent. Just add the TwitterAgent to a wave. The agent listens to every message and updates your twitter status. I took the twitter4j API which is pretty easy to use.
package org.waveprotocol.wave.examples.fedone.agents.twitter;
import java.util.ArrayList;
import java.util.List;
import org.waveprotocol.wave.examples.fedone.agents.agent.AbstractAgent;
import org.waveprotocol.wave.examples.fedone.agents.agent.AgentConnection;
import org.waveprotocol.wave.examples.fedone.util.Log;
import org.waveprotocol.wave.model.document.operation.AnnotationBoundaryMap;
import org.waveprotocol.wave.model.document.operation.Attributes;
import org.waveprotocol.wave.model.document.operation.AttributesUpdate;
import org.waveprotocol.wave.model.document.operation.BufferedDocOp;
import org.waveprotocol.wave.model.document.operation.DocOpCursor;
import org.waveprotocol.wave.model.operation.wave.WaveletDocumentOperation;
import org.waveprotocol.wave.model.wave.ParticipantId;
import org.waveprotocol.wave.model.wave.data.WaveletData;
import twitter4j.Twitter;
import twitter4j.TwitterException;
public class TwitterAgent extends AbstractAgent {
private static final Log LOGGER = Log.get(TwitterAgent.class);
private Twitter twitter;
private TwitterAgent(String username, String hostname, int port, String twitterUsername, String twitterPassword) {
super(AgentConnection.newConnection(username, hostname, port));
this.twitter = new Twitter(twitterUsername, twitterPassword);
}
private void tweetLines(List lines) {
for (String line : lines) {
LOGGER.info("updateStatus: " + line);
try {
twitter.updateStatus(line);
} catch (TwitterException e) {
LOGGER.warning(e.getMessage(), e);
}
}
}
@Override
public void onDocumentChanged(WaveletData wavelet, WaveletDocumentOperation documentOperation) {
BufferedDocOp docOp = documentOperation.getOperation();
final List lines = new ArrayList();
docOp.apply(new DocOpCursor() {
@Override public void annotationBoundary(AnnotationBoundaryMap map) { }
@Override public void characters(String chars) { lines.add(chars); }
@Override public void deleteCharacters(String chars) { }
@Override public void deleteElementEnd() { }
@Override public void deleteElementStart(String type, Attributes attrs) { }
@Override public void elementEnd() { }
@Override public void elementStart(String type, Attributes attrs) { }
@Override public void replaceAttributes(Attributes oldAttrs, Attributes newAttrs) { }
@Override public void retain(int itemCount) { }
@Override public void updateAttributes(AttributesUpdate attrUpdate) { }
});
tweetLines(lines);
}
@Override
public void onParticipantAdded(WaveletData wavelet, ParticipantId participant) { }
@Override
public void onParticipantRemoved(WaveletData wavelet, ParticipantId participant) { }
@Override public void onSelfAdded(WaveletData wavelet) { }
@Override public void onSelfRemoved(WaveletData wavelet) { }
public static void main(String[] args) {
try {
if (args.length == 5) {
int port;
try {
port = Integer.parseInt(args[2]);
} catch (NumberFormatException e) {
throw new IllegalArgumentException("Must provide valid port.");
}
TwitterAgent agent = new TwitterAgent(args[0], args[1], port, args[3], args[4]);
agent.run();
} else {
System.out.println("usage: java TwitterAgent
");
}
} catch (Exception e) {
System.err.println("Catastrophic failure: " + e);
System.exit(1);
}
System.exit(0);
}
}
One issue with the current implementation should be mentioned: If you’ll restart the TwitterAgent all the messages will be resubmitted to your twitter account! If someone knows how to avoid this, please leave a comment.
Within in the next days, I’ll add some more little features (e.g. grab status updates and add them to a wave, twitter direct message gateway, …). What else could you think of?
This should be considered as a small demonstration and is far away from a Twitter and Google Wave integration