21. Twitter Adapter

Spring Integration provides support for interacting with Twitter via Twitter adapters. With Twitter adapters you can both receive and send Twitter messages.

21.1 Introduction

Twitter is a social networking and microblogging service that enables its users to send and read messages known as tweets. Tweets are text-based posts of up to 140 characters displayed on the author's profile page and delivered to the author's subscribers who are known as followers.

[Important]Important
Current Twitter support is based on Twitter4J API, however future version will be changed to use Spring Social project as it is nearing its first release at the time of writing.

Spring Integration provides a convenient namespace configuration to define Twitter artifacts.

xmlns:twitter="http://www.springframework.org/schema/integration/twitter"
xsi:schemaLocation="http://www.springframework.org/schema/integration/twitter 
	http://www.springframework.org/schema/integration/twitter/spring-integration-twitter-2.0.xsd"

21.2 Twitter OAuth Configuration

Twitter API allows for both authenticated and anonymous operations. For authenticated operations Twitter uses OAuth - an authentication protocol that allows users to approve application to act on their behalf without sharing their password. More information can be found at http://oauth.net/ or in this article http://hueniverse.com/oauth/ from Hueniverse. Please also see OAuth FAQ for more information about OAuth and Twitter.

In order to use OAuth authentication/authorization with Twitter you must create new Application on Twitter Developers site. Follow the directions below to create a new application and obtain consumer keys and access token:

  • Go to http://dev.twitter.com/

  • Click on Register an app link and fill out all required fields on the form provided; set Application Type to Client and depending on the nature of your application select Default Access Type as Read & Write or Read-only and Submit the form. If everything is successful you'll be presented with the Consumer Key and Consumer Secret. Copy both values in the safe place.

  • On the same page you should see My Access Token button on the side bar (right). Click on it and you'll be presented with two more values: Access Token and Access Token Secret. Copy these values in a safe place as well.

21.3 Twitter Template

Spring Integration uses the same familiar template pattern to interact with Twitter. Since current Twitter support is based on Twitter4J API and we provide Twiter4JTemplate. For anonymous operation (e.g., search) you don't have to define Twitter4JTemplate explicitly, since the default instance of it will be created and injected into the endpoint. However, for authenticated operation (e.g., update status, send direct message etc.) you must configure Twitter4JTemplate as a bean and inject it explicitly into the endpoint. Below is a sample configuration of Twitter4JTemplate:

<bean id="twitterTemplate" class="org.springframework.integration.twitter.core.Twitter4jTemplate">
	<constructor-arg value="21691649-4XYZY5iJEOfz2A9qCFd9SjBRGb3HLmIm4HNE6AMv4""/>
	<constructor-arg value="AbRxUAvyNCtqQtvxFK8w5ZMtMj20KFhB6oEfTA0"/>
	<constructor-arg value="4XzBPabcJQxyBzzzH3TrRQ"/>
	<constructor-arg value="ab2piKdMfPu8bVa3ab6DAIvIWEVZyMDL0RSEN2I8"/>
</bean>

[Note]Note
The values above are not real

As you can see form the configuration above all we need to do is to provide OAuth attributes as constructor arguments filling them with values you have obtained in the previous step. The order of constructor arguments is: 1) consumerKey; 2) consumerSecret; 3) accessToken; 4) accessTokenSecret;

However a more practical way to manage OAuth connection attributes would be via Spring's placeholder support by simply creating a property file (e.g., oauth.properties):

twitter.oauth.consumerKey=4XzBPabcJQxyBzzzH3TrRQ
twitter.oauth.consumerSecret=ab2piKdMfPu8bVa3ab6DAIvIWEVZyMDL0RSEN2I8
twitter.oauth.accessToken=21691649-4XYZY5iJEOfz2A9qCFd9SjBRGb3HLmIm4HNE6AMv4
twitter.oauth.accessTokenSecret=AbRxUAvyNCtqQtvxFK8w5ZMtMj20KFhB6oEfTA0

and configuring a property-placeholder pointing to he above property file:

<context:property-placeholder
            location="classpath:oauth.properties"/>

<bean id="twitterTemplate" class="org.springframework.integration.twitter.core.Twitter4jTemplate">
	<constructor-arg value="${twitter.oauth.consumerKey}"/>
	<constructor-arg value="${twitter.oauth.consumerSecret}"/>
	<constructor-arg value="${twitter.oauth.accessToken}"/>
	<constructor-arg value="${twitter.oauth.accessTokenSecret}"/>
</bean>

21.4 Twitter Inbound Adapters

Twitter inbound adapters allow you to receive Twitter Messages. There are several types of twitter messages - tweets

Current release of Spring Integration provides support for receiving tweets as Public Messages, Direct Messages, Mention Messages as well as perform Searches

Every Inbound Twitter Channel Adapter is a Polling consumer which means you have to provide a poller configuration. However, one important thing you must understand with regard to Twitter since its inner-workings are slightly different then any other poling consumer. Twitter defines a concept of Rate Limiting. You can read more about it here: Rate Limiting . In the nutshell Rate Limiting is the way Twitter manages how often an application can poll for updates. Luckily for you you don't have to worry about it since the special Rate limit aware polling thread is created when any Twitter adapter is started. This thread will poll Messages (Tweets) from the Twitter account at the rate allowed by Twitter at the time (it may change after every poll). The latest Tweet timestamp will be stored in the instance of the org.springframework.integration.store.MetadataStore which is a strategy interface designed for storing various types of metadata (e.g., last retrieved tweet) to help components such as Twitter to deal with duplicates. By default, Spring Integration will look for a bean of type org.springframework.integration.store.MetadataStore in the ApplicationContext. If one found then it will be used, otherwise it will create a new instance of SimpleMetadataStore which is a simple in-memory implementation that will only persist meta-data within the life-cycle of the application context which means upon restart you may end up with duplicate entries. If you need to persist meta-data between Application Context restarts, you may use PropertiesPersistingMetadataStore (property file based persister) or provide your own implementation of the MetedataStore interface (e.g., JdbcMetadatStore) and configure it as bean in the Application Context.

<bean class="org.springframework.integration.store.PropertiesPersistingMetadataStore"/>

The Poller that is configured as part of the any Inbound Twitter Adapter (see below) will simply poll from this MetadataStore

21.4.1 Inbound Message Channel Adapter

This adapter allows you to receive updates from everyone you follow.

<twitter:inbound-channel-adapter twitter-template="twitterTemplate" channel="inChannel">
    	<poller fixed-rate="5000" max-messages-per-poll="3"/>
</twitter:inbound-channel-adapter>

21.4.2 Direct Inbound Message Channel Adapter

This adapter allows you to receive Twitter Messages that were sent directly to you

<twitter:dm-inbound-channel-adapter twitter-template="twiterTemplate" channel="inboundDmChannel">
    	<poller fixed-rate="5000" max-messages-per-poll="3"/>
</twitter:dm-inbound-channel-adapter>

21.4.3 Mentions Inbound Message Channel Adapter

This adapter allows you to receive Twitter Messages that Mention you via @user

<twitter:mentions-inbound-channel-adapter twitter-template="twiterTemplate" 
			channel="inboundMentionsChannel">
    	<poller fixed-rate="5000" max-messages-per-poll="3"/>
</twitter:mentions-inbound-channel-adapter>

21.4.4 Search Inbound Message Channel Adapter

This adapter allows you to perform searches. As you can see it is not neccessery to define twitter-template since search could be performed anonymously, however an you must define a search query.

<twitter:search-inbound-channel-adapter query="#springintegration" 
			channel="inboundMentionsChannel">
    	<poller fixed-rate="5000" max-messages-per-poll="3"/>
</twitter:search-inbound-channel-adapter>

Here is a link that will help you learn more about Twitter queries: http://search.twitter.com/operators

As you can see the configuration of all of these adapters is very similar to other inbound adapters with one exception. Some may need to be injected with the twitter-template. Once configured the Twitter Messages would be encapsulated into a Spring Integration Message and sent to a channel specified via channel attribute. Currently the Payload type of any Message is org.springframework.integration.twitter.core.Tweet which is very similar to the object with the same name in Spring Social. As we migrate to Spring Social we'll be depending on their API and some of the artifacts that ar currently in use will be obsolete, however we've already made sure that the impact of such migration is minimal by alignning our API with the curent state (at the time of writing) of Spring Social

To get the text from the org.springframework.integration.twitter.core.Tweet simply invoke getText() method.

21.5 Twitter Outbound Adapter

Twitter outbound channels adapters allow you to send Twitter Messages - tweets

Current release of Spring Integration supports sending Status Update Messages and Direct Messages. Twitter outbound channels adapters as any other outbound adapter will take the Message payload and send it as Twitter message. Currently the only supported payload type is String, so consider adding a transformer if the payload of the incoming message is not a String.

21.5.1 Twitter Outbound Update Channel Adapter

This adapter allows you to send regular status updates by simply sending a Message to a channel identified via channel attribute.

<twitter:outbound-channel-adapter twitter-template="twitterTemplate" channel="twitterChannel"/>

The only extra configuration that is required for this adapter is twitter-template

21.5.2 Twitter Outbound Direct Message Channel Adapter

This adapter allows you to send Direct Twitter Messages (i.e., @user) by simply sending a Message to a channel identified via channel attribute.

<twitter:dm-outbound-channel-adapter twitter-template="twitterTemplate" channel="twitterChannel"/>

The only extra configuration that is required for this adapter is twitter-template

[Important]Important
Twitter does not allow you to post duplicate Messages. This is a common problem during testing when the same code works the first time but doesn't work the second time,so make sure to change the content of the Message. One thing that works good for testing is appent timestamp to the end of the message.