GASでカユいところに手が届いたTips3選

毎年恒例の[ラクス Advent Calendar](https://qiita.com/advent-calendar/2021/rakus)、2021年の一日目です！！:santa_tone2:
クリスマスまでどうぞお付き合いください:gift:

今年は @amderbar さんにカレンダーをつくってもらい、その場のノリで一日目に登録してしまいました。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176262/d030f913-edc4-0634-3571-8d9a29660843.jpeg" width="450">
↑社内チャットで調子に乗った筆者。後悔先に立たず。


一日目からこけてしまうわけにはいかないので、なんとか記事を絞り出します。
...絞り出します!!


# GASとは

Google が提供する Apps Script（：GAS）とは、Google Workspace のサービスをコードから操作することができるプラットフォームです。基本的にJSの知識があれば記述ができ、学習コストも低い上に、デプロイ環境を自分で用意する必要がないため、ちょっとした自動化や拡張を行う際にとても便利です。

https://workspace.google.co.jp/intl/ja/products/apps-script/

また、以下のようにブラウザからコードを記述できることも大きな特徴です。Google のアカウントがあれば、ほぼ準備ナシで実装に取りかかれます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176262/3ff72070-cdd6-fdb3-203b-9fb419537d57.png" width="600">


## GASでできること

以下に挙げるのは一例です。Google Workspace のサービス操作はもちろん、APIのリクエスト、簡単な Web アプリの作成も行うことができます。

* Driveのファイル操作
* スプレッドシート操作
* カレンダーの操作
* 簡単なWebアプリの作成

# Tips3選

いろいろなことができる GAS ですが、いろいろなことができるゆえに、その機能をすべて理解している人は少ないと思います。
そのため、今回は私が GAS を使ったときに便利だった機能などを3つ紹介します。


## トリガーとトリガーのセット

作成したスクリプトは、なにかの動作や時間によって実行されるよう設定することができます。
設定できるトリガーのタイミングには、以下のようなものがあります。

* X時間ごとに実行
* 1日1回 X時に実行
* X曜日に実行
* 毎月X日に実行
* ファイルを開いたときに実行
* ファイル更新時に実行
* フォーム更新時に実行

トリガーを使うことで、たとえば、入力されている内容を定期的に集計してどこかへ送る処理や、スプレッドシートの変更を検知して入力値のバリデートを行うことが可能になります。

### トリガーの設定方法

GAS のエディタを開き、左にあるメニューから「トリガー」を選択します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176262/1f71d37a-f985-8768-f1be-05715bd47f40.png" width="300">


その後、左下にある「トリガーの追加」からトリガーを設定することができます。
複数設定でき、それぞれ実行する処理も別に設定できるため、目的によって複数のトリガーを設定するといいでしょう。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176262/e21b2102-421f-239e-cdef-f2a89fb582f5.png" width="400">




### スクリプトからのトリガー登録

また、このトリガーは GAS 自身からスクリプトで設定することもできます。

```js:GAS
  const spreadsheetId = SpreadsheetApp.getActiveSpreadsheet().getId()

  // 編集時に実行されるトリガーを作成
  ScriptApp
  .newTrigger("METHOD_NAME")  // 実行される関数名
  .forSpreadsheet(spreadsheetId)
  .onEdit()
  .create()

  // 1時間に1回実行されるトリガーを作成
  ScriptApp
  .newTrigger("METHOD_NAME")
  .timeBased()
  .everyHours(1)  // 時間指定
  .create()
```




## ロック

トリガーを使ってスクリプトを実行する場合、処理が同時に複数実行されてしまう場合があります。
たとえば、トリガーを「スプレッドシートを編集したとき」にしていた場合、複数のユーザが同じスプレッドシートを編集すると、同じスクリプトが複数同時に続行されてしまう可能性があります。GAS で他サービスを操作しようとすると、API のレスポンス待ちに時間がかかって処理時間が長くなるため、ときには無視できない問題になるでしょう。

このような場合、処理を「ロック」することができます。

```js
  // 二重起動防止
  // 1秒間スクリプトのロック取得を試みる
  // 取得できなかったら false を返す
  const lock = LockService.getScriptLock()
  if(!lock.tryLock(1000)) {
    return
  }
```

上記のロックは「スクリプトロック」と呼ばれるロックで、同時に同じスクリプトでロックを取得できなくなります。

また、GASには、スクリプトロック意外にも、スプレッドシートやドキュメントなど、GoogleWorkSpace のリソースをロックする「ドキュメントロック」、1ユーザが同じスクリプトを同時に実行しないようにできる「ユーザロック」があります。


## claps

前述した通り、GAS の特徴としてブラウザから編集ができることがありますが、ローカルにコードがないため、Git での管理や、他人への共有をすることができません。

そのため、Google から GAS をローカルで開発することができる clasp が提供されています。

https://github.com/google/clasp


claps を使うことで、ローカルで記述したスクリプトを GAS へ push して実行することができるため、スクリプトのGit管理が可能になります。
また、ローカルで開発ができるので、普段使っている好みのエディタでの開発を行うことができます。


### clapsの導入

npmでインストールできます。

```bash
$ npm install @google/clasp -g
```

### .clasp.json 作成

claspでは、.clasp.json に push 先のコンテナ情報などを登録します。

以下のようにスクリプトIDを記載することで、push 先を指定できます。

```json:.clasp.json
{"scriptId":"__APPS_SCRIPT_ID__"}
```

`__APPS_SCRIPT_ID__` に記載するプロジェクトの ID は、以下のように用意したプロジェクトの設定画面から取得できます。
（キャプチャはスプレッドシートでGASを実行するときのものです。）

![15164342126281.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176262/75675b52-256a-143e-c3b3-79238d2f0e80.jpeg)


### スクリプトを psuh

.clasp.json が設定できたら、以下のコマンドで用意したプロジェクトへスクリプトを push することができます。

```bash
$ clasp push
```

### .claspignore

スクリプトを push するときに、GASと関係ないファイルがアップロードされてしまうことを防ぐため、
clasp には、push したくないファイルを登録しておく機能があります。

以下のように、.claspignore に記載したファイルは、プロジェクトへの push を行ったときにアップロードされません。（.gitignore と同じノリです。）

```:.claspignore
.git/*
.gitignore
README.md
```



## おわりに

ここで触れたことは、ほんのさわりのみです。
いろいろ調べてみると、簡単なスクリプトの作成や自動化を簡単に行えるため、日々の業務やその他もろもろに活用できることに気づくはずです。

興味がある方は、ぜひ一度触ってみてください。

-----

さて、明日は @oohira さんです！
GitLab CI についての記事を書いてくださるそうなので、お楽しみに！！:santa_tone3: