ScalaScriptで実装する AlfredからSlackに簡単投稿

AlfredからSlackに分報を投稿するスクリプトを今回はScalaScriptで書いてみる
2021.09.06

はじめに

こちらのブログ(Scala で簡単スクリプト Ammonite を試す) でScalaで簡単なスクリプトが書けるAmmoniteに入門しました。Ammonite にはScalaで簡単にスクリプトが書ける ScalaScript という機能あるため、何か作ってみたくなりますよね。

以前 Alfredから簡単にSlack分報をPostする 機能をGoで実装しましたが、こちらをScalaScriptで再実装してみます。

完成デモ

Alfredを起動して t [メッセージ] で分報チャンネルに投稿します。

demo-post-to-slack

実装

準備

  • Ammonite
    • Ammoniteについて紹介したブログはこちら
  • Alfred プロ
    • Alfredのworkflow機能を使うにはproバージョン(有料)が必要です
  • Slackのトークン
    • Bolt入門ガイドがとても参考になります
    • トークンとアプリのインストール までで大丈夫です
    • 権限は char:write に設定します

ScalaScript

Slackに投稿するスクリプトをScalaScriptで作ります。

[path to project]/script.sc というファイルを作り、実行権限を付与しておきます。

パラメータは以下の3つ

  • Slackのトークン
  • 投稿チャンネル名
  • 投稿内容
#!/usr/bin/env amm

import ammonite.ops._

@main
def main(token:String, channel: String, message: String) {

  val POST_URL = "https://slack.com/api/chat.postMessage"
  val res = requests.post(
    POST_URL,
    data = Map(
      "token" -> token,
      "channel" -> channel,
      "text" -> message
    )
  )
}

1行目に #!/usr/bin/env amm と書くことで、スクリプトファイルを直接実行出来るようになります。 Ammoniteでは Requests-Scala がバンドルされており、簡単なリクエストであれば他のライブラリをインポートする必要はありません。

実行します。

$ cd [path to project]
$ ./script.sc [トークン] [チャンネル名] [投稿内容]

投稿するだけならこれで完成です。簡単ですね。

もう少し手を加えましょう。投稿に失敗した場合に通知したいと思います。

Ammoniteでは uPickle がバンドルされているため、uJsonを使えばJSONオブジェクトを簡単に扱えます。

Slack-Apiの仕様によると、エラー時は "ok": false となるので、ハンドリングして出力します。

#!/usr/bin/env amm

import ammonite.ops._

@main
def main(token:String, channel: String, message: String) {

  val POST_URL = "https://slack.com/api/chat.postMessage"
  val res = requests.post(
    POST_URL,
    data = Map(
      "token" -> token,
      "channel" -> channel,
      "text" -> message
    )
  )

  val parsed  = ujson.read(res.text())
  val status = parsed("ok")
  if(!status.bool) {
    println(s"${parsed("error").str}")
  }

}

エラー時のみエラー内容を出力するようにしました。出力内容は通知されるように後ほどAlfredで設定します。

Alfred

ファークフローを + ボタンより追加します。今回は Templates > Essentials > Keyword to Script to Notifivation を選択して進めます。

alfred-template

キーワードは適当に決めます。今回は t にしました。

alfred-setting-keyword

次にスクリプトを以下のように修正し、上で作成したScalaScriptを呼び出します。

PATH=$PATH:/usr/local/bin

token=[Slackのトークン]
channel=[チャンネル]
text="{query}"

[path to project]/script.sc $token $channel "$text"

Ammoniteのコマンドである amm がインストールされているPATH( /usr/local/bin )を追加して、2つの固定パラメータをセット。 投稿内容は {query} としておくことで、Alfredから入力された値が設定できます。

最後に通知欄を変更します。 エラー時のみ通知されるように

[ ] Only show if the input has content

にチェックを入れます。

alfred-notification

以上で完了です。デモのように t [投稿内容] で投稿できるようになりました。

まとめ

簡単なスクリプトであればサクッと書けますね。

プロダクトをScalaで開発している場合には、開発や運用で使う便利スクリプトもScalaで書くことで開発環境構築のコストも下げれそうです。今はRubyで書くことが多いですが、今後はScalaScriptも検討していきたいと思います。

参考