java-ja温泉成果物 @で話しかけるとsayコマンドでしゃべるbot
java-ja温泉ではsayコマンドで盛り上がってました。
んで、"@saybot hogehoge"のように@をつけて話しかけると、sayコマンドでしゃべるbotをscalaで書いてみました。
Runtime#execでsayコマンドを実行しているので、このbotが動いているマシンでしかしゃべらないです。
つまり、オレのマシンです。
import scala.actors._ import java.lang.Thread import java.net.{Authenticator, PasswordAuthentication} import java.net.{URL, HttpURLConnection} import java.text.SimpleDateFormat import java.util.Locale import java.util.Calendar import scala.xml.XML import scala.util.matching._ object SayBot extends Application{ // Replyを取得する間隔(millsec) val INTERVAL = 60 * 1000 val twitterId = "saybot" val twitterPass = "******" Authenticator.setDefault( new Authenticator { override def getPasswordAuthentication = { new PasswordAuthentication(twitterId, twitterPass.toCharArray); } } ) val url = "http://twitter.com/statuses/replies.xml" // Actor object SayActor extends Actor{ // 前回Replyを取得した時刻 var cl:Calendar = Calendar.getInstance cl.add(Calendar.HOUR_OF_DAY , -9) var lastTime = cl.getTimeInMillis def act = { getReplies Thread.sleep(INTERVAL) } // Replyを取得する def getReplies(){ val df = new SimpleDateFormat("EEE MMM dd HH:mm:ss +0000 yyyy", Locale.US) println( "getReplies " + lastTime + ":" + df.format(lastTime)) val urlConn = new URL(url).openConnection.asInstanceOf[HttpURLConnection] urlConn.connect(); urlConn.getResponseCode for (s <- XML.load(urlConn.getInputStream) \ "status" reverse ; created_at = s \ "created_at" text ; time = df.parse(created_at).getTime if(time>lastTime)) { var (text, user_name) = (s \ "text" text, s \ "user" \ "name" text) println( user_name + ":" + text ) lastTime = time val r = new Regex("@" + twitterId + "\\s(.+)$") r.findAllIn(text).matchData.foreach( i=>{ say( i.group(1) )} ) } } // sayコマンドを実行する def say( message :String){ var rt:Runtime = Runtime.getRuntime rt.exec( "say " + message) // とりあえず文字数×0.5secだけsleep Thread.sleep( message.length * 500) } } while( true ){ SayActor.act } }
idとpasswordをちがうアカウントにすれば使えるようになるはずです。
まぁ、ぶっちゃけかなりショボいコードです。
まず日本語はダメです。そのうちyahoo日本語係り受け解析とかでヨミを解析してしゃべるようにするかも。
ホントはActorライブラリの勉強だったんだど、まったくActorを使う意味がないコードになっています。
あと、Replyが複数あると声がかぶるとか。例外処理ちゃんとやってねぇとか。