この記事はITC Advent Calendar(2) 4日目の記事です
その一
https://adventar.org/calendars/2563
その二
https://adventar.org/calendars/2640
初めまして、がっちゃんです。
本年度のITCの部長やってます。
今回はとあるイベント( https://cybozu.connpass.com/event/70773/ )でとあるLT( https://www.slideshare.net/AyaSuzuki9/gasbot-83171149 )を聞いてGAS面白そうと思って触ってみたので記事にしました。
まず導入
GASについて〜SlackからGoogle Spread Sheetにデータを登録するまでは
素晴らしいスライド( https://www.slideshare.net/AyaSuzuki9/gasbot-83171149 )の方で書いてくださってるので是非そちらをどうぞ。
これやってみるときにびっくりしたこと
え、めっちゃ認証厳重やん。
初回にミスったせいで一生ハマってた
一発目の選択で「自分だけ」を設定してしまって、別のURLが発行されてて、それに登録しようとしまくっててそんなURL無い!って言われ続けてハマってた。
何回か設定を変えて公開し直したりしたら /u/0/
がないURLが発行されるので、それを使えば治りました。(いまだに治った原因が定かじゃない…w)
これを一通り作ってみてから、Slackでドキュメントを管理するBOTアプリを作った
完成イメージ
できるBOTアプリをサーバーレス(流行ってるから言いたい)で作りました。
構成
Slack Incoming/Outgoing Webhook
- Slack入力を読み取ってもらう
- レスポンスを出力してもらう
GAS
- 受け口
- ルーティング
- フォーマット掛け
- もろもろの管理など
Google Spreadsheet
- データの保存
苦労したとことハマったとこ
Google Apps ScriptのGUIエディタだとファイル分割ができない(と言うよりもめんどくさい)
普段のJSの感覚で import
とか require
とか使えると思ったら使えないっぽかった
(と言うよりも、ググった時にびっくりするほどJSの書き方がヒットしてノイズだらけで読む気が失せた)
ので、1ファイルで書くことにしました。
その結果、300行ぐらいの1ファイルコードになりました()
次やる時か、気が向いたときにファイル分割とリファクタリングしよう…
Arrayを与えてもよしなに指定の行にデータをぶっ込んでくれなかった…
これは、Google Spreadsheet の特性上仕方ないことなんだとは思うんですが、
行を指定して、データを並べた Array
を与えたのですが、うまいことデータ挿入をやってくれなくって、結構はまりました。
以下の記事のおかげで解決しましたが、なかなかにややこしかった。
スタンドアロンで考えて設計しないとデバッグがめんどくさい。
SlackBotとしてGASアプリを作る時に気をつけておかないといけないのが、
この (https://www.slideshare.net/AyaSuzuki9/gasbot-83171149) スライドの37枚目でも書いているように、一度Webアプリケーションとして公開して、SlackBotで叩けるようにすると、更新のたびにGUIで更新ぽちぽちしないといけなくなります。
Webアプリをローカルで試さずにいちいちデプロイしてテストする感じですね。
自分は流石にめんどくさかったので、
// sample request
// var sample = 'docadmin add スプレッドシート soso xxxxxxxxxxx';
// var sample = 'docadmin list';
// var sample = 'docadmin find 自己紹介プレゼン';
// var sample = 'docadmin activate active piyo';
function router(rawRequest) {
var request = adjustValues(rawRequest /* sample */);
// ~~~
}
function adjustValues(request) {
var parameter = request.parameter.text.split(' ');
// var parameter = request.split(' ');
// ~~~
みたいな感じで、いくつかの入力パターンを用意して、開発中はそっちのパターンを利用して、
できる限り少ないコストで Slack 連携に切り替えれるようにしてました。
これがまた結構大事。
遅くなるし、メソッドを探すのが大変だったりするので無理にSpreadsheet上で操作しようとしない。
この記事を読んでハッと気づかされたのですが、作り始めはSpreadsheet内の行そのものを操作してデータ書き換えをしたり、走査をしたりしようとしてました。
でも、それだとSpreadsheetで提供されているメソッドを探すのに苦労したり、Spreadsheet APIを叩く分遅くなります。 (GASは5分を超える処理はタイムアウトにされるので、実行時間にも注意)
なので、GASではほぼJSと同じ構文で書けることが多いので、できるだけその書き方をすることをお勧めします。
SpreadsheetApp.openById(SPREAD_SHEET_ID).getSheets()[0]
ってしてあげた方がいい
度々出てきているのですが、このスライド ( https://www.slideshare.net/AyaSuzuki9/gasbot-83171149 ) でのスプレッドシートの取得のやり方をすると、
Spreadsheet
オブジェクト(ファイル丸ごとみたいなイメージ)を sheet
に代入することになり、
getRange(row, colmun)
などのメソッドを使うことができなくなります。
原因は getRange(row, column)
のメソッドが Sheet
オブジェクト(ファイルの中にあるシートみたいなイメージ)に属しているためで、
これを解決するには、 SpreadsheetApp.openById(SPREAD_SHEET_ID).getSheets()[0]
のような形で、
Spreadsheet
オブジェクトの中の 0番目の Sheet
オブジェクトを取得する必要があります。
自分はこれがいまいち理解できてなくって、 getRange(row, column)
がno_methods errorを吐かれることにハマってましたw
まとめ
いかがだったでしょうか。
スライドをみて、GASを触ってみたいなって思い、そのあと詰まったりハマったりしながらも大体10時間ぐらいでこれぐらいのサーバーレスBOTを作ることができました。
思った以上にお手軽にBOTを作れて楽しかったのでまた別の機会にちょっとしたところを便利にするBOT作ってみようと思います。
これを読んだみなさんもGASに興味を持って色々遊んでもらえれば、幸いです!
ありがとうございました!
参考リンク
- https://www.slideshare.net/AyaSuzuki9/gasbot-83171149
- https://developers.google.com/apps-script/reference/spreadsheet/
- https://qiita.com/ShishidoToru/items/0ab9de4ea281df9358f4
- https://qiita.com/ryan5500/items/e72eb205fbe006c2eb6f#%E3%82%B7%E3%83%BC%E3%83%88%E5%85%A8%E4%BD%93%E3%81%AE%E3%83%87%E3%83%BC%E3%82%BF%E6%8E%A2%E7%B4%A2%E5%87%A6%E7%90%86%E3%81%AFjs%E5%81%B4%E3%81%A7%E3%83%81%E3%82%A7%E3%83%83%E3%82%AF%E3%81%99%E3%82%8B%E3%81%BB%E3%81%86%E3%81%8C%E9%80%9F%E3%81%84