先日、とらのあな主催のKotlin勉強会で、Kotlinを使ったWEBアプリケーション開発の始め方という題で発表してきました。
ちょっと時間が押していたので発表は巻きになってしまったのですが、Kotlinで開発を始める後押しができていたら幸いです。
といっても、Java資産周りの技術解説いりますよね、本当に始めるなら
Kotlinにおいてprotectedのアクセス修飾子は、Javaと異なり同一パッケージからのアクセスを許容しません。 そのため、テストコードなどでprotectedのメソッドを実行したい場合は、リフレクションを使う必要があります。
継承してテストするという方法もありそうですが、今までしなかった発想なのでどうなんですかね。
例えばTestDataRepositoryにcreateSampleDataというLongのパラメータを1つ取り、SampleDataクラスを返却するprotectedのメソッドあるとした場合、以下が対象のメソッドを実行するコードになっています。
var testSuite = TestDataRepository() val testMethod = testSuite::class.memberFunctions.find { it.name == "createSampleData" } val actual = testMethod?.let { it.isAccessible = true it.call(testSuite, 100L) }
testSuite::class
)から、.memberFunctions.find { it.name == "createSampleData" }
)しますtestMethod?.
)、val actual = testMethod?.let {
)it.isAccessible = true
)、it.call(testSuite, 100L)
)以上になります。
Javaの場合はprotectedメソッドであれば同一パッケージからすんなり呼べたので、テストが楽でよかったのですが、Kotlinの場合はちょっと工夫がいりそうです。 もうちょっと簡単な方法もありそうなのですが(PowerMockのWhiteboxクラス使うとか)、おいおい調べてみないといけないなという感じです。
BotkitにはSlackアプリがJSONでユーザ、チャンネル、チームの情報を保持できる簡易DBのような仕組みがあります。
今回はこれを拡張し、保持できる単位を増やしてみました。
Botkitで利用されている簡易DBは、simple_storage.jsとして実装されているので、そのコードを参考にすることで拡張ができました。
まずは必要となるjfsパッケージをインストールします。
npm i jfs
そしてsimple_storage.jsのstorageに、追加したいDBを足して返す関数を作ります。
ここでは、勤怠情報を保持するスペースとしてkintaiを作っています。ファイル名はstorage.jsの想定です。
'use strict'; import simple_storage from 'botkit/lib/storage/simple_storage.js'; import Store from 'jfs'; export function kintai_storage(config) { if (!config) { config = { path: './', }; } let storage = simple_storage(config); let kintai_db = new Store(config.path + '/kintai', {saveId: 'id'}); let objectsToList = (cb) => { return (err, data) => { if (err) { cb(err, data); } else { cb(err, Object.keys(data).map((key) => data[key])); } }; }; storage.kintai = { get: (kintai_id, cb) => { kintai_db.get(kintai_id, cb); }, save: (kintai_data, cb) => { kintai_db.save(kintai_data.id, kintai_data, cb); }, delete: (kintai_id, cb) => { kintai_db.delete(kintai_id, cb); }, all: (cb) => { kintai_db.all(objectsToList(cb)); } }; return storage; }
そして、この新しいstorageを利用するには、slackbotのパラメータに、storageキーの値を先ほど作成した関数としたオブジェクトを渡してください。
import Botkit from 'botkit'; import { kintai_storage } from './storage'; const controller = Botkit.slackbot({ storage: kintai_storage({path: './data/'}), }).configureSlackApp( ...以下省略
このプログラムを起動すると以下のように、保持できるスペースとして新たにkintaiが追加されていることを確認できます。
data ├── channels ├── kintai ├── teams └── users
本格的に管理するのであれば、Sqliteなどを利用した方がいいと思いますが、一つ増やしたいくらいであれば、このような方法もいいのではないでしょうか。
現在、Slackアプリを開発中なのですが、初めてのこともあり色々と学ぶことが多かったです。
Slackアプリを開発するにあたっては、公式フレームワークのBotkitを利用することにしました。
Botkitの導入はSlackアプリのプロジェクトで、npm i botkit
をするだけでいいのですが、
ES201Xでコーディングするため、Babelも導入しました。
npm i botkit npm i -D babel-cli babel-core babel-preset-env
SlackアプリはNode.jsで動くので、.babelrcは以下のようになります。
{ "presets": [ ["env", { "targets": { "node": "current" } }] ] }
開発用のコードはsrc/main
配下に、実行コードはdist/main
配下とすることにしたので、
トランスパイルの実行用にpackage.jsonのscriptsに以下の記述を加えました(app.jsが起点のファイルです)。
"build": "babel src -d dist", "start": "node dist/main/app.js", "clean": "rm -rf dist",
実行する際は以下のようにして使っています。
npm run clean; npm run build; npm start
あとはコーディングするだけなのですが、起動の段で幾つか注意するところがあります。
https://ホスト名:ポート/oauth
を渡せばOK)https://ホスト名:ポート/slack/recieve
になるどちらもBotkitで開発できるのですが、以下の点が異なります。
今回Slackアプリとして開発したのは、interactive_message_callbackを利用したかったためです。
アプリ作成は、slack apiのページで『Create New App』ボタンを押すことで開始できます。
ここでアプリの名前とインストールするSlackのチームを入力しましょう。
その後の各項目での作業は以下になります。
https://ホスト名:ポート番号/slack/receive
を設定するアプリ用のSlackコマンドを作る場合はここの設定を行います。
https://ホスト名:ポート番号/slack/receive
を設定する配布アプリを作成する場合は、ここでRedirect URLsにhttps://ホスト名:ポート番号/oauth
を設定する必要がありますが、
内部利用だけの場合は設定不要です。
利用するBotユーザの表示情報をここで設定します。
注意点として、Slack上に登録されるユーザはここで設定した名前ですが、スラッシュコマンドが応答するアプリの名称はBasic Informationで設定したものになります。
トランスパイルが終わっていればnpm start
で起動するので、SSL対応のサーバでアプリを起動してください。
起動後にブラウザからhttps://ホスト名:ポート番号/login
にアクセスし、認証を行うとRMTがスタートします。
最初は開発用サーバとしてHerokuを利用していたのですが、Herokuではできないこともあり、現在は利用していません(ngrokを使っています)。
ただ、利用する際にもいくつかハマリポイントが合ったので残しておきます。
process.env.PORT
を利用する
web: npm start
のように起動コマンドを記載するSlackのチュートリアルにもありますが、開発ではngrokでSlackからのリクエストを受けて、ローカルに転送することで、ローカル開発ができます。
Macの場合はHomebrewで導入するのが簡単だと思います。
brew cask install ngrok
起動は以下のようにアプリで利用するポート(ここでは3000)を指定して実行する感じです。
ngrok http 3000
ngrokは起動している間はドメインが変わらない&裏でアプリの再起動をしても問題なく転送してくれるので、開発中はngrokを起動しっぱなしにして利用することになると思います。
ただ、セキュリティリスクがあることをやっているので、会社などで立ち上げていると情シスに怒られる可能性があります。注意しましょう。
コーディングに関してはざっくり省きましたが、このようにすることでSlackアプリを自分で作ることができます。
本番利用にはAWSを使おうと思っているので、その手順はまたの機会に。
コーディングのエッセンスはまた別途書きたいと思っています。