To access the Twitter Platform, you need to obtain a Consumer Key/Secret pair and an Access Token/Secret pair. Every user who wants his commits to be tweeted needs to do this.
Go to https://apps.twitter.com/ and select Create new app. Once done, open the Keys and Access Tokens tab, then click Create my access token.
Once you have the 4 authentication strings, you might want to check if they are correct and if they truly let you post to Twitter. You can do so with this debug code:
TwitterStatusUpdater.java
1 2import twitter4j.Twitter; import twitter4j.TwitterFactory; import twitter4j.conf.PropertyConfiguration; import java.io.BufferedReader; import java.io.InputStreamReader; import java.util.Properties; /** * Little app to ensure authorisation works and you can publish tweets to Twitter. * First use {@link TwitterTokenGenerator} to obtain access token/secret pair. Then provide this script with the consumer * key/secret and access token/secret. Lastly, type in the twitter message you want to post. */ public class TwitterStatusUpdater { public static void main(String[] args) throws Exception { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); // Consumer key + consumer secret print("Enter consumer key:"); String consumerKey = br.readLine(); print("Enter consumer secret:"); String consumerSecret = br.readLine(); // Access token + access token secret print("Enter access token:"); String token = br.readLine(); print("Enter access token secret:"); String tokenSecret = br.readLine(); TwitterFactory twitterFactory = new TwitterFactory(new PropertyConfiguration(new Properties() {{ put("oauth.consumerKey", consumerKey); put("oauth.consumerSecret", consumerSecret); put("oauth.accessToken", token); put("oauth.accessTokenSecret", tokenSecret); }})); Twitter twitter = twitterFactory.getInstance(); twitter.verifyCredentials(); print("Enter your Twitter status update:"); String twitterUpdate = br.readLine(); twitter.updateStatus(twitterUpdate); print("No exceptions, so your update seems successful"); } private static void print(String x) { System.out.println(x); } }
We'd like to store the 4 authentication strings as one object:
TwitterLoginRecord.java
1 2public class TwitterLoginRecord { private final String consumerKey; private final String consumerSecret; private final String token; private final String tokenSecret; public TwitterLoginRecord(String consumerKey, String consumerSecret, String token, String tokenSecret) { this.consumerKey = consumerKey; this.consumerSecret = consumerSecret; this.token = token; this.tokenSecret = tokenSecret; } public String getConsumerKey() { return consumerKey; } public String getConsumerSecret() { return consumerSecret; } public String getTokenSecret() { return tokenSecret; } public String getToken() { return token; } }
We need to change the "Hello world!" servlet to become a form for typing in the data that will become TwitterLoginRecord
. First declare the variable-class mapping on the first line of the template:
twitterSettings.vm
1 2#* @vtlvariable name="loginRecord" type="com.example.ampstutorial.TwitterAccessTokenRecord" *#
Then change the body
to become a form:
twitterSettings.vm
1 2<body> <div> <form action="./twitter-settings" method="post"> <table class="dialog-prefs" cellspacing="0"> <thead> <tr> <th colspan="2"><h3>Twitter Settings</h3></th> </tr> </thead> <tbody> <tr> <td class="tdLabel"><label for="consumerKey" class="label">Consumer key:</label></td> <td><input type="text" name="consumerKey" value="${loginRecord.consumerKey}" id="consumerKey"/></td> </tr> <tr> <td class="tdLabel"><label for="consumerSecret" class="label">Consumer secret:</label></td> <td><input type="password" name="consumerSecret" value="${loginRecord.consumerSecret}" id="consumerSecret"/></td> </tr> <tr> <td class="tdLabel"><label for="token" class="label">Token:</label></td> <td><input type="text" name="token" value="${loginRecord.token}" id="token"/></td> </tr> <tr> <td class="tdLabel"><label for="tokenSecret" class="label">Token secret:</label></td> <td><input type="password" name="tokenSecret" value="${loginRecord.tokenSecret}" id="tokenSecret"/></td> </tr> <tr> <td></td> <td class="action"><input type="submit" value="Save"/></td> </tr> </tbody> </table> </form> </div> </body>
Note that action="./token-servlet"
specifies where the form will post
the collected data.
To accept the data post
ed from the form, override the doPost
method:
TwitterSettingsServlet.java
1 2import static com.google.common.base.Strings.isNullOrEmpty; @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String consumerKey = request.getParameter("consumerKey"); String consumerSecret = request.getParameter("consumerSecret"); String token = request.getParameter("token"); String tokenSecret = request.getParameter("tokenSecret"); if ( !isNullOrEmpty(consumerKey) && !isNullOrEmpty(consumerSecret) && !isNullOrEmpty(token) && !isNullOrEmpty(tokenSecret)) { storeLoginRecord(consumerKey, consumerSecret, token, tokenSecret); } response.sendRedirect("./twitter-settings"); }
Note how the parameter names match those in the twitterSettings.vm
form.
For the purposes of this tutorial, the username and password are just stored in a Map
in a field of the servlet - this is not persistent. To learn how to save configuration data for your plugins see Storing Plugin Settings for Fisheye .
We'll use TwitterLoginRecordStore
interface, so that we can easily switch to a persistent store in the future.
TwitterLoginRecordStore.java
1 2public interface TwitterLoginRecordStore { TwitterLoginRecord get(String userName); void put(String userName, TwitterLoginRecord record); }
TwitterLoginRecordStoreImpl.java
1 2import java.util.HashMap; import java.util.Map; public class TwitterLoginRecordStoreImpl implements TwitterLoginRecordStore { private final Map<String, TwitterLoginRecord> store = new HashMap<>(); @Override public TwitterLoginRecord get(String userName) { return store.get(userName); } @Override public void put(String userName, TwitterLoginRecord record) { store.put(userName, record); } }
atlassian-plugin.xml
1 2<component key="twitterLoginRecordStore" class="com.example.ampstutorial.TwitterLoginRecordStoreImpl" public="true"> <interface>com.example.ampstutorial.TwitterLoginRecordStore</interface> </component>
TwitterSettingsServlet.java
1 2private final TwitterLoginRecordStore twitterLoginRecordStore; private final TemplateRenderer templateRenderer; public TwitterSettingsServlet(TwitterLoginRecordStore twitterLoginRecordStore, TemplateRenderer templateRenderer) { this.twitterLoginRecordStore = twitterLoginRecordStore; this.templateRenderer = templateRenderer; } private void storeLoginRecord(String consumerKey, String consumerSecret, String token, String tokenSecret) { twitterLoginRecordStore.put(getCurrentUser(), new TwitterLoginRecord(consumerKey, consumerSecret, token, tokenSecret)); }
We use the user login as the key in the store. To get the current user login, we use EffectiveUserProvider
. Add a new dependency:
pom.xml
1 2<dependency> <groupId>com.atlassian.fisheye</groupId> <artifactId>fisheye-jar</artifactId> <version>3.10.0-SNAPSHOT</version> <scope>provided</scope> </dependency>
Inject the user provider to the servlet and use it:
TwitterSettingsServlet.java
1 2import com.atlassian.fecru.user.EffectiveUserProvider; private final EffectiveUserProvider effectiveUserProvider; public TwitterSettingsServlet(EffectiveUserProvider effectiveUserProvider, TwitterLoginRecordStore twitterLoginRecordStore, TemplateRenderer templateRenderer) { this.effectiveUserProvider = effectiveUserProvider; this.twitterLoginRecordStore = twitterLoginRecordStore; this.templateRenderer = templateRenderer; } private String getCurrentUser() { return effectiveUserProvider.getEffectiveUserLogin().getUserName(); }
Once saved, we want to show the data in the form. To fill the form template, we need to modify the get
method:
TwitterSettingsServlet.java
1 2@Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setAttribute("decorator", "fisheye.userprofile.tab"); response.setContentType("text/html"); TwitterLoginRecord loginRecord = twitterLoginRecordStore.get(getCurrentUser()); templateRenderer.render("/templates/twitterSettings.vm", loginRecord != null ? ImmutableMap.of("loginRecord", loginRecord) : ImmutableMap.of(), response.getWriter()); }
Rate this page: