Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
101
Help us understand the problem. What is going on with this article?
@hironobu-igawa

【初心者向けTips】単純作業はもう嫌だ!GASツール作りの4つの技

この記事はモチベーションクラウドシリーズアドベントカレンダー2020の9日目の記事です。

最近GASでツールを作成したので、その経験を基に、GASツールを作成するための4つの技を紹介します。
この4つの技を覚えれば、GASツールで煩わしい作業から解放されます!

4つの技

GASツールを作成するために覚える4つの技は「関数」「イベントトリガー」「スプレッドシート連携」「外部API連携」です。
この4つを覚えればGASツールを作成できます。

関数:プログラムを定義する技
イベントトリガー:関数を起動する技
スプレッドシート連携:スプレッドシートを読み込んだり書き込んだりする技
外部API連携:Slackなどの外部APIと連携する技

関数:プログラムを定義する技

プログラムを定義するために関数を作成します。GASは定義した関数を実行することができます。

スプレッドシートのメニューバーからツール>スクリプトエディタの順にクリックすると、別タブにスクリプトエディタが表示されます。
スクリーンショット 2020-12-08 17.50.45.png
スクリーンショット 2020-12-08 17.52.50.png

スクリプトエディタからgsファイルを編集して、以下のように関数を定義します。

function hello() {
  // 実行するプログラム
}

例ではhello関数を定義しました。helloは定義したい関数の名前にあわせて入力してください。

イベントトリガー:関数を起動する技

作成した関数も起動しなければ動きません。作成したプログラムを起動するための3つのイベントトリガーを紹介します。

ボタン

関数を起動するためのボタンを作成して、ボタンがクリックされたら関数が起動するようにできます。

ボタンの作成方法
スプレッドシートのメニューバーから挿入>図形描画をクリックすると、図形描画モーダルが表示されます。
図形描画モーダルでボタンを作成することができます。
スクリーンショット 2020-12-08 18.04.04.png
スクリーンショット 2020-12-08 18.04.37.png

図形描画モーダルのメニューバーから図形>図形>ボタンのような図形を選択して図形描画モーダルにボタンを追加します。

スクリーンショット 2020-12-08 18.05.56.png
スクリーンショット 2020-12-08 19.03.42.png

図形描画モーダルにボタンを追加したら、ボタンに文言を入力しましょう。
保存して終了ボタンをクリックすると、シートにボタンを作成できます。
スクリーンショット 2020-12-08 19.04.42.png

作成したボタンを右クリックすると、ボタンの右上にが表示されます。
︙>スクリプトを割り当てをクリックすると、スクリプトを割り当てモーダルが表示されます。
スクリーンショット 2020-12-08 19.05.11.png

スクリプトを割り当てモーダルで関数を設定できます。
スクリーンショット 2020-12-08 19.05.46.png

hello関数を割り当てる場合は、helloと入力してOKボタンをクリックすれば、hello関数を割り当てることができます。

タイマー

タイマーを設定して、関数を特定の時間に起動するようにできます。

タイマーの設定方法
スプレッドシートのメニューバーからツール>スクリプトエディタの順にクリックすると、別タブにスクリプトエディタが表示されます。
スクリプトエディタのメニューバーから現在のプロジェクトトリガーをクリックすると、別タブにトリガー画面が表示されます。
スクリーンショット 2020-12-08 19.10.08.png
スクリーンショット 2020-12-08 19.11.06.png

トリガーを追加ボタンをクリックすると、GAS Botsのトリガーを追加モーダルが表示されます。
スクリーンショット 2020-12-08 19.12.22.png

設定項目 設定内容
実行する関数を選択 タイマーで起動したい関数を選択します。
実行するデプロイを選択 Headを選択します。
イベントのソースを選択 タイマーを設定したいので時間主導型を選択します。

イベントのソースを選択で時間主導型を選択すると、時間ベースのトリガーのタイプを選択が設定できるようになります。

  • 特定の日時・・・特定の日時に1回関数を起動します。
  • 分ベースのタイマー・・・指定の分おき毎に関数を起動します。1分おきから30分おきの範囲で選択できます。
  • 時間ベースのタイマー・・・指定の時間おき毎に関数を起動します。1時間おきから12時間おきの範囲で選択できます。
  • 日付ベースのタイマー・・・特定の時刻に関数を起動します。午前0時〜1時から午後11時〜午前0時の範囲で選択できます。
  • 週ベースのタイマー・・・特定の曜日の特定の時刻に関数を起動します。週は毎週月曜日から毎週日曜日の範囲で選択できます。時刻は午前0時〜1時から午後11時〜午前0時の範囲で選択できます。
  • 月ベースのタイマー・・・特定の日の特定の時刻に関数を起動します。日は1日から31日の範囲で選択できます。時刻は午前0時〜1時から午後11時〜午前0時の範囲で選択できます。

保存ボタンをクリックすると、タイマーの設定が完了します。
スクリーンショット 2020-12-08 19.13.30.png

Webhook

WebhookとはSlackなどの外部サービスのイベントを受信するための仕組みです。
WebhookでイベントをHTTPリクエストとして受信して、関数を起動するようにできます。

Webhookの実装方法
WebhookはdoGet関数/doPost関数で実装します。
doGet関数は連携する外部サービスがGETメソッドでリクエストを送信する場合に利用します。
doPost関数は連携する外部サービスがPOSTメソッドでリクエストを送信する場合に利用します。
連携する外部サービスがどのようなリクエストを送信するかによってdoGet関数/doPost関数のどちらを利用するかは変わります。

doGetの実装例

function doGet(event) {
  const target = event.parameter.target;
  hello(target)
}

例ではリクエストのtargetパラメータを取得して、hello関数を実行します。
event.parameterプロパティからリクエストのパラメータを取得できます。

doPostの実装例

function doPost(event) {
  const parameter = JSON.parse(event.postData.contents);
  const target = parameter.target;
  hello(target)
}

例ではリクエストのtargetプロパティを取得して、hello関数を実行します。
event.postData.contentsからリクエストのbodyを取得できるので、JSON.parseでパースしてオブジェクトに変換して利用します。

複数の外部サービスからリクエストを受け付ける場合
doGet関数/doPost関数は1つしか実装できないため、doGet関数/doPost関数内でif文などを利用して外部サービス毎に処理を切り替える必要があります。

Webhook URLの生成方法
Webhookの関数を作成した後、Webhookを起動するためのURLを生成する必要があります。
スプレッドシートのメニューバーからツール>スクリプトエディタの順にクリックすると、別タブにスクリプトエディタが表示されます。
スクリプトエディタのメニューバーから公開>ウェブ アプリケーションとして導入…をクリックすると、「Deploy as web app」モーダルが表示されます。
スクリーンショット 2020-12-08 19.15.01.png
スクリーンショット 2020-12-08 19.18.22.png

設定項目 設定内容
Project version Newを選択します。
Execute the app as 自分のメールアドレスを選択します。
Who has access to the app: Anyone, even anonymousを選択します。

Deployボタンをクリックします。

Current web app URLが表示されます。このURLが外部サービスからリクエストを送信するとWebhookが実行できるWebhook用のURLです。
スクリーンショット 2020-12-08 19.19.55.png

「非公開」にはできませんので、第三者に漏洩しないように取り扱いには十分にご注意ください。

Webhook用のURLを生成した後に修正した場合
修正を反映するためにWebhook用のURLを再生成する必要があります。

スプレッドシート連携:スプレッドシートを読み込んだり書き込んだりする技

スプレッドシートと連携して、関数の実行結果をスプレッドシートに書き込んだり、関数を実行する用の設定をスプレッドシートから読み込んだりすることができます。

対象のセルを取得
スプレッドシートに書き込みをする場合でも読み込みをする場合でも、操作対象のセル範囲を取得する必要があります。
操作対象のセル範囲を取得するには、以下のメソッドを利用します。

  • SpreadsheetApp.getActiveSpreadsheet()・・・対象のスプレッドシートを取得します。
  • Spreadsheet#getSheetByName(name)・・・指定のシート名に該当するシートを取得します。
  • Sheet#getRange(row, column)・・・指定の引数に該当するセル範囲を取得します。
  • Sheet#getRange(row, column, numRows)・・・指定の引数に該当するセル範囲を取得します。row, columnで範囲の開始位置を指定して、numRowsで範囲の終了位置を開始位置から相対的に指定します。
  • Sheet#getRange(row, column, numRows, numColumns)・・・指定の引数に該当するセル範囲を取得します。row, columnで範囲の開始位置を指定して、numRows, numColumnsで範囲の終了位置を開始位置から相対的に指定します。
  • Sheet#getRange(a1Notation)・・・指定の引数に該当するセル範囲を取得します。文字列でgetRange("A1")getRange("A1:B2")getRange("A2:A")などと指定します。

Sheet#getRange(*)の指定方法が分かりづらい場合、こちらが分かりやすいかもしれません。

書き込み
対象のセル範囲に値を書き込むには、Range#setValues(values)メソッドを利用します。valuesは値の2次元配列です。

以下の例シートのように値を設定する場合は、

A B C
1 A1 B1 C1
2 A2 B2 C2

以下のように実装します。

const spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
const sheet = spreadsheet.getSheetByName("");
const range = sheet.getRange("A1:C2");

range.setValues([
  ["A1", "B1", "C1"],
  ["A2", "B2", "C2"]
]);

読み込み
対象のセル範囲から値を読み込むには、Range#getValues()メソッドを利用します。戻り値は値の2次元配列です。

以下の例シートから値を設定する場合は、

A B C
1 A1 B1 C1
2 A2 B2 C2

以下のように実装します。

const spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
const sheet = spreadsheet.getSheetByName("");
const range = sheet.getRange("A1:C2");

const values = range.getValues();

console.log(values); // output: [["A1", "B1", "C1"], ["A2", "B2", "C2"]]

外部API連携:Slackなどの外部APIと連携する技

関数から外部APIにHTTPリクエストを送信することができます。
外部API連携することでGASからSlackにメッセージを送信するなどができます。

URL Fetch App
GASから外部APIにHTTPリクエストを送信するには、UrlFetchApp.fetch(url[, params])メソッドを利用します。戻り値はHTTPResponseです。

引数は主に以下の値を指定します。

引数 説明
url String HTTPリクエストを送信する宛先のURL
params.contentType String リクエストのContent-Typeを指定します。JSONを送信する場合は"application/json"を指定します。
params.headers Object リクエストヘッダをkey/valueのオブジェクトで指定します。
params.method String HTTPメソッドを指定します。デフォルトは"get"です。
params.payload String リクエストボディを指定します。GETメソッドの場合は指定できません。オブジェクトを指定するとapplication/x-www-form-urlencodedmultipart/form-dataかとして扱われます。

HTTPResponseは主に以下のメソッドを利用します。

メソッド 戻り値の型 説明
getContentText() String レスポンスボディを取得します。
getHeaders() Object レスポンスヘッダを取得します。
getResponseCode() Integer 200などのHTTPステータスコードを取得します。

Slackのsampleチャンネルに"hello"というメッセージを送信する場合は、以下のように実装します。

const data = {
  channel: "sample",
  text: "hello"
};

response = UrlFetchApp.fetch(
  "https://slack.com/api/chat.postMessage",
  {
    contentType: "application/json"
    headers: {
      "Authorization": "Bearer xoxp-xxxxxxxxx-xxxx"
    },
    method: "post",
    payload: JSON.stringify(data)
  });

console.log(response.getResponseCode()); // output: 200
console.log(response.getContentText()); // output: '{ "OK": true, ... }'

まとめ

GASでツールを作成するための4つの技を紹介しました。
ほとんどのツールは4つの技の組み合わせで作成することができます。
日々の業務やプライベートで自動化したい作業があれば、ぜひ自動化して楽になってもらえれば嬉しいです!

私は4つの技を駆使して、単純作業だった勤怠連絡をツール化して、楽をしてます!

皆様もGASでツールを作成してエンジョイライフを過ごしましょう!

【補足】なぜ、GAS?

GUI/CUIを作るコストが少ない
GUIはスプレッドシートの機能で簡単に作成することができます。

実行環境を準備する必要がない
GASはGoogleのスプレッドシート上で動作するため、実行環境を準備する必要がありません。

簡単に共有できる
GASはGoogleのスプレッドシート上で動作するため、他のユーザーにも簡単に共有できます。

【おまけ】GASで何を作った?

私は4つの技を駆使して、毎日Slackに勤怠連絡していた作業をツール化しました。

勤怠連絡
ワンクリックで勤怠連絡を行いたかったので、ボタンをクリックしたらSlackに勤怠連絡できるようにしました。
イベントトリガーのボタンを作成して、ボタンクリックに割り当てた関数から外部API連携を実行して、Slackに勤怠連絡メッセージを送信できるようにしました。
ボタンは「勤務開始ボタン/勤務終了ボタン/休憩開始ボタン/休憩終了ボタン」を実装し、ボタン毎に勤怠連絡メッセージが変わります。
ツールを作る前はSlackでメッセージと勤怠日時を手動入力してました。

スクリーンショット 2020-12-08 19.21.35.png
スクリーンショット 2020-12-08 19.24.40.png

ユーザ設定
ツールは他の開発メンバーにも共有したかったので、ユーザ設定シートを作って、勤怠連絡メッセージのユーザ名とアイコンを開発メンバー毎に設定できるようにしました。
スプレッドシート連携でユーザ設定シートと連携して、ユーザ設定シートからユーザ名とアイコンを読み込んで、勤怠連絡メッセージのパラメータに設定するようにしました。
スクリーンショット 2020-12-08 19.22.24.png

タイムカード
勤怠連絡した日時を簡単に視認できるようにしたかったので、タイムカードシートを作成して、タイムカードに勤怠日時を記録するようにしました。
勤怠連絡の操作時に、スプレッドシート連携でタイムカードシートと連携して、タイムカードシートに勤怠日時を書き込みました。
タイムカードシートに日々の稼働状況が記録されているため、「日付/出勤時間/退勤時間/非稼働時間」を一覧で見ることができます。
ツールを作る前はSlackに連絡した内容をスクロールで遡って確認してました。月次の稼働報告のために1ヶ月分も遡っていたので大変でした。
スクリーンショット 2020-12-08 19.21.51.png

101
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
hironobu-igawa
最近はVue.jsでフロントエンドの開発をしています。 2020年 モチベーションクラウドの開発に参加しました。 2019年 コミュニケーションクラウドの開発業務に参加しました。

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
101
Help us understand the problem. What is going on with this article?