Scala.jsを使ってHubotのコードを書いてみた時の話

  • 5
    いいね
  • 0
    コメント
この記事は最終更新日から1年以上が経過しています。

Hubotのインターフェース部分はJavaScriptにまかせて、ロジック部分(?)をScalaで書いてみた時の雑記です。
この辺みて、全部Scalaでやってる・・・すごい・・・と思い、とりあえずScala.js使ってHubot書いてみるかと思ったのが始まりでした。

https://speakerdeck.com/kinzal/jiang-jun-suhonsaou-riip-miwaku-in-shi-kegu-geeknight-number-7-scalada-ming-falseping-cheng-wei-xin-dian-zhong-tescala

https://github.com/newta/scalajs-hubot

Hubot準備

このあたり見つつ yo hubot します。
https://hubot.github.com/docs/

$yo hubot
                     _____________________________
                    /                             \
   //\              |      Extracting input for    |
  ////\    _____    |   self-replication process   |
 //////\  /_____\   \                             /
 ======= |[^_/\_]|   /----------------------------
  |   | _|___@@__|__
  +===+/  ///     \_\
   | |_\ /// HUBOT/\\
   |___/\//      /  \\
         \      /   +---+
          \____/    |   |
           | //|    +===+
            \//      |xx|

? Owner: ...
? Bot name: scalajs
? Description: scala is cool
? Bot adapter: (campfire) slack
? Bot adapter: slack
   create bin/hubot
   create bin/hubot.cmd
   create Procfile
   create README.md
   create external-scripts.json
   create hubot-scripts.json
   create .gitignore
   create package.json
   create scripts/example.coffee
   create .editorconfig

Scala.js等準備

チュートリアルがしっかりしているのでこれで終了です。
https://www.scala-js.org/tutorial/basic/

$cat path/to/project/plugins.sbt
addSbtPlugin("org.scala-js" % "sbt-scalajs" % "0.6.8")

$cat path/to/project/build.properties
sbt.version=0.13.9

$cat path/to/build.sbt
enablePlugins(ScalaJSPlugin)

name := "Scala js in Hubot"

scalaVersion := "2.11.7"

scalaJSOutputWrapper := ("var __ScalaJSEnv = { exportsNamespace: exports };", "")

tips

  • scalaJSOutputWrapperをつけるとjs側で下記のように書けます
"use strict";
const scalajs = require("../lib/scala-js-in-hubot-fastopt.js");
const hoge = scalajs.com.ru.waka.Hoge()

これがないとどうなるかというと

"use strict";
const scalajs = require("../lib/scala-js-in-hubot-fastopt.js").__ScalaJSExportsNamespace
const hoge = scalajs.com.ru.waka.Hoge()

というように書かなければならなくなります。

参考

Scalaでpongするだけの機能を書く

こんな感じの雑スクリプト書きました。
src/main/scala/com/ru/waka/Hoge.scala

package com.ru.waka

import scala.scalajs.js.JSApp
import scala.scalajs.js.annotation.{JSExportAll, JSExport}

@JSExportAll
object Hoge extends JSApp {
  def ping(): String = "pong"

  @JSExport
  override def main(): Unit = println("hoge")
}

とりあえずjavascriptに変換してsrc/libディレクトリにでも置いておきましょう。

$sbt fastOptJS
[info] Loading project definition from /Users/t-arata/Documents/MiddleWareWorkspace/hubot/scalajs/project
[info] Set current project to Scala js in Hubot (in build file:/Users/t-arata/Documents/MiddleWareWorkspace/hubot/scalajs/)
[success] Total time: 1 s, completed 2016/04/26 22:50:27
$cp -rf target/scala-2.11/scala-js-in-hubot-fastopt.js ./src/lib/scala-js-in-hubot-fastopt.js

JavaScriptでHubotScriptを書く

書いた物はこんな感じです

src/scripts/ping.js

// Description:
//  test

"use strict";
const scalajs = require("../lib/scala-js-in-hubot-fastopt.js");
const hoge = scalajs.com.ru.waka.Hoge()

module.exports = (robot => {
    robot.respond(/ping/i, res => {
        res.send(hoge.ping())
    })
})

Hubotはデフォルトで /scripts/src/scripts のディレクトリを見に行ってくれるんですが、とりあえずsrcディレクトリにコード集めたかったのでこっちにおいてます。

最後に起動

こんな感じで書けば起動するはずなので、起動してみました。

$bin/hubot
scalajs> scalajs ping
scalajs> pong

反応返ってきましたね。めでたしめでたし。
Scala.js趣味のHubotで使うならいい感じな気がしました。
多分動くレポジトリはこちらなのでご参考に・・・
https://github.com/ara-ta3/scalajs-with-hubot