sudo -u grails

Grailsの記事が充実する。といいなぁ

Twitter連携するWebアプリなんてあっという間にできるよ。そう、Grailsのspring-security-twitterプラグインならね!

pull requestがmergeされてプラグインが更新されて不便なところが解消された記念に紹介します。

  • spring-security-twitter プラグインを導入する
  • Role をつくる
  • GSP に連携ボタンを設置する

たったこれだけです。

spring-security-twitter プラグインを導入する

http://grails.org/plugin/spring-security-twitter に書いてある通り、 BuildConfig.groovyrepositories ブロックに

mavenRepo "http://maven.springframework.org/release/"

を、 plugins ブロックに

compile ":spring-security-twitter:0.5.2"

を、それぞれ追記します。そのあと refresh-dependencies コマンドで、追記したプラグインの依存性を解決します。

grails> refresh-dependencies

| Loading Grails 2.1.5
| Configuring classpath.
| Environment set to development....
| Installing zip spring-security-twitter-0.5.2.zip.....
| Installed plugin spring-security-twitter-0.5.2
| Resolving plugin JAR dependencies

**************************************************************
* You've installed the Spring Security Twitter plugin.       *
*                                                            *
* Next run the "s2-init-twitter" script to configure plugin. *
*                                                            *
**************************************************************

| Resolving plugin JAR dependencies.....
| Installing zip spring-security-core-1.2.7.2.zip.....
| Installed plugin spring-security-core-1.2.7.2
| Resolving plugin JAR dependencies

*******************************************************
* You've installed the Spring Security Core plugin.   *
*                                                     *
* Next run the "s2-quickstart" script to initialize   *
* Spring Security and create your domain classes.     *
*                                                     *
*******************************************************

| Resolving plugin JAR dependencies...
| Dependencies refreshed.

みたいな感じで、Mavenリポジトリからダウンロードしてプラグインのインストールをしてくれます。丁寧にインストラクションを出してくれてるので、まずは s2-quickstart コマンドから打ちましょう。これは、spring-security-twitterプラグインのベースとなっているspring-security-coreプラグインのコマンドです。

grails> s2-quickstart jp.myapp User Role

これで、プラグインで扱うユーザとロールのドメインクラスができあがります。 jp.myapp っていうのはpackage名ですね。自分のアプリで任意に決めて付けてください。次に

grails> s2-init-twitter
(中略)
> Enter your Twitter API Key twitter
> Enter your Twitter API Consumer Key sOMeTwiTTErcoNSumERKEy
> Enter your Twitter API Consumer Secret sOMeTwiTTErcoNSumERSEcRETTwiTTErcoNSumERS

です。 API Key というのを聞いてきますが、任意の文字列で構いません。 Consumer KeyConsumer Secrethttps://dev.twitter.com/ で払い出したものを使いましょう。

Role をつくる

Role が無くても動作はするのですが、「認証を通ったか通ってないか」で画面を振り分けたりするときにこれが無いと不便なので、作っておきましょう。 BootStrap.groovy

import jp.myapp.Role

class BootStrap {

  def init = { servletContext ->
    Role.findByAuthority("ROLE_USER") ?: new Role(authority:"ROLE_USER").save()
    Role.findByAuthority("ROLE_TWITTER") ?: new Role(authority:"ROLE_TWITTER").save()
  }
}

みたいな感じで書いておけばOKです。ROLE_USERとROLE_TWITTERが存在しなかったら作って保存する、というだけのコードです。 ?: はエルビス演算子ですね。2つ作ってる理由は、spring-security-twitterプラグインがデフォルトでその2つのロールを利用するからです。必要であれば設定を変えることもできます。

GSP に連携ボタンを設置する

こんなGSPコードを index.gsp の末尾のほうに追記するだけで、連携を確認できます。

<sec:ifLoggedIn>
  <div class="message">Authenticated. Hello <sec:username/>!</div>
</sec:ifLoggedIn>
<sec:ifNotLoggedIn>
  <div class="message">Not authenticated. <twitterAuth:button /> </div>
</sec:ifNotLoggedIn>

run-app して動作を確認してみましょう。実行したアプリを開くと、こんな画面が出るので「Connect with Twitter」をクリックしましょう。

f:id:y___u:20130522151356p:plain

いつものTwitter連携画面が出るので、承認してあげます。

f:id:y___u:20130522151401p:plain

すると、元の画面に戻りますが、自分のTwitterIDでメッセージが表示されますね!

f:id:y___u:20130522151405p:plain

内部では、TwitterIDでアカウントが生成され、そのアカウントでのログイン処理が行われています。つまり、自分の作ったWebアプリ用のユーザ認証の仕組みと、そのTwitter連携ができているのです。

TwitterAPIを使って投稿してみる

ここまでやったんだから、投稿についても試してみましょう。

まず、デフォルトパッケージで生成されている TwitterUser クラスを自分のpackageに移動し、 TwitterTemplate を取得するメソッドを追加します。こんな感じになりますね。

package jp.myapp

import org.springframework.social.twitter.api.impl.TwitterTemplate;

class TwitterUser {

  Long twitterId
  String username

  String tokenSecret
  String token

  static belongsTo = [user: User]

  static constraints = {
      twitterId(unique: true, nullable: false)
      username(nullable: false, blank: false)
  }

  TwitterTemplate getTwitterTemplate(config){
    new TwitterTemplate(
      config.grails.plugins.springsecurity.twitter.consumerKey,
      config.grails.plugins.springsecurity.twitter.consumerSecret,
      token,
      tokenSecret )
  }
}

TwitterTemplatespring-social-twitterに含まれるクラスですね。もちろんimportもしてあげます。

あとは、つぶやくためのコントローラを作ってあげればよいです。こんな感じに書けますね。

package jp.myapp

import grails.plugins.springsecurity.SpringSecurityService
import org.springframework.social.twitter.api.impl.TwitterTemplate

class TweetController {
  def springSecurityService

  def index() {
    def tw = TwitterUser.findByUsername( springSecurityService.getCurrentUser().username ).getTwitterTemplate(grailsApplication.config)
    def st = tw.timelineOperations().updateStatus("#Grails のspring-security-twitterプラグインを使ってつぶやいています。 #yokohamagroovy #mattarigrails")
    render st.getCreatedAt()
  }
}

springSecurityService からログインしているユーザを取得し、そのユーザ名を元に TwitterTemplate を取得し、 TimelineOperations のupdateStatusによってつぶやきを投稿しています。

このアクションを実行するには、アプリのコントローラ一覧から jp.myapp.TweetController をクリックすればよいですね。renderでつぶやきの作成日時を返しているので、ブラウザ上は Wed May 22 16:16:11 JST 2013 みたいな結果が得られるでしょう。

基本的に TwitterTemplate を取得できるようにしておけば、ほとんどあらゆるAPIの操作ができます。そのあたりは、TwitterTemplateのJavaDocから

  • BlockOperations
  • DirectMessageOperations
  • FriendOperations
  • GeoOperations
  • ListOperations
  • SearchOperations
  • TimelineOperations
  • UserOperations

あたりを辿ればだいたいわかりますよ!