Twitter4j ve Wicket

Şu sıra gerek çalıştığım şirkette olsun gerekse boş zamanlarımda olsun, sosyal medya ile kendi projeleri nasıl birleştirebileceğim üzerine yoğunlaşmış durumdayım. Bunun asıl sebebi üzerinde çalıştığım bir projede, kayıt formunda kullanının hem facebook hemde twitter hesaplarını kullanıcının profiline bağlamak durumunda kalmam. Bunu yaparken facebook tarafında önceden yazdığım facebook yazsının katkısı büyük oldu.

Baslamadan Önce

Bu gün ise bir twitter uygulamasının nasıl geliştirleceğine bakacağız. Yine her zaman ki gibi şu sıralar benim gözdem olan Wicket frameworkünü kullanacağım. Twitter kısmında ise Twitter4j API’sini kullanacağım. Tabi sadık dostumuz Maven’ide unutmamak gerekiyor.

Herşeyden önce, facebook’ta olduğu gibi, uygulamanızı Twitter sistemine kayıt ettirmeniz gerekiyor. Bunun için Twitter’ın development sayfasına yönleniyoruz. Twitter kullanıcı adı ile giriş yaptıktan sonra, My Applications alt menüsünden uygulamalarım kısmına giriş yapıyoruz. Burada Create New Application seçip uygulamamızı yaratıyoruz.

Burada bizim için Consumer Key ve Consumer Secret bilgileri çok önemli. Uygulamamız içerisinde bunları kullanacağız. Ben uygulama içerisinde kolay kullanabilmek için SocialMedia isimli bir sınıf yaratıp bu bilgileri içerisine yerleştirdim. Size de aynısını yapmanızı öneririm. Bu yazının devamında Consumer Key ve Secret bilgilerine bu sınıf üzerinden erişilecektir.

Twitter Development sitesinde işimizi bitirmeden önce son bir ayar yapalım ki ileride başımız ağrımasın.Read, Write and Access direct messages kurallarına sahip olacak şekilde AccessToken’ınızı yaratmanızı istiyorum. Bu sayede olası yetiklendirme engellerinin önüne geçebileceksiniz.

Şimdi ise Maven ile önceden açıkladığım şekilde bir Wicket projesi oluşturuyoruz. Daha sonrasında HomePage sınıfının içerisini boşaltıyoruz. Tabi bunu yaparken aynı sınıfa ait html sınıfının içeriğini temizlemeyide unutmuyoruz. Bundan sonra tek yapmamız gereken Twitter4j bağımlılığımızı pom.xml dosyamıza eklemek.

pom.xml

...
<dependency>
<groupId>org.twitter4j</groupId>
<artifactId>twitter4j-core</artifactId>
<version>2.2.5</version>
</dependency>
...

Paneller ve Sayfalar

Artık yapacağımız şey Twittter için Wicket panelleri ve sayfaları oluşturmak. Fakat önce kısaca uygulamanın ne yapacağından bahsedelim.

  • Uygulama bir form içerisinde TwitterConnect bileşenine sahip olacak. Bu form bir panel içerisinde olacak.
  • Kullanıcı TwitterConnect’e tıkladığında, Twitter’a yönlenecek.
  • Kullanıcı gerekli izinleri verdikten sonra karşısına TwitterPIN bilgisi gelecek.
  • Bu PIN bilgisini yarattığımız panel içerisindeki forma yazacak ve devam edecek.
  • Eğer kullanıcıdan gerekli izinler alınabildiyse, kullanıcı yeni bir sayfaya yönlenecek.
  • Bu sayfada kullanıcı istediği gibi durumunu güncelleyebilecek.
  • Son olarak demoya bakarak istediğinizin bu olup olmadığına karar verebilirsinioz

TwitterPanel

İşimize twitter panelimizi ve içeriğini yaratmakla başlayalım. Yaptığımız girişten de anlaşıldığı üzere, panelimizin içinde bir formumuz olacak. Bu formun içerisinde ise bir text giriş alanı, bir link ve bir buton bulunacak. Link twitter connect özelliğini sağlayacak ve kullanıcıyı twitter’a giriş yapmaya yönlendirecek. Bu link doğrudan Twitter4j API’si tarafından hazırlanabiliyor.

Kullanıcı giriş yaptıktan sonra birazdan gerçekleştireceğimiz TwitterPage sayfasına yönelecek.

TwitterPanel.java


package blg.bhdrkn.wicket.twitter;

import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.form.AjaxButton;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.markup.html.link.Link;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.PropertyModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import twitter4j.Twitter;
import twitter4j.TwitterException;
import twitter4j.TwitterFactory;
import twitter4j.auth.AccessToken;
import twitter4j.auth.RequestToken;

public class TwitterPanel extends Panel {

private static final long serialVersionUID = 1L;
private static final Logger logger = LoggerFactory.getLogger(TwitterPanel.class);

private Twitter twitter;
private RequestToken requestToken;
private String twitterPinModel = "";

private AccessToken accessToken;

public TwitterPanel(String id) {
super(id);
createTwitter();
Form<Void> twitterForm = new Form<Void>("twitterForm");
addTwitter(twitterForm);
addFormSubmit(twitterForm);
add(twitterForm);
}

private void createTwitter() {
try {
twitter = new TwitterFactory().getInstance();
twitter.setOAuthConsumer(SocialMedia.TWITTER_CONSUMER_KEY,
SocialMedia.TWITTER_CONSUMER_SECRET);
requestToken = twitter.getOAuthRequestToken();
} catch (TwitterException e) {
e.printStackTrace();
}
}

private void addFormSubmit(Form<Void> twitterForm) {
twitterForm.add(new AjaxButton("button") {

private static final long serialVersionUID = 1L;

@Override
protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
try {
accessToken = twitter.getOAuthAccessToken(
requestToken, twitterPinModel);
setResponsePage(new TwitterPage(accessToken));
} catch (TwitterException e) {
logger.error("Error While Getting AccessToken: "
+ e.getMessage());
e.printStackTrace();
}
}

@Override
protected void onError(AjaxRequestTarget target, Form<?> form) {
logger.error("Error");
}

});
}

private void addTwitter(Form<Void> twitterForm) {

Link<String> simpleLink = new Link<String>("twitterLink") {

private static final long serialVersionUID = 1L;

@Override
public void onClick() {

}

@Override
protected CharSequence getURL() {
return requestToken.getAuthenticationURL();
}
};

TextField<String> twitterPIN = new TextField<String>("twitterPIN",
new PropertyModel<String>(this, "twitterPinModel"));

twitterForm.add(simpleLink, twitterPIN);
}
}

class SocialMedia{
public static final String TWITTER_CONSUMER_KEY = "your_counsumer_key";
public static final String TWITTER_CONSUMER_SECRET = "your_counsumer_secret";
}

TwitterPanel.html


<wicket:panel>
<div style="clear: both;"></div>
<div class="boxDark">
<div class="span-17 last">
<div class="span-3"><p/></div>
<div class="span-14 last">
Twitter Form
</div>
</div>
<div class="clear"></div>
<div class="span-17 last" style="height: 40px;"><hr/></div>
<div class="span-17 last" style="height: 100px;">
<p>
Other Form Component Can be added and submited with Twitter PIN.
After submission there will be a new page which enables you to update twitter status.
<br/>
You must disable popup blocker to access twitter pin. After disabling the popup blocker please refresh to get twitter connect link.
</p>
</div>
<div class="span-17 last">
<form wicket:id="twitterForm">
<label for="twitter">Twitter Connect: </label>
<input id="twitter" name="twitter" type="text" wicket:id="twitterPIN"/>
<a wicket:id="twitterLink" target="_blank"><img src="images/twitter.png" /></a>
<div class="clear"></div>

<label for="save"></label>
<input name="save" id="save" type="submit" wicket:id="button" value="Proceed"/>

<div class="clear"></div>
</form>
</div>
<div class="clear"></div>
</div>
<div style="clear: both;"></div>

</wicket:panel>

TwitterPage

Wicket için TwitterPanel kısmını yazdıkdan sonra geriye sadece TwitterPage kımını yazmak kalıyor.  Bu sayfa ise twitter bağlantısı yapılmış kullanıcıların yönleneceği sayfadır. Kullanıcı buradan durumunu güncelleyip testini gerçekleştirebilir.

TwitterPage.java


package blg.bhdrkn.wicket.twitter;

import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.form.AjaxButton;
import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.TextArea;
import org.apache.wicket.model.PropertyModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import twitter4j.Twitter;
import twitter4j.TwitterException;
import twitter4j.TwitterFactory;
import twitter4j.auth.AccessToken;

public class TwitterPage extends WebPage {

private static final long serialVersionUID = 1L;
private static final Logger logger = LoggerFactory.getLogger(TwitterPage.class);

private Twitter twitter;
private AccessToken token;

private Form<Void> tweetForm;
private TextArea<String> tweetArea;
private String tweetModel;

public TwitterPage(AccessToken token) {
this.token = token;
addHashTagNews();
addTweetForm();
}

private void addHashTagNews() {

}

private void addTweetForm() {
tweetForm = new Form<Void>("tweetForm");
tweetArea = new TextArea<String>("tweetArea",
new PropertyModel<String>(this, "tweetModel"));
tweetArea.setOutputMarkupId(true);
tweetForm.add(tweetArea);
tweetForm.add(new AjaxButton("updateStatus") {

private static final long serialVersionUID = 1L;

@Override
protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
try {
twitter = new TwitterFactory().getInstance();
twitter.setOAuthConsumer(SocialMedia.TWITTER_CONSUMER_KEY,
SocialMedia.TWITTER_CONSUMER_SECRET);
twitter.setOAuthAccessToken(token);
twitter.updateStatus(tweetModel);
target.appendJavaScript("alert('Status Updated: "
+ tweetModel + "');");
tweetModel = "";
target.add(tweetArea);
} catch (TwitterException e) {
logger.error("Error While Updating the Status");
e.printStackTrace();
}
}

@Override
protected void onError(AjaxRequestTarget target, Form<?> form) {
logger.error("Error Before Updating the Status");
}
});
add(tweetForm);
}
}

TwitterPage.html

<!DOCTYPE html>
<html xmlns:wicket="http://wicket.apache.org">
<head>
<title>Wicket Tiwtter4j Tutorial</title>
</head>
<body>
<div class="span-24 append-bottom">
<div class="clear"></div>
<div class="boxDark">
<div class="span-24">
<div class="span-3"><p/></div>
<div class="span-21">
Twitter - Update Status
</div>
</div>
<div class="clear"></div>
<div class="span-24" style="height: 40px;"><hr/></div>
<div class="span-24">
<form wicket:id="tweetForm">
<textarea cols="110" rows="2" wicket:id="tweetArea"></textarea>
<input type="submit" wicket:id="updateStatus" value="Update Status"/>
</form>
</div>
<div class="clear"></div>
</div>
<div class="clear"></div>
</div>

</body>
</html>

Sayfalar ve paneller bittikten sonra geriye TwitterPanel’in ekleneceği yeri belirlemek kalıyor. Hatırlarsanız projemizin başında HomePage sınıfımızın içeriğini temizlemiştik. Şimdi tek yapmamız gereken bu sınıfın içine TwitterPanelimizi eklemek.

HomePage.java


package blg.bhdrkn.wicket.twitter;

import org.apache.wicket.request.mapper.parameter.PageParameters;
import org.apache.wicket.markup.html.WebPage;

public class HomePage extends WebPage {
private static final long serialVersionUID = 1L;

public HomePage(final PageParameters parameters) {
add(new TwitterPanel("twitterPanel"));
}
}

HomePage.html

<!DOCTYPE html>
 <html xmlns:wicket="http://wicket.apache.org">
 <head>
 <title>Wicket Tiwtter4j Tutorial</title>
 </head>
 <body>
 <div wicket:id="twitterPanel"></div>
 </body>
 </html>

Son

Sizde göreceğiniz üzere başarıyla Twitter’a durum güncellemeleri yapılabiliyor. Eğer kodu takip ederken sorun yaşadıysanız aşağıdaki adresten kodun tamamını indirip deneyebilirsiniz. Bunun yanı sıra eğer HashTag bilgilerinin nasıl çekileceğini düşünüyorsanız, kaynak kodlarının içerisinde bununla ilgili bir örnek mevcut. Tabi örnek yorum satırı haline getirilmiş durumda, çünkü markup kısmında koodun karşılığı yok. Fakat markup kısmına karşılığını ekleyip deneyebilirsiniz.

GitHub

https://github.com/bhdrkn/Wicket-Examples

End Of Line