ScalaでSlack botを作った

某社のチャット上で動作する勤怠システムを見て、自分も欲しくなったので作ってみた。
ソースコードは以下に配置した。

github.com

とりあえず勤怠の記録、参照する部分を作成したがまだまだ全然できていない。
AWSかAzureで運用するつもり
以下備忘録

構成

SwaggerでAPI作って、Scala.jsでAPIにアクセスするまで

手順メモ

Swagger Editorインストー

dockerでも配布されていたのでdocker経由でインストー

Swagger Tools Docs

docker run -p 80:8080 --name swagger-editor swaggerapi/swagger-editor

http://localhost/にアクセスする。swagger-editorが表示された。
単純なAPIの疎通確認なので、プリセットで入っているこのサンプルコードをそのまま利用する。

f:id:hkou:20170528104916p:plain

node.js用のサーバーコードを生成

メニューの「Generate Server」から「nodejs-server」を選択する。node.js用のコード一式が詰め込まれたzipファイルがダウンロードされる。 f:id:hkou:20170528105050p:plain

サーバー立ち上げ

準備

nodejs-server-server\api\swagger.yamlを開いて、hostをlocalhost:8080に設定する。

package.jsonがあるディレクトリで以下のコマンドを実行して依存パッケージを落としてくる。

npm install

実行

>node index.js
Your server is listening on port 8080 (http://localhost:8080)
Swagger-ui is available on http://localhost:8080/docs

http://localhost:8080/docsにアクセスする

なんでも良いので適当なAPIを開き、実行してみる(Try it outを押下)。レスポンスが返ってくることを確認 f:id:hkou:20170528110334p:plain

Scala.jsでAPIアクセス側を実装

plugins.sbt

scala-jsプラグインとscalariformプラグインを追加する。

resolvers += Resolver.typesafeRepo("releases")
addSbtPlugin("org.scalariform" % "sbt-scalariform" % "1.6.0")
addSbtPlugin("org.scala-js" % "sbt-scalajs" % "0.6.16")

build.sbt

scala.jsプラグインを有効化

enablePlugins(ScalaJSPlugin)

mainを作成

scalaJSUseMainModuleInitializer := true

依存ライブラリにscala.js-dom, upickleを追加

libraryDependencies += "org.scala-js" %%% "scalajs-dom" % "0.9.1"
libraryDependencies += "com.lihaoyi" % "upickle_sjs0.6_2.12" % "0.4.4"

Code

GET http://localhost:8080/v2/pet/{id}にアクセスしてレスポンス取得、パースしてcase classにマッピングするコード

import org.scalajs.dom.ext._
import upickle.default._
import scala.concurrent.ExecutionContext.Implicits.global
import scala.scalajs.js.JSApp
import scala.util.{ Failure, Success }

case class Category(
  id: Int,
  name: String
)
case class Pet(
  id: Int,
  category: Category,
  name: String,
  photoUrls: Seq[String],
  tags: Seq[String],
  status: String
)

object Main extends JSApp {
  def main(): Unit = {
    Ajax.get("http://localhost:8080/v2/pet/10").onComplete {
      case Success(r) => {
        println(r.responseText)
        val parse = read[Pet](r.responseText)
        println(parse.id)
      }
      case Failure(t) => println(t.getMessage)
    }
  }
}

js生成

sbt
fastOptJS

HTML

scala.jsで生成したjsを読み込むだけ

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>scala.js api test</title>
    <meta charset="utf-8">
    <meta name="description" content="">
    <meta name="author" content="">
    <meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
    <script src="../target/scala-2.12/scalajspractice-fastopt.js"></script>
</body>
</html>

動作確認

Chrome起動

普通に起動するとクロスオリジンの制約で以下のようにエラーになるので、

XMLHttpRequest cannot load http://localhost:8080/v2/pet/10. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.

セキュリティ設定無効で起動

chrome.exe --disable-web-security --user-data-dir

動いた f:id:hkou:20170528113304p:plain

三重県へ温泉掘りに行ってきた

引越しがやっと落ち着いたので前から行こう行こうと思って行けなかった三重の温泉へ行ってきました。

出発

東名阪を進んでいく。 f:id:hkou:20170520094852j:plain

途中事故渋滞があった。 f:id:hkou:20170520095548j:plain

車が停められて入れそうな海岸があったので休憩がてら見に行った。この日は雲一つない快晴だった。 f:id:hkou:20170520134640j:plain

昼ごはん

昼ごはんは高速降りて尾鷲市の「お魚市場 おとと」というところで食べた。
地魚丼に生しらすをつけました。 f:id:hkou:20170520123821j:plain

湯ノ口温泉

最初の目的地、湯ノ口温泉へ到着。 f:id:hkou:20170520144014j:plain

結構長湯したので冷たいものが食べたくなり、風呂上がりにアイス買って食べた f:id:hkou:20170520154439j:plain

川湯温泉 亀屋旅館

一泊目の宿は「亀屋旅館」というところに泊まりました。旅行行くときはテント泊かビジホ泊ぐらいしかしてないからこういう旅館は新鮮。

f:id:hkou:20170520165453j:plain

川沿いの宿なので、部屋から川が一望できる f:id:hkou:20170520165753j:plain

f:id:hkou:20170521083954j:plain

川湯温泉 露天風呂

ここの川は地下から60度の源泉が湧き出しているそうで、川のどこを掘っても温泉が出てくるそうだ。一応以下写真のようなでかい温泉もあるけど混浴水着着用必須な感じなので宿に水着を貸してもらい、また温泉も掘ってみたかったのでスコップも借りて行ってみた。

f:id:hkou:20170521084053j:plain

円形になっているところが温泉部分、入ってみるとめちゃくちゃ熱い。となりが川なんだけど川の水はすごく冷たい両極端だ。川の水が温泉へ入ってくる部分がちょうど良い感じの温度になっていたのでそこに入った。 f:id:hkou:20170520175745j:plain

ある程度身体が温まったので今度は借りてきたスコップで河原に穴掘ってみた。掘ってみると川底がかすかに温かく感じる。川の水が入らないようにせき止めてしばらくしたらちょっと温めだけど温泉っぽくなった。 f:id:hkou:20170520175724j:plain

川に入ったり、温泉掘ったりしてどろだらけになったので内湯に入り直すことにした。 f:id:hkou:20170520181938j:plain

翌日

昨日掘った温泉へ行ってみると、濁っていたお湯が澄んでいてしかも結構温かく(ちょっと熱い)ぐらいになってて本当に温泉っぽい感じになっていた。 f:id:hkou:20170521084209j:plain

湯の峰温泉

川湯温泉のすぐ近くに温泉郷があるとのことで行ってみることに。 f:id:hkou:20170521094854j:plain

湯の峰温泉 つぼ湯

日本最古の湯として有名な「つぼ湯」、他のブログとか見ると1時間待ちとかしてやっと入れたとか書いてあったので、あんまり期待せずにちょっと見てみるかぐらいで行ったらちょうど人が捌けた状態らしく待ち時間無しで即効入れた。 f:id:hkou:20170521095743j:plain

このときは知らなかったけど、あとで調べてみたら世界遺産だったらしい。大きさは大人2人も入れば窮屈になるぐらい。ちょっと熱めだったけどいい湯でした。 f:id:hkou:20170521095819j:plain

Fitbit Alta hrを購入した

パッケージ

f:id:hkou:20170514101808j:plain

裏面

f:id:hkou:20170514101821j:plain

開封

f:id:hkou:20170514101940j:plain

本体

f:id:hkou:20170514102117j:plain

本体の裏

心拍数計が見える。 f:id:hkou:20170514102146j:plain

充電器

充電は洗濯ばさみのようなものに本体を挟んでおこなう。 f:id:hkou:20170514102258j:plain

使い心地とか

  • 軽い。腕に付けてても全然気にならない。寝てるとき付けてても大丈夫だった。
  • タッチパネルは評判どおり感度が悪い気がする。
  • 睡眠測定はなかなか面白い。結果をどう見ればいいかまだ分かってないけど入眠時間と起きた時間を正確に計測できているのはすごい

f:id:hkou:20170516213822p:plain

ガステーブルを買った

旧宅にはショボいIHが備え付けられていたが、新宅には備え付けは無かったので新たにガステーブルを購入した。
ビックカメラで購入。ちょうどポイントが沢山溜まっていたので全額ポイントで購入した。

開封 f:id:hkou:20170506112858j:plain

箱から取り出した

f:id:hkou:20170506113107j:plain

付属していた電池を挿入

f:id:hkou:20170506113323j:plain

このガステーブルにはガスホースが付属していないとのことなので、別途ガスホースとソケット的なものも購入した。

f:id:hkou:20170506113456j:plain

ホースにソケットをねじ込む(すごく固かった…) f:id:hkou:20170506113916j:plain

もう一方のホースをガステーブル本体に付ける。

f:id:hkou:20170506114057j:plain

配置して着火確認。ちゃんと火が着いた。 f:id:hkou:20170506114331j:plain

ごみの自己搬入をやってきた

引越しした際に色々大きなゴミが出たので、まとめて捨てるためにゴミの自己搬入をやってみることにした。

自己搬入のやり方を確認する

名古屋市のHPから自己搬入のやり方を確認する。

名古屋市:ご自分で処理施設に搬入する場合(自己搬入)(暮らしの情報)

まずは各区の環境事業所に電話してどのようなモノが捨てられるか確認した。(なんでも捨てられるわけではないみたい)

重い金属系のモノ(ダンベル、バーベルプレート)は捨てられないと言われ、代わりに金属の引取をしている会社を紹介された。

車を調達する

ゴミを処分場まで運ぶのに車が必要なので、レンタカーでハイエースを借りた。
今まで運転してきたのがコンパクトカーだったり軽自動車だったりしたので車体の大きさに戸惑った。

f:id:hkou:20170504092325j:plain

ブツを積み込む

自宅にあった不用品を積み込んだ。汗だくになった。

f:id:hkou:20170504092320j:plain

区の環境事業所へ向かう

処理場へ向かう前にまずは捨てるものの目視確認をしてもらい許可証を発行してもらうために環境事業所へ向かった。

f:id:hkou:20170504092458j:plain

まずは「ごみ等搬入申請書」に必要事項を記入する。
記入し終わったら職員の方に積荷を確認してもらい搬入許可証をもらう。

f:id:hkou:20170504091749j:plain

搬入許可証と大江破砕工場への地図をもらった。

f:id:hkou:20170504093609j:plain

大江破砕工場

www.city.nagoya.jp

大江破砕工場へ向かう

環境事業所では手続きだけで実際にゴミを捨てる場所は結構離れた場所にある(環境事業所から車で40分ぐらいかかった)

ゴミ捨てる前の計量

ゴミを詰め込んだ車ごと全体の車重を測る。先程環境事業所でもらった搬入許可証を係の人に渡して車重を記録してもらう。

f:id:hkou:20170504102459j:plain

ゴミを捨てる

写真は無い。工場内の経路を進んでいき大きな建屋の中に入った。中には大きなベルトコンベアが何台も動いており、そこにゴミを放り投げて廃棄は完了した。

ゴミを捨てた後の計量

また車ごと車重を測る。先程の捨てる前の車重と捨てた後の車重を比較してどれぐらい料金が掛かるかを計算する。ちなみにわたしの場合は80kg捨てて1600円かかった(10kg=200円らしい)

f:id:hkou:20170504103504j:plain

重量金属系のゴミを捨てに行く

大江破砕工場でも重量系の金属ゴミは捨てられないので、代わりに紹介された朝日金属さんへ向かった。こちらは特に費用請求もされず無償で引き取ってもらえました。

f:id:hkou:20170504124819j:plain

f:id:hkou:20170504123954j:plain

まとめ

おそらくゴミの自己搬入をやろうとする人は出来るだけゴミを捨てる費用を減らしたいのだと思うけど、今回かかった費用レンタカー代1万ちょっと+廃棄費用(1600円)+ガソリン代(600円ぐらい)で、それなりにかかりなおかつ手間もかかったのであまり割安感は感じなかった。あまりオススメはしない。 ゴミを運搬できる車を既に持っていて時間があって人手が足りている人なら多少安上がりになるだろうとは思うが、これに該当しない人は素直に廃棄物処理業者を呼んで処理してもらったほうが良いと思う。

追記

この記事をTwitterに流したら、他の市はもっと手軽に捨てられる情報が流れてきた。お手軽で良さそう。

d.hatena.ne.jp

カーシェアを使ってみた

カリテコ申し込みした

カリテコというサービスを契約した。なぜ数あるカーシェアサービスのうちでカリテコなのかというと、自宅近くに複数の駐車場があったからだ。それ以上の理由は特に無い。

ICカードが届いた

申込みをしてしばらく経ったらICカードが送られてきた。 f:id:hkou:20170402203318j:plain

カーシェアやってみる

予約から乗車までの大まかな流れ

  1. カリテコのサイトからログインして、借りる時間を設定する。
  2. ステーション(車がおいてある駐車場)の一覧が表示されるので、開いているところを選ぶ。
  3. 予約が完了すると予約確認メールが通知されてくる。
  4. 駐車場まで行って、車後部窓ガラスにICカードをかざしてドアロック解除する。
  5. グローブボックス内に車の鍵が入っているので抜き取る。
  6. 運転する

感想

  • まだ2台しか利用してないけど、近所の車の車内は非常に綺麗だった。変な匂いもしないし(禁煙)ゴミが落ちていることもない。
  • 雑な運転をしていると音声で警告をしてくる。わりと鬱陶しいので慎重に運転するようになった。ただ全部の車が警告してくるわけでもないらしく特に何も言わない車もあった。
  • レンタカーみたいに給油して返さなければならないわけではないので非常に楽。
  • 予約時間を見極めるのは結構面倒。一度多めに予約時間をとってしまったために1時間ぐらい無駄にしてしまったことがあった。タイムズカーシェアは予約時間よりも早く返却するとその分料金が減るらしい。
  • 名鉄協商パーキングが無料で使えるのは地味に便利。たまに車で行く場所の近くにパーキングがあったので良い。