package Twitter_Control_Panel; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.URLDecoder; import java.util.Date; import java.util.List; import java.util.Map; import java.util.TreeMap; import twitter4j.Query; import twitter4j.QueryResult; import twitter4j.Status; import twitter4j.Tweet; import twitter4j.Twitter; import twitter4j.TwitterException; import twitter4j.TwitterFactory; import twitter4j.User; import twitter4j.http.AccessToken; import twitter4j.http.RequestToken; import com.extentech.ExtenXLS.ExcelTools; import com.extentech.toolkit.Logger; import com.extentech.toolkit.StringTool; /** * This class is the server-side controller for the Sheetster Twitter Control * Panel Doc App * * Combined with a "Control Panel" spreadsheet, this program will provide the * following services: * * - Provide data feeds of interesting statistical data for reporting in * Sheetster - Provide watch lists and keyword searches that can be used to: a) * search for a list of keywords in the tweets of new followers, triggering alt * reply messages and workflows b) search for a list of keywords in the tweets * of current followers and watched/followed users, triggering alerts and * workflows - Report and monitor SEO metrics such as "Follower vs. Followed" * and "Influence among Influencers" - Allow for automated tweeting from a * canned list of tweets, on a schedule or in re: to watched lists of keywords, * users * * * @author John McMahon :: Jun 14, 2011 :: Copyright ©2011 Extentech Inc. * */ public class Tweetster extends SheetsterRESTClient { private Date lastTweetDate = null; // the time of the current tweet private String lastTweet = "Sheetster FTW!"; // the current tweet "status line" private String userName = ""; // the twitter user name private long updateInterval = 0000l; // default 3 seconds private boolean running = true; // running flag // maintain the location of important cells here private static String DOCUMENT_ID = "34"; // change to your doc id private static String SHEET_CONTROL = "Control Panel"; private static String SHEET_DATA = "data"; private static String CELL_USERNAME = "D5"; private static String CELL_LASTTWEET = "D6"; private static String CELL_LASTMENTION = "D7"; private static String CELL_DATA_DATE = "G5"; private static String CELL_FOLLOWING_CT = "G6"; private static String CELL_FOLLOWER_CT = "G7"; private static String CELL_CURRENT_TWEET = "C9"; private static String NAME_WATCHLIST = "watchlist"; private static String NAME_KEYWORDLIST = "keywords"; private static String NAME_AUTO_TWEET = "auto_tweet_content"; private static String NAME_AUTO_TWEET_DT = "auto_tweet_date"; /** * @return Returns the running. */ public boolean isRunning() { return running; } /** * @param running * The running to set. */ public void setRunning(boolean running) { this.running = running; } /** * @return Returns the updateInterval. */ public long getUpdateInterval() { return updateInterval; } /** * @param updateInterval * The updateInterval to set. */ public void setUpdateInterval(long updateInterval) { this.updateInterval = updateInterval; } /** * @return Returns the lastTweet. */ public String getlastTweet() { return lastTweet; } /** * @param lastTweet * The lastTweet to set. */ public void setlastTweet(String lastTweet) { this.lastTweet = lastTweet; } /** * @return Returns the twitter. */ public Twitter getTwitter() { return twitter; } /** * @param twitter * The twitter to set. */ public void setTwitter(Twitter twitter) { this.twitter = twitter; } private Twitter twitter; /** * Create a new Tweetster Instance * * @param twc * the twitter client * @throws Exception */ public Tweetster() throws Exception { init(); } /** * launch the Tweetster process * * @param args */ public static void main(String args[]) { try { Tweetster tweets = new Tweetster(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } /** * Initialize the server communication * @throws Exception * */ private void init() throws Exception { // defaults setMemeId(DOCUMENT_ID); // the id of the previously uploaded Sheetster template (Sheetster_Twitter_Control_Panel.v2.xlsx authenticate(); try { // The factory instance is re-useable and thread safe. twitter = new TwitterFactory().getInstance(); // insert the appropriate consumer key and consumer secret here twitter.setOAuthConsumer("", ""); RequestToken requestToken; requestToken = twitter.getOAuthRequestToken(); AccessToken accessToken = null; BufferedReader br = new BufferedReader(new InputStreamReader( System.in)); while (null == accessToken) { System.out .println("Open the following URL and grant access to your account:"); String orul = requestToken.getAuthorizationURL(); Logger.logInfo(orul); launchBrowser(orul); System.out .print("Enter the PIN(if aviailable) or just hit enter.[PIN]:"); String pin = br.readLine(); try { if (pin.length() > 0) { accessToken = twitter.getOAuthAccessToken(requestToken, pin); } else { accessToken = twitter.getOAuthAccessToken(); } } catch (TwitterException te) { if (401 == te.getStatusCode()) { Logger.logInfo("Unable to get the access token."); } else { te.printStackTrace(); } } } // persist to the accessToken for future reference. Logger.logInfo(String.valueOf(twitter.verifyCredentials().getId())); Logger.logInfo("token : " + accessToken.getToken()); Logger.logInfo("tokenSecret : " + accessToken.getTokenSecret()); mainLoop(); } catch (IOException e) { Logger.logErr("Problem running Tweetster.", e); } catch (TwitterException ex) { Logger.logErr("Fatal Error with Twitter Client.", ex); } System.exit(0); } /** * the main program logic loop, runs until exit() * */ public void mainLoop() { while (isRunning()) { try { // TODO: avail ourselves of these // twitter.getId() // twitter.getIncomingFriendships(cursor); // ResponseList blockingUserList = twitter.getBlockingUsers(); // AccountTotals acctjson = twitter.getAccountTotals(); // UserStreamListener usl = twitter.getUserListMembers(listOwnerScreenName, listId, cursor) // usl.onFollow(arg0, arg1); // twitter.createFriendship(userId); // process main tasks Logger.logInfo("Authenticating User"); authenticate(); // update the static fields in the sheet setSheetname(SHEET_CONTROL); Logger.logInfo("Accessing Timeline"); List statuses = twitter.getUserTimeline(); // get the Twitter user account object User uxr = null; if(statuses != null && statuses.size()>0) uxr = statuses.get(0).getUser(); // for (Status status : statuses) { // process all lastTweets // Logger.logInfo(status.getUser().getName() + ":" + // status.getText()); // } this.addCell(Tweetster.CELL_USERNAME, uxr.getScreenName()); this.userName = this.getCell(Tweetster.CELL_USERNAME).toString(); this.addCell(Tweetster.CELL_FOLLOWING_CT, uxr.getFriendsCount()); // friends are followers? ok. this.addCell(Tweetster.CELL_FOLLOWER_CT, uxr.getFollowersCount()); // spreadsheets FTW! Date cal = new Date(); this.addCell(Tweetster.CELL_DATA_DATE, cal.toLocaleString()); // TODO: get a better calendar if(statuses.size()>0){ this.lastTweet = statuses.get(0).getText(); this.lastTweet = URLDecoder.decode(this.lastTweet, "utf-8"); // TODO: improve this. this.addCell(Tweetster.CELL_CURRENT_TWEET, lastTweet); this.lastTweetDate = statuses.get(0).getCreatedAt(); this.addCell(Tweetster.CELL_LASTTWEET, lastTweetDate); } setSheetname(SHEET_DATA); // perform searches on users and keywords // this can get interesting... very interesting. TreeMap keywordTweets = new TreeMap(); String[] keywords = this.getList(this.NAME_KEYWORDLIST); Object[][] tweets; for(String k : keywords){ k = StringTool.allTrim(k); k = StringTool.strip(k, "'"); if(k.length()>2){ Logger.logInfo("Searching tweets containing: " + k); try{ // touchy tweets = searchTweets(k); for(Object[] t : tweets){ // TODO: analysis etc. Logger.logInfo("Tweet from " + t[0] + ": " +t[1]); keywordTweets.put(t[0], t[1]); // deduped and sorted... we want the users more than tweets... // this.addCell(celladdr, val) Object[] objarr = {t[0], t[1]}; for(int x=0;x