もふもふ技術部

IT技術系mofmofメディア

claspでgas(google app script)アプリをいい感じに改修した

mofmofでは毎日オンライン朝会をしていて、2チームに別れてzoomの部屋に入りそれぞれの部屋で1人ずつ最近の出来事をしゃべるってことを15分程やっています。 ちょっと雑談しましょう的なノリです。

以前からgas(google app script)で朝会を管理していたのですが、

  • コード管理とデプロイが面倒
  • 環境変数にすべき値(スプレッドシートIDとかslackのhookURLなど)をハードコーディングする必要がある
  • gs≒はjsなので型が無い

claspを使うとtypescriptで開発できたり、githubと連携してデプロイできそうだったり(※未検証)するので良さそうだなと思ってclaspで作り直しました。

やること

  • スプレッドシートからメンバーリストを取得
  • メンバーをシャッフルする
  • シャッフルしたメンバーを2チームに分ける
  • スプレッドシートからランダムでお題(話すことが思いつかない人用にお題を出す)を1つ取得
  • 特別コンテンツ(おしゃべりじゃないことをする日、オンラインゲーム・瞑想・ヨガとか)をやるかどうか抽選する
  • ↑情報をテキスト化する
  • テキストをslackに通知する

セットアップ

セットアップ等はこちらの記事を参考にしました。 https://dev.classmethod.jp/articles/ts2gas/

clasp自身がtypescriptを変換してくれるので特に何も考えることもなくtsがgsに変換された上でgasにデプロイされます。

ファイル分割

typescriptが使えるので、てっきりモジュール化(ESM)・ファイル分割もいけるんだろうと思っていたのですができませんでした。 デプロイしたら単純にimport文がコメントアウトされてるだけでした。

webpack

サードパーティプラグイン等を使えばモジュール化もできそうな感じではあったのですが、webpackでローカルビルドしてjsに変換した上でアップする方式にしました。

こちらの記事を参考にしました。 https://zenn.dev/tacck/articles/20211218_gas#webpack-%E8%A8%AD%E5%AE%9A

やってることは

$index.ts

import { main, timerMain } from "./modules/main";

declare const global: {
  [x: string]: unknown;
};

global.main = main; // 処理の本体。本来はトップレベルにする必要ない(timeMainの中で呼び出される)が、デバッグ用に直接叩くこともあるので追加
global.timerMain = timerMain; // gasのタイマーから呼び出す関数

ビルドしてclasp deployするとglobalに設定した関数がgas上で実行可能関数として選択できます。 sc-gas-global

参考記事のように、package.jsonで以下のようにしとくと便利でした

  "scripts": {
    "build": "webpack",
    "push": "npm run build && clasp push" 
  },

テスト

ここまででアプリ自体はできました。 ついでなのでテストもしておこうと思いました。 と言っても最低限のところだけ、作成したメッセージが期待された文言が入っているかをテストしてみました。

gas特有の関数

spread操作とか環境変数操作等、gas特有の関数に依存しているのでテストするにあたってはスタブを作成する必要があります。 自前で作ると面倒で何かいい感じのものは無いかと調べたらありました。 https://github.com/dan-kushnaryov/gas-mock-globals 一通りのスタブが揃ってるっぽいのでこれをテストコードでimportしてあげればOK

完成

こんな感じでslackに通知されます。 sc-slack-hook-img

  • Around: zoomみたいなオンライン会議用チャットツールです。ゲームなどもできます。リアクション機能多め。
  • アンゴラウール はオンライン会議室の名前です。羊からの連想です。
  • マスクしている箇所にメンバーの名前がリスト表示されます。

リポジトリはこちらです。 https://github.com/sugiii8/asakai-clasp

以上です。