Mule School: Integration with Social Media: Part I – Twitter

April 17 2012

21 comments 0
twitter

This tutorial is the first in a series of blog posts that explain how to integrate Mule and Social Media.

Today’s post will focus on connecting to Twitter and sending a tweet (if you don’t know what is read this). Subsequent tutorials will cover:

Mule Server and Studio versions

For this integration, I am using the latest version of Mule ESB Community Edition with Mule Studio (1.0.0). This sample can also be run in standalone Mule ESB Community Edition and Mule ESB Enterprise Editions.

Mule Studio comes with built-in Twitter connector we can straight away use in Studio. Lets build a new twitter flow that looks like below. We will create an HTTP inbound end point that forwards request to Twitter connector. Finally, the Twitter connector returns a twitter4j.StatusJSONImpl object that will be transformed using an expression-transformer to display response object’s string representation.

Let’s build the sample now.

  • Create a new Mule flow and name it “twitter”.
  • Drag and drop a new HTTP inbound end point on to “twitterFlow1”. Double click on HTTP icon to bring up properties dialog. Specify “addtweet” for Path field.
  • Click on “Global Elements” tab and click on Create to bring up Global Type dialog box. Select “Twitter” from “Cloud Connectors” section. Leave default values and click Ok. We need to configure twitter account to generate necessary security tokens. I will explain this process in next section.
  • Drag and drop Twitter connector next to HTTP inbound end point. Double click on Twitter icon to bring up properties dialog. Select Twitter connector we created in previous step for “Config Reference” field. Select “Update status” for Operation field. Finally specify “#[header:INBOUND:mymessage]” as Status. This expression extracts “mymessage” parameter value from HTTP request.
  • Finally drag and drop an “expression transformer” next to “Twitter” connector. Double click on Expression icon to bring up properties dialog. Specify evaluator as “groovy” and expression as “payload.toString()”. More on expression transformers can be read from Mule 3 documentation.

Here is the completed flow. I have erased my generated keys.

Pretty simple, right? To explain in more detail:

In MuleStudio this syntax will be indicated as an error because MuleStudio is still trying to use the older version of the XSD.
Anyway, what do all these attibutes mean?

The “consumerKey”, “consumerSecret”, “oauthToken” and “oauthTokenSecret” are in fact keys that are generated by the Twitter application. (More on that in a minute.)

Configure Twitter

Before your are able to start using the Twitter integration you will have to do some configuration in your Twitter account.
Go to the following url: https://dev.twitter.com and sign in with your Twitter username and password.

First, you should add an application:

Fill in all the fields in the screen and agree to the “Terms and Conditions.”

 

 

 

 

 

Once your application has been generated, you can choose from a tab bar to configure your application in more detail:

You will see that the consumer key and consumer secret are already generated but the access level is Read-only. If you want to read more information on the Twitter permisson model you can click on the link.

To authenticate your application with your Twitter account you will have to generate authentication keys. This is not done by default:

Click the button to create your access tokens and the following screen will appear:

By default the access level is Read-only. If you need access to direct messages you will have to update your Access level. This can be done in the following ways:

Consumer keys

Go to the Settings tab and adjust the access level:

OAuth keys:

You should recreate your access token (after changing the access level in the settings tab) if you also want to update your access level of your OAuth keys.

Running the application

Right click on twitter.mflow and select Run As Mule Application. Once application has successfully started, you can test the application with the following URL: http://localhost:8081/addtweet?mymessage=hello. Do check your twitter account to see a new tweet with message “hello”.

A successful twitter update will result in following response:

If you ever try to tweet the same message twice you will get the following response from Twitter:

StatusJSONImpl{createdAt=null, id=-1, text='null', source='null', isTruncated=false, 
inReplyToStatusId=-1, inReplyToUserId=-1, isFavorited=false, inReplyToScreenName='null', 
geoLocation=null, place=null, retweetCount=-1, wasRetweetedByMe=false, contributors=null, 
annotations=null, retweetedStatus=null, userMentionEntities=null, urlEntities=null, 
hashtagEntities=null, user=null}

And that’s it! Have fun!

This is a guest post from Mule community member Tom Stroobants. Thank you Tom! (we’ll be sending you a cool T-shirt).  If anyone else in the Mule community would like to write a guest post, please email us.


We'd love to hear your opinion on this post

21 Responses to “Mule School: Integration with Social Media: Part I – Twitter”

  1. Hi ,this is a very good tutorial , hope you could write more example tutorial to give us more lesson ,thanks a lot

    Agree(0)Disagree(0)Comment
  2. Hello,

    I attempted the above tutorial and i got this Exception:

    1. Unbuffered entity enclosing request can not be repeated. (org.apache.commons.httpclient.ProtocolException)
    org.apache.commons.httpclient.methods.EntityEnclosingMethod:487 (null)
    2. Failed to route event via endpoint: DefaultOutboundEndpoint{endpointUri=http://api.twitter.com/1/statuses/update.json, connector=HttpConnector

    AND on my browser an getting:
    Failed to invoke updateStatus. Message payload is of type: String

    Please help,
    Thanks in Advance

    Agree(0)Disagree(0)Comment
    • Hi Danny,

      As “Guru” explained, this can be caused by a proxy server. If so could you also try this example when you are directly connected to the internet ?
      If you are not using a proxy … Which version of Mule are you using ?

      Best regards,

      Tom.

      Agree(0)Disagree(0)Comment
  3. Thanks for the post Tom!

    Agree(0)Disagree(0)Comment
  4. Hi Tom and Danny,

    This is a very nice tutorial. I got this successful withour a proxy. I am behind a proxy.

    @ Danny: Am in the same stage, The same error log. Hope you are behind a proxy. I am trying out bypass through proxy credentials. Let me post the updates if am successful

    Regards
    Guru

    Agree(0)Disagree(0)Comment
  5. Well done Tom … looking forward to linkedin, facebook, yammer implementations.

    Agree(0)Disagree(0)Comment
  6. @Tom &Guru,

    Thanks for the quick response,

    I tried with my 3G card and connected directly to the internet – “No Proxy” and it worked successfully,

    so i guess it’s my work proxy that doesn’t allow social media connections(assumption).

    AND I must say this is a GOOD and straight forward tutorial.

    now i would like to try it for fb.

    Happy Integration,
    Danny

    Agree(0)Disagree(0)Comment
  7. Thanks,

    Great Danny, I experienced the same joy when i connected to direct internet.

    Looking forward to solve this proxy issue. But my organisatio allows twiiter. Since I can access the urls from browser. I dont know why.

    It will be a great show if i can run behind a proxy.

    @ Tom. Thanks, I am looking forward for LinkedIn connector.

    Regards
    Guru

    Agree(0)Disagree(0)Comment
  8. @Guru,

    “It will be a great show if i can run behind a proxy.”

    I can also access twitter from my browser using my organisations proxy.
    so i guess we are experiencing the same challenge.

    Do you know of any other tutorials of how i can advance my knowledge Mule ESB? I’am still hungry for more , want to master this 🙂 .

    Happy Integration,
    Danny

    Agree(0)Disagree(0)Comment
  9. Very nice tutorial, it works great!
    One question: Spaces entered in the message display as %20 on Twitter, any way to avoid this?

    Greets,

    Hilko

    Agree(0)Disagree(0)Comment
  10. Hi Danny,

    Sure. I can help you on that.

    By the way I am trying to deploy the same in MuleION. Mule gives one month free usage. Such that I can avoid org proxy here.

    Regards
    Guru

    Agree(0)Disagree(0)Comment
  11. You really make it seem so easy with your presentation
    but I find this matter to be really something that I think I would never understand.
    It seems too complex and very broad for me.
    I am looking forward for your next post, I’ll try to get the hang of it!

    Agree(0)Disagree(0)Comment
  12. @Teresa
    Hello Teresa, Once you start playing with it, it will become more clear. My next post was about facebook integration, you can check it out here:

    http://blogs.mulesoft.com/mule-school-integration-with-social-media-part-ii-%E2%80%93-facebook/

    Feel free to contact me if you would have any questions …

    Tom.

    Agree(0)Disagree(0)Comment
  13. hi .
    awesome tutorial.
    it solve my confusion.
    thank you

    Agree(0)Disagree(0)Comment
  14. Hello. When trying to run the application, I get the following error message: “org.mule.module.launcher.application.DefaultMuleApplication: null”
    Any idea?

    Agree(0)Disagree(0)Comment
  15. @ Tom,

    When I call the url it shows the following error

    INFO 2013-02-13 16:52:17,601 [[twittermule].connector.http.mule.default.receiver.02] org.mule.transport.service.DefaultTransportServiceDescriptor: Loading default outbound transformer: org.mule.transport.http.transformers.ObjectToHttpClientMethodRequest
    INFO 2013-02-13 16:52:17,610 [[twittermule].connector.http.mule.default.receiver.02] org.mule.transport.service.DefaultTransportServiceDescriptor: Loading default response transformer: org.mule.transport.http.transformers.MuleMessageToHttpResponse
    INFO 2013-02-13 16:52:17,611 [[twittermule].connector.http.mule.default.receiver.02] org.mule.transport.service.DefaultTransportServiceDescriptor: Loading default outbound transformer: org.mule.transport.http.transformers.ObjectToHttpClientMethodRequest
    INFO 2013-02-13 16:52:17,612 [[twittermule].connector.http.mule.default.receiver.02] org.mule.lifecycle.AbstractLifecycleManager: Initialising: ‘connector.http.mule.default.dispatcher.13018016’. Object is: HttpClientMessageDispatcher
    INFO 2013-02-13 16:52:17,616 [[twittermule].connector.http.mule.default.receiver.02] org.mule.lifecycle.AbstractLifecycleManager: Starting: ‘connector.http.mule.default.dispatcher.13018016′. Object is: HttpClientMessageDispatcher
    ERROR 2013-02-13 16:52:27,857 [[twittermule].connector.http.mule.default.receiver.02] org.mule.exception.DefaultMessagingExceptionStrategy:
    ********************************************************************************
    Message : Failed to route event via endpoint: DefaultOutboundEndpoint{endpointUri=http://api.twitter.com/1/statuses/update.json, connector=HttpConnector
    {
    name=connector.http.mule.default
    lifecycle=start
    this=31bcc8
    numberOfConcurrentTransactedReceivers=4
    createMultipleTransactedReceivers=true
    connected=true
    supportedProtocols=[http]
    serviceOverrides=
    }
    , name=’endpoint.http.api.twitter.com.1.statuses.update.json’, mep=REQUEST_RESPONSE, properties={}, transactionConfig=Transaction{factory=null, action=INDIFFERENT, timeout=0}, deleteUnacceptedMessages=false, initialState=started, responseTimeout=10000, endpointEncoding=UTF-8, disableTransportTransformer=false}. Message payload is of type: PostMethod
    Code : MULE_ERROR–2
    ——————————————————————————–
    Exception stack is:
    1. connect timed out (java.net.SocketTimeoutException)
    java.net.PlainSocketImpl:-2 (null)
    2. The host did not accept the connection within timeout of 10000 ms (org.apache.commons.httpclient.ConnectTimeoutException)
    org.apache.commons.httpclient.protocol.ReflectionSocketFactory:155 (null)
    3. Failed to route event via endpoint: DefaultOutboundEndpoint{endpointUri=http://api.twitter.com/1/statuses/update.json, connector=HttpConnector
    {
    name=connector.http.mule.default
    lifecycle=start
    this=31bcc8
    numberOfConcurrentTransactedReceivers=4
    createMultipleTransactedReceivers=true
    connected=true
    supportedProtocols=[http]
    serviceOverrides=
    }
    , name=’endpoint.http.api.twitter.com.1.statuses.update.json’, mep=REQUEST_RESPONSE, properties={}, transactionConfig=Transaction{factory=null, action=INDIFFERENT, timeout=0}, deleteUnacceptedMessages=false, initialState=started, responseTimeout=10000, endpointEncoding=UTF-8, disableTransportTransformer=false}. Message payload is of type: PostMethod (org.mule.api.transport.DispatchException)
    org.mule.transport.http.HttpClientMessageDispatcher:155 (http://www.mulesoft.org/docs/site/current3/apidocs/org/mule/api/transport/DispatchException.html)
    ——————————————————————————–
    Root Exception stack trace:
    java.net.SocketTimeoutException: connect timed out
    at java.net.PlainSocketImpl.socketConnect(Native Method)
    at java.net.PlainSocketImpl.doConnect(Unknown Source)
    at java.net.PlainSocketImpl.connectToAddress(Unknown Source)
    + 3 more (set debug level logging or ‘-Dmule.verbose.exceptions=true’ for everything)
    ********************************************************************************

    Agree(0)Disagree(0)Comment
  16. @ all,

    PLease tell me if you crack this tutorial with proxy..
    regards,
    Arunava Basu

    Agree(0)Disagree(0)Comment
  17. Hi Tom,

    Good article. I do have a doubt. Currently, mule requires either the screenName or the userid to be hard coded. Is there an alternative way to make it dynamic so that if a ui is to provided it could refer to the input screen provided?

    Cheers,
    Ram Kumar

    Agree(0)Disagree(0)Comment
  18. […] A public version of what is in the book can be found here. I am not going to re-produce that sample and will instead focus on what I changed in order to […]

    Agree(0)Disagree(0)Comment