Posted at

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

More than 3 years have passed since last update.

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