gas
TypeScript
Slack

ランチチーム分割(当たり付き)を作った話

2018.08.01に使う

  • github.com/tsuyukimakoto/yoritomo

スクリーンショット 2018-07-29 19.29.14.png


モチベーション

  • ランチに行く人を募り、お店に入りやすい人数にチーム分けしたい
  • コミュニケーション促進のためという名目で会社から補助を得たい

要件

  • 会社の基本コミュニケーションツールがSlackなので利用はSlackで完結したい
  • httpsでアクセスできるサーバー
  • 誰がサインアップしているかを保持しておくデータストア
  • 指定した時刻にプログラムをキックできるスケジューラ

SlackのInteractive Message

  • 押せるボタンをメッセージに出せる
  • 3秒以内にレスポンスがないとエラーに!
    • GAS+SpreadSheetで試していた時に3秒以内に戻ってこないことが多かった

浮気をしようとする

  • GCEのずっと無料枠が拡大されたという記憶

Google Compute Engineのずっと無料枠


Cloud Functions

  • nodejsがv6.14.0でウッとなる

つまり

  • 何かの定期実行機能でSlackにMessage Butotnを送信
  • Slackからの応答をGoogle Cloud Functionsで受ける
  • Google Cloud Datastoreを参照してSlackに応答を返す

あれ?AWSでいいんじゃね?

  • API Gateway + Lambda
  • Dynamodb

API Gatewayだけ料金が微妙にかかりそう


Lambdaの定期実行

nodejsもv8.10に対応している。Python3.6で何も気にせずに書いてしまえという誘惑も


みやもとさん動いてんじゃん!

ということに気づいたというか、せっつかれたというか


GASに戻ります

2018.07のイマドキ

clasp + Typescript で書くのが良いっぽい。


clasp

Command Line Apps Script Projects

CLIからの認証、プロジェクトの作成、コードのプッシュやデプロイなんかができる。

以前は gapps ってツールを使ってたらしいのですが、Google製のclaspが出たのでディスコンらしい


gas-clasp-starter

package.jsonにgas-clasp-starterの名前とかバージョンが書いてあるので注意が必要


Typescript

  • @types/google-apps-script

補完効くので楽チン。
とはいえsublimetextだとビルドするまで気づかないエラーとかはある。


yoritomoの構成

.
├── appsscript.json
├── config.service.ts ← 設定を扱う。ProeprtyServiceをここに閉じ込めている
├── constants.ts
├── index.ts  ← エントリーポイント
├── models.ts  ← 型定義。ここじゃない気がしている
├── storage.service.ts  ← データを扱う。SpreadSheetはここに閉じ込めている
└── utils.ts ← バグりがちなロジックを入れて、主にこのファイルをテストしている

PropertyService

  • スクリプトのプロパティを読み書きする
    • 簡易key/valueとして使える

スクリーンショット 2018-07-30 1.06.12.png


スプレッドシートに持たせられない

  • みやもとさんは設定用のシートがあるけれど
    • みやもとさんはデータが増えると遅くなった
      • 1週間でスプレッドシートを入れ替えるようにしたので、設定は別で持たないといけない

DriveAppとSpreadSheetAPp

  • G Driveの特徴

    • ファイルは複数のパスに置ける
    • 同じファイル名のファイルが同じパスにあっても問題ない
  • SpreadSheetApp

    • 新しいファイルはrootにできる(マイドライブ)
    • 実行ユーザーのマイドライブにできるし、G Driveなどの権限も実行ユーザーでとっているので初期設定した人が辞めたらやり直しです
  • フォルダもファイルもidをスクリプトプロパティに保存しておくと場所を変えられても問題ない

  • フォルダをlsしてファイルを探すのも遅くなることが容易に想定できるのでid直打ちで開く


ファイルを作って移動して決めうちでrootフォルダから消す

let root_folder = DriveApp.getRootFolder()
let spreadsheet_file = DriveApp.getFileById(spreadsheet.getId())
folder.addFile(spreadsheet_file)
root_folder.removeFile(spreadsheet_file)

ログ出力

GASでログを出力って探すと Logger.log を使って ⌘+Enter でって書いてある。
これはScriptEditorから実行するときは手軽で便利。

タイマー実行とかWebアプリケーションとして実行された時にはLogger.logはたまらない。

  • console.infoとかを使う
    • GOOGLE STACKDRIVERに記録される
    • Google Cloud Platform と AWS で実行されるアプリケーションをモニタリング、ロギング、診断
    • StackDriverの管理画面で見ると良い
    • 通知メールは12時間以上遅れて来たりするので注意
    • ScriptEditorから開くときはpopupブロックを解除しておかないと動かないように感じてしまう

Webアプリケーションとして公開

  • doGet/doPostという関数を用意しておくとWebアプリケーションとして公開できる
    • コードに変更を加えた場合には新しいバージョンで公開しないと反映されない
    • clasp deployだと新しいバージョンはできるけど公開されない
    • https://github.com/google/clasp/issues/43
    • バージョンを変えてもURLは変わらない

SlackのInteractive Message

  • Slack appを作る必要がある
    • ボタンを出せる
    • ボタンのレスポンスを受けるURLを指定できる
  • Slack appはIncomming webhookも持てるのでIncomming webhookアプリでの管理ではなくてSlack appの管理で良い
  • 3秒ルールがある(応答が3秒以内に返らないとエラーが表示される)