Scalaでニコ生アラート
rubyとかjavaとかでニコ生アラートつくってみた、という記事はありますがScalaでニコ生アラートつくってみた、というのがなかった(or 見つけられなかった)ので作ってみました。
Web APIとの通信はDispatcherを使っているのでBuild.scalaでDependenciesに追加する必要があります
NicoliveAlert.scala
/**
* author: crexista
*/
class NicoLiveAlertClient {
val mailAddress = ""//ここにニコニコ動画に登録してるメールアドレスを入れます
val passWord = ""//ここにニコニコ動画にログインするさいのパスワードをいれます
val authURL = "https://secure.nicovideo.jp/secure/login?site=nicolive_antenna"
val userAgent = "NicoLiveAlert 1.0.0"
val apiURL = "http://live.nicovideo.jp/api/"
val getAlertAPI = "getalertstatus"
def start() = {
val http = new Http
val param = Map[String, String]("mail" -> mailAddress, "password" -> passWord)
val userAgentMap = Map[String,String]("User-Agent" -> userAgent)
//ユーザー認証トークンです
val token = (http(url(authURL).POST <:< userAgentMap << param >> ((a:InputStream) => XML.load(a))) \\ "ticket").text
//ニコ生アラートに接続するためのスレッド情報を取得します
val alertStatus = http(url(apiURL + getAlertAPI).POST << Map("ticket" -> token) >> ((a:InputStream) => XML.load(a)))
val host = (alertStatus \\ "ms" \\ "addr").text
val port = (alertStatus \\ "ms" \\ "port").text.toInt
val thread = (alertStatus \\ "ms" \\ "thread").text.toInt
val socket = new Socket(host, port)
val echoMessage = "<thread thread=\"" + thread.toString + "\" version=\"20061206\" res_from=\"-1\"/>\0"
val recieveData:ArrayBuffer[Byte] = new ArrayBuffer[Byte](200)
socket.getOutputStream.write(echoMessage.getBytes("UTF-8"))
socket.getOutputStream.flush()
while(true) {
val onData = socket.getInputStream.read.toByte
recieveData += onData
if (onData == 0){
println(new String(recieveData.toArray, "UTF-8"))
recieveData.clear()
}
}
}
}
はまりどころ
ニコ生のコメントサーバはXmlSocketというプロトコルを使っていて
xmlデータの最後には改行コードではなくNULL文字をつけて通信しているということ。
詳しくはここ
http://d.hatena.ne.jp/rivertop/20070622/1182529919
なので、getlineとかつかうとずっと待ち受け状態になってしまう。
Build.scala
ニコニコ生放送のWeb APIをDispatcherを使って叩いているのでDispatcher(classic)をDependenciesで呼んであげる必要がある
Build.scala
import sbt._
import sbt.Keys._
object NicoLiveAlertBuild extends Build {
val dispatch = "net.databinder" %% "dispatch-http" % "0.8.9"
val typeSafeResolver = "Typesafe Repository" at "http://repo.typesafe.com/typesafe/releases/"
lazy val root = Project(
id = "NicoliveAlert",
base = file("."),
settings = Project.defaultSettings ++ Seq(
name := "NicoliveAlert",
organization := "st.crexi",
scalaVersion := "2.10.0",
libraryDependencies ++= Seq(dispatch),
resolvers ++= Seq(typeSafeResolver)
)
)
}