Groovyでfacebookへ近況書き込み

Facebook, Groovy

先日成功したfacebookのOAuth2.0認証方式をクラス化した。

クラスと使用例をあげる。
OAuth2.0認証にて取得したアクセストークンさえあれば、restfbライブラリを利用してfacebookに自由にアクセスできる。
RestFB - A Lightweight Java Facebook Graph API and Old REST API Client

FacebookOauth.Groovy

#!/usr/bin/env groovy
@Grab("org.mortbay.jetty:jetty-embedded:6.1.26")
import java.lang.reflect.InvocationTargetException
import java.lang.reflect.Method
import javax.servlet.http.*
import javax.servlet.ServletException
import org.mortbay.jetty.Connector
import org.mortbay.jetty.Handler
import org.mortbay.jetty.handler.AbstractHandler
import org.mortbay.jetty.Request
import org.mortbay.jetty.Server
class FacebookOauth {
def appId
def localHost = "localhost"
def localPort = 9999
def scopeList = []
def String accessToken = null
def String expiresIn = null
def accessTokenFile = new File("access_token.txt")
void load() {
if( accessTokenFile.exists() )
this.accessToken = accessTokenFile.text
}
void save() {
accessTokenFile.write this.accessToken
}
String auth() {
assert appId
assert localHost
assert localPort
assert !accessToken
assert !expiresIn
assert scopeList && !scopeList.empty
def urltext = "https://www.facebook.com/dialog/oauth?" + [
"client_id=${appId}",
"redirect_uri=" + URLEncoder.encode("http://${localHost}:${localPort}/login_success.html", "utf-8"),
"scope=" + URLEncoder.encode(scopeList.join(","), "utf-8"),
"response_type=token",
].join("&")
def browser = { url ->
switch(System.getProperty("os.name", "")) {
case ~/^Mac OS/:
Class fileMgr = Class.forName("com.apple.eio.FileManager")
Method openURL = fileMgr.getDeclaredMethod("openURL", [ String.class ] as Class[])
openURL.invoke(null, [ url ] as Object[])
break
case ~/^Windows/:
return Runtime.runtime.exec("rundll32 url.dll,FileProtocolHandler " + url)
break
                default:
def enableBrowser = [ "firefox", "opera", "konqueror", "epiphany", "mozilla", "netscape" ].find{
Runtime.runtime.exec([ "which", it ] as String[]).waitFor() == 0
}
if (!enableBrowser)
throw new NoSuchMethodException("Could not find web browser")
return Runtime.runtime.exec(enableBrowser + " ${url}")
break
}
}(urltext)
def server = new Server(localPort)
server.with{
connectors.each{
it.host = "${localHost}"
}
handler = [
                handle:{ String target, HttpServletRequest request, HttpServletResponse response, int dispatch ->
switch(target) {
case "/login_success.html":
response.with{
status = HttpServletResponse.SC_OK
contentType = "text/html"
writer.withWriter{
it.println("<html>")
it.println("<head>")
it.println("<script type='text/javascript'>")
it.println("function init() {")
it.println("    window.location = 'http://localhost:9999/access_token.html?' + window.location.toString().split('#')[1];");
it.println("}")
it.println("</script>")
it.println("</head>")
it.println("<body onload=\"init();\">")
it.println("</body>")
it.println("</html>")
}
}
break
case "/access_token.html":
synchronized(this){
accessToken = request.getParameter("access_token")
expiresIn = request.getParameter("expires_in")
}
request.handled = true
break
                        default:
response.status = HttpServletResponse.SC_NOT_FOUND
break
}
}
] as AbstractHandler
}
server.start()
while ( !accessToken ) {
Thread.sleep(1000)
}
browser.destroy()
server.stop()
server.join()
this.accessToken
}
}

Example.groovy

#!/usr/bin/env groovy
@Grab("com.restfb:restfb:1.6.9")
import com.restfb.*
import com.restfb.types.*
FacebookOauth oauth = new FacebookOauth(
    appId:"XXXXXXXXXX", // acebookに登録したアプリケーションのIDを設定
    scopeList:[ // スコープの設定を配列で列挙。必要なら権限を追加する。
"email",
"read_stream",
"friends_about_me",
"read_friendlists",
"user_about_me",
"publish_stream",
"offline_access",
"create_event"
],
// その他、認証開始のためのローカルサーバー用設定値(localHost、localPort)や
// アクセストークン保存ファイル(accessTokenFile)などのプロパティも設定可能
// 今回はデフォルトのまま使用。
)
// loadすれば、以前取得したトークンがあればそれを利用しfacebookと通信する。
oauth.load()
// loadしてもトークンがからだった場合(=初めての認証)、認証手続きにてアクセストークン取得
FacebookClient client = new DefaultFacebookClient(oauth.accessToken ?: oauth.auth() )
// 今後も利用したい場合、アクセストークンを保存
oauth.save()
5.times {
FacebookType publishMessageResponse = client.publish(
"me/feed",
FacebookType.class,
Parameter.with("message", "ゲンゾウ時計:" + new Date().format("yyyy/MM/dd HH:mm:ss"))
)
Thread.sleep(5000)
}

近況報告を5秒ごとに登録してみた。

明日はユーザー情報の一覧を取得してみる。
もう少しでようやく当初の目標である、ユーザーごとの近況報告一覧表示ができるようになりそうだ。

Facebook, Groovy