We are about to switch to a new forum software. Until then we have removed the registration on this forum.
Hi all,
I currently have a program that connects to twitter, opens a stream and the tweets coming flooding in based on keywords in the filter. This data is then visualised through shapes, colour and sound.
What I am trying to do is add the ability for users to tweet the program and have it find their tweet and visualise it on screen. Just searching through the flood doesn't find these tweets as the streaming api only returns up to 40% of the incoming tweets. I have been informed that @mentions may allow me to stream all available tweets and filter for tweets that mention my account specifically.
I have found this example and have tried to adapt it without success due to the builder having already been used.
Error Message: Cannot use this builder any longer, build() has already been called.
Does anyone have an idea on how to incorporate the @mentions ability to filter through the data from the streaming api?
Thanks.
Twitter code below.
String userDefined;
GetMentions men = new GetMentions();
// Stream it
void openTwitterStream(String user) {
// OAuth stuff
ConfigurationBuilder cb = new ConfigurationBuilder();
cb.setOAuthConsumerKey("*****");
cb.setOAuthConsumerSecret("*****");
cb.setOAuthAccessToken("*****");
cb.setOAuthAccessTokenSecret("*****");
//the stream object
twitterStream = new TwitterStreamFactory(cb.build()).getInstance();
//@mentions modification, doesn't work due to the cb.build already having been used. ---------------------------
Twitter twitter = new TwitterFactory(cb.build()).getInstance();
try {
User u = twitter.verifyCredentials();
List<Status> statuses = twitter.getMentionsTimeline();
System.out.println("Showing @" + u.getScreenName() + "'s mentions.");
for (Status status : statuses) {
System.out.println("@" + status.getUser().getScreenName() + " - " + status.getText());
}
}
catch (TwitterException te) {
te.printStackTrace();
System.out.println("Failed to get timeline: " + te.getMessage());
System.exit(-1);
}
//end of @mentions modification ------------------------------------------------------------------------
// filter is used to pass querys to the stream
// see twitter4j's java doc
FilterQuery filtered = new FilterQuery();
// if you enter keywords here it will filter, otherwise it will sample
String keywords[] = {userDefined};
//track is like "search"... well kind of
// for a better explanation go
// dev.twitter.com/streaming/overview/request-parameters"
filtered.track(keywords);
// the StatusListener interface is where the magic happens
// code there will be executed upon tweets arriving
// so we want to attach one to our stream
twitterStream.addListener(listener);
if (keywords.length == 0) {
// sample() method internally creates a thread which manipulates TwitterStream
// and calls these adequate listener methods continuously.
// ref //dev.twitter.com/streaming/reference/get/statuses/sample
// "Returns a small random sample of all public statuses"
twitterStream.sample();
} else {
twitterStream.filter(filtered);
}
println("connected");
}
// Implementing StatusListener interface
// the methods are pretty much self explantory
// they will be called according to the messages arrived
// onStatus is probably what you are lookikng for...
StatusListener listener = new StatusListener() {
//@Override
public void onStatus(Status status) {
//println("@" + status.getUser().getScreenName() + " - " + status.getText());
String s = status.getText().toLowerCase();
String[] tweetWords = s.split(" ");
for (int i = 0; i < tweetWords.length-1; i++) words.add(tweetWords[i]);
//println("tweetWords: " + tweetWords.length);
//tweetWords = null;
}
//@Override
public void onDeletionNotice(StatusDeletionNotice statusDeletionNotice) {
println("Got a status deletion notice id:" + statusDeletionNotice.getStatusId());
}
//@Override
public void onTrackLimitationNotice(int numberOfLimitedStatuses) {
//println("Got track limitation notice:" + numberOfLimitedStatuses);
}
//@Override
public void onScrubGeo(long userId, long upToStatusId) {
println("Got scrub_geo event userId:" + userId + " upToStatusId:" + upToStatusId);
}
//@Override
public void onStallWarning(StallWarning warning) {
println("Got stall warning:" + warning);
}
//@Override
public void onException(Exception ex) {
ex.printStackTrace();
}
};
Answers
I managed to get around the builder issue by creating another speficically for the @mentions function. Now I have no idea how to filter for these.
I have found this in the documentation which in no uncertain terms says that @mentions are excluded from the streaming api.
I hope there's some sort of workaround to this.
Anyone have any ideas?
The above works. If the users account is mentioned eg:
tweet content @exampleaccount
then this will filter it from the stream and it can be used on screen.Solved.
Posting api keys to a public forum is asking for trouble...
In general: if someone issues you a variable with "secret" or "private" or "PIN" etc. in the name, don't post it to a public forum, and don't check it in to a public open source repository (e.g. github).
Examples:
ConsumerSecret
PrivateSecret
SecretKey
PrivateKey
AccessTokenSecret
Treat it like your bank PIN number. You can still ask questions about banking in public, you just shouldn't provide your personal PIN number as part of an example.
I didn't think I had. The keys and secrets have been changed to x's or asterisk's in place of the actual key, token or secret.
Please either @jeremydouglass or @koogs inbox me and tell me on which line I have gone wrong.
On the topic of the @mentions code, it appears that it is not required at all. Just tweet and @mention the account and it should filter it. Useful.
@SnailPropulsionLabs -- not sure -- I had just assumed @koogs had edited those out for you, as he made his comment at 5:53 and your post was edited at 5:53.
The @ mention does sound useful!
Thanks for the response jeremy.