javatwitterapache-camelenterprise-integration

Camel consuming twitter timeline tweets, and rates


I am trying to get tweets from my Twitter timeline with ConsumerTemplate (Camel) in a Quarkus app.

I don't understand how it should be done correctly while using rate limits (my free account has rate 15 polls in 5 min).

The Camel setup has property count which I set to 10, and expect to get 10 new tweets in one poll, but the problem is that template offers only one tweet per Camel request:

for (int i = 0; i < 15; i++) {

    // I would expect here List or stream, but I can get only single `Status`
    final Status tweets = consumerTemplate.receiveBodyNoWait(String.format("twitter-timeline://home?sinceId=%s&count=10", sinceId), Status.class);

    // just to show that I change that property
    if (nonNull(tweets)) {
         sinceId = tweets.getId();
    }

}

So my question is why I get only one tweet per poll even if count is set (a value more than 1). Is there any better way or running that template, or something I can use instead while respecting downstream Twitter rate limits?


Solution

  • The ConsumerTemplate is based on a PollingConsumer under the hood, which as the name implies, pulls Exchages one at a time hence why you are receiving only 1 Status (== 1 Exchange) even while setting a count endpoint option.

    It is almost hard (and error-prone) to implement tweets (or other Exchanges) consumption the right way. Indeed this is already offered out-of-the-box with the Apache Camel Twitter Component consumer.

    Here down a sample of a route to consume user public activity (timeline) using the twitter-timeline component:

    <routes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xmlns="http://camel.apache.org/schema/spring"
            xsi:schemaLocation="
                http://camel.apache.org/schema/spring
                https://camel.apache.org/schema/spring/camel-spring.xsd">
    
        <route id="twitter-timeline" autoStartup="true">
            <from uri="twitter-timeline:USER?user=some-user&amp;consumerKey=your-app-key&amp;consumerSecret=your-app-key-secret&amp;accessToken=your-app-access-token&amp;accessTokenSecret=your-app-access-token-secret"/>
            <log message="${body}"/>
        </route>
    
    </routes>
    

    This will leverage the default polling configured delays which you can tweak based on your preferences to address any rate-limits. In your case for example, to respect 15 requests per 5 mins, you can set the consumer to poll each 20 seconds for one page:

    <from uri="twitter-timeline:USER?user=some-user&amp;count=100&amp;numberOfPage=1&amp;delay=20000"/>