更新 2020/11/01
Google Apps Script
どうも、こんにちは!JellyWareです。
Getting Started!! Riiiver tutorialの第10弾となります。
このシリーズは、Riiiverやプログラミングを学び、初心者の方でもEco-Drive Riiiverを活用したオリジナルアプリを理解して作れるようになることを目指します。
前回、前々回と学んだ「API通信」「JSON」を活用して天気情報をGoogle スプレッドシートで管理できるようにします。
そのために必要な「GAS」というのを今回は学びます。
後半ではglitchを使用します。glitchについては、第6弾をご参照ください。
目次
GAS
GAS とは何かということを説明し、簡単なサンプルコードを実行してもらいます。
GASとは?
GAS とは、Google Apps Script の略です。
Google が提供するプログラミングを行える環境で、JavaScripit をベースにした言語を使用します。(基本的に JavaScript と同じで、GAS 専用の関数を使うことができます。)
Googleが提供するスプレッドシートなどのサービスと紐づけて使用することができます。
スプレッドシートと連携
それでは実際にGAS を使ってみましょう。
事前準備として「Google スプレッドシート」を新規作成する必要があります。
作成するには「Google」アカウントが必要です。ここの一連の流れに関しては、知っていらっしゃる方がほとんどだと思われますので割愛させていただきます。
(調べるとすぐに作成方法を見つけることができると思います。)
作成できた方はツール > スクリプトエディタ
を選択していきます。
このような画面が立ち上がります。この画面にコードを書いていきます。その前に、少し設定を変更します。
実行 > Chrome V8 を搭載した新しい Apps Script ランタイムを有効にする
をクリックするだけです。Chrome V8 を搭載した新しい Apps Script ランタイムを無効にする
となっている方は、既に有効なので不要です。
それでは現在書かれているコードを全部消して、下記のコードを記入してください。
const doGet = (e) => {
// 現状Activeになっているsheetを取得
const sheet = SpreadsheetApp.getActiveSheet();
// 1を追記
sheet.appendRow([1]);
}
次に、「保存」して実行します。「保存」はフロッピーディスクのアイコンをクリックするだけです。
赤枠のフロッピーディスクをクリックします。
「プロジェクト名の編集」というウィンドウが表示されるので、適当に「test」などの名前をつけてOKをクリックしましょう。
保存ができたら、この「GAS」を外部からも使用できるように設定していきます。
メニューの公開
> ウェブアプリケーションとして導入…
を選択します。
選択するとこちらのようなウィンドウが表示されます。
New
と全員(匿名ユーザーを含む)
を選択し導入
ボタンを押します。これを選択すると、誰でもこのGASを実行できるようになります。後に支給されるURLの管理には注意しましょう。
「承認が必要です」というウィンドウが出たら、許可を確認
ボタンを押します。
ボタンを押すと上記のようなウィンドウが表示されるので、自分のGoogle アカウントを選択します。
ボタンを押すと「警告画面」に移りますが、今回は気にしなくて大丈夫です。左下にある小さな詳細
をクリックします。
ボタンを押すと、表示が広がります。左下の小さなtest(安全ではないページ)に移動
をクリックします。
ボタンを押して上記の表示が出たら、下へスクロールして右下の許可
ボタンをクリックします。
ボタンを押すと次のようなウィンドウが表示されます。
「URL」をコピーして、OKを押します。
(URLをコピーし忘れた方は、メニューの公開
> ウェブアプリケーションとして導入…
から確認してください。)
次に、新しいタブを開いてコピーしたURLにアクセスして下さい。
アクセスしたページはエラーになりますが、スプレッドシートに「1」が追記されていれば成功です。ちなみに、新しく開いたページを更新すると「1」がどんどん追記されます。
このように簡単に外部からスプレッドシートを操作することができます。
それでは、使用したコードの解説を行います。
const doGet = (e) => {
// 現状Activeになっているsheetを取得
const sheet = SpreadsheetApp.getActiveSheet();
// 1を追記
sheet.appendRow([1]);
}
doGet()
関数を作成しています。doGet()
関数は特別な関数で、公開したWebアプリケーションのURLにアクセスがあった、もしくは、「GET通信」が行われた時に実行される関数です。
次に、関数内の処理について順に解説します。
// 現状Activeになっているsheetを取得
const sheet = SpreadsheetApp.getActiveSheet();
Activeなsheetは、スプレッドシートを開くと最初に表示される、または現在開いているsheetのことを指します。
SpreadsheetApp.getActiveSheet()
を使用することで、Activeなsheetを取得できます。
特にシートを増やしたり名前を変更していなければ、シート1
がActiveなsheetになります。
// 1を追記
sheet.appendRow([1]);
次に、取得したActiveなsheetに値を追記します。
appendRow()
は、引数として受け取った配列をシートの最終行に追加する関数です。追加するシートは、appendRow()
の前に.
を使って連結します。
GAS(JavaScript)の配列は、第9弾で学んだJSONの配列と同じで、値を[ ]
で囲み,
で区切ります。
// 1,2を追記
sheet.appendRow([1,2]);
例えばこのようにすると、1の隣のセルに2と記入されます。
変更したGASを外部から実行できるようにするには、プロジェクトを更新する必要があります。
先程と同様にメニューの 公開
> ウェブアプリケーションとして導入...
をクリックしてください。ここで"プロジェクトバージョン"を New
にすることを忘れないようにして下さい。その他は前回の設定が保持されていると思います。
更新
ボタン、OK
ボタンを押します。ちなみに、スクリプトの内容を変えてもURLに変化はありませんのでURLを再びコピーする必要はありません。
URLクエリパラメータを取得
先ほどのコードを少し変更し、URLクエリパラメータを活用して好きな値をスプレッドシートに送信できるようにします。
コード.gs
内のコードを全て削除して、以下のコードと差し替えてください。
const doGet = (e) => {
// URLクエリパラメータからデータを取得
const queryParameter = e.parameter.test;
// 現状Activeになっているsheetを取得
const sheet = SpreadsheetApp.getActiveSheet();
// シートに取得したデータを追記
sheet.appendRow([queryParameter]);
}
コードを差し替えたら、プロジェクトのバージョンを New
にして更新します。
また、実行する前に下記のようにURLクエリパラメータを追加してください。query
のところは好きな値に変えて大丈夫です。
https://script.google.com/macros/s/xxxxxx/exec?test=query
上記URLにアクセスすると、今度は「1」ではなくURLクエリパラメータに追加した値が記入されます。(上記URLの場合、query
が記入されます。)
次にコードの解説をします。変更した箇所は2点です。
// URLクエリパラメータからデータを取得
const queryParameter = e.parameter.test;
2,3行目に追加しました。
e.parameter.URLクエリパラメータの変数名
とすることで、URLクエリパラメータの変数に対応する値を取得できます。
今回はtest
にしましたが、他の変数名でも問題ありません。
// シートに取得したデータを追記
sheet.appendRow([queryParameter]);
9行目のappendRow()
の引数を変更しました。
3行目で宣言した、URLクエリパラメータの値が代入されているqueryParameter
に変更しています。
Node.js で GAS
それではNode.js を使ってGASを実行してみましょう。と言っても、前回行ったAPI通信とほとんど同じです。
それでは、glitchでプロジェクトを作成して、axios
のモジュールを追加しましょう。前回作成したプロジェクトが残っている場合は、そちらを使用しても問題ありません。モジュールの追加方法については第8弾をご参照ください。また、プロジェクトは非公開にしましょう。
GASとAPI通信
まずはURLクエリパラメータを使ってスプレッドシートに値を送信します。使用するGASは「URLクエリパラメータを取得」のコードで大丈夫です。
まずは、以下の3つを確認しましょう。
- URL:GASから支給されるウェブアプリケーションのURL
- 送信データ:任意
- 通信方法:GET
URLは、そのままGASから支給されるURLを使用すれば大丈夫です。
通信方法は、doGet()
関数を用いるためGET
です。
送信データは、スプレッドシートに記入したい値となるため任意としています。
準備ができたら、以下の5行目のURLを差し替えて実行しましょう。
※GASのURLクエリパラメータをtest
から変更されている方は、11行目のtest
も変更する必要があります。
// axiosの読み込み
const axios = require("axios");
// URL
let url = "https://script.google.com/macros/s/xxxxxx/exec"; // みなさんのGASのURLと差し替える
// 送信データ
const query = "今日の天気は晴れ";
// 最終URL作成
url = `${url}?test=${query}`;
// 文字コードの変換
url = encodeURI(url)
// API通信
const doApi = async () => {
try {
await axios.get(url);
} catch (error) {
console.log("Error message: " + error.message);
}
};
// 実行
doApi();
実行すると、このように8行目に設定した値がGoogle スプレッドシートに追加されます。
それでは、コードを解説してきます。と言っても、前回行ったAPI通信のコードとほとんど同じため、変更した点のみ解説します。
// URL
let url = "https://script.google.com/macros/s/xxxxxx/exec";
// 送信データ
const query = "今日の天気は晴れ";
// 最終URL作成
url = `${url}?test=${query}`;
4~11行目を変更しました。
上から順に、「URL」「送信データ」「URLクエリパラメータ」をGAS用に設定しています。
// 文字コードの変換
url = encodeURI(url)
13,14行目を追加しました。
プログラミングで「URLクエリパラメータ」を活用する場合、日本語のままだと文字コード(コンピュータが文字を扱うためのルール)の関係でエラーが発生します。
そのためencodeURI()
関数を使って、文字コードの変換を行っています。
OpenWeatherと連携
次に前回活用したOpenWeatherとスプレッドシートを連携させます。
東京の気温と天気をスプレッドシートに送信します。
まずはGASのコードを修正します。
const doGet = (e) => {
// URLクエリパラメータからデータを取得
const temp = e.parameter.temp
const weather = e.parameter.weather
// 現状Activeになっているsheetを取得
const sheet = SpreadsheetApp.getActiveSheet();
// 日時を取得
const date = new Date();
// シートに取得したデータを追記
sheet.appendRow([date, temp, weather]);
}
先ほどのコードから、3点修正しました。
// URLクエリパラメータからデータを取得
const temp = e.parameter.temp
const weather = e.parameter.weather
2~4行目を変更しました。
まずは、URLクエリパラメータの変数名を変更し、「気温(temp)」と「天気(weather)」の2つを取得するようにしました。
// 日時を取得
const date = new Date();
9,10行目を追加しました。
次に日時を取得しています。
new Date()
を使用することで、実行したタイミングの日時を取得できます。
// シートに取得したデータを追記
sheet.appendRow([date, temp, weather]);
最後に、取得したデータをそれぞれシートに追記するように修正しました。
次にNode.jsのコードを変更します。
追加したら、以下のコードの28行目をGASのURLに差し替えて、.env
ファイルに前回と同じようにAPI Keyを追加します。
// axiosの読み込み
const axios = require("axios");
// URL
let url = "https://api.openweathermap.org/data/2.5/weather";
// 都市名
const cityName = "Tokyo";
// API Key
const apikey = process.env.API_KEY.replace(/\\n/g, '\n');// .envから取得
// 最終URL
url = `${url}?q=${cityName}&APPID=${apikey}&units=metric`;
// OpenWeather
const doOpenWeather = async () => {
try {
let result = await axios.get(url);
return result["data"];
} catch (error) {
console.log(`Error message: ${error.message}`);
}
};
// GASのURL
let gasUrl = "https://script.google.com/macros/s/xxxxxxx/exec"; // みなさんのGASのURLに差し替える
const doGAS = async () => {
// OpenWeatherから気温と天気を取得
const openWeatherData = await doOpenWeather();
try {
// JSONデータから必要なデータを取得
const temp = openWeatherData["main"]["temp"]; // 気温
const weather = openWeatherData["weather"][0]["main"]; // 天気
// 最終URLを作成
gasUrl = `${gas}?temp=${temp}&weather=${weather}`
await axios.get(gasUrl);
} catch(error) {
console.log(`Error message: ${error.message}`);
}
}
// 実行
doGAS();
実行すると、このように日付とOpenWeatherから取得した値がGoogle スプレッドシートに追加されます。
それでは、コードを解説してきます。
// axiosの読み込み
const axios = require("axios");
// URL
let url = "https://api.openweathermap.org/data/2.5/weather";
// 都市名
const cityName = "Tokyo";
// API Key
const apikey = process.env.API_KEY.replace(/\\n/g, '\n');// .envから取得
// 最終URL
url = `${url}?q=${cityName}&APPID=${apikey}&units=metric`;
// OpenWeather
const doOpenWeather = async () => {
try {
const result = await axios.get(url);
return result["data"];
} catch (error) {
console.log(`Error message: ${error.message}`);
}
};
まずは、31行目までを解説します。OpenWeatherとAPI通信を行い、東京の情報を取得しています。コードは、第8弾のOpenWeatherとAPI通信をするコードから少し変更しています。
変更した箇所は、1点です。
// 最終URL
url = `${url}?q=${cityName}&APPID=${apikey}&units=metric`;
13,14行目を変更しました。
units=metric
というURLクエリパラメータを追加しました。これを追加することで、取得する気温が ℃(摂氏) に変換されます。(追加しない場合は華氏となります。)
OpenWeatherから取得したデータは文字列となっているため、JSONに変換してデータを扱いやすくします。
// GASのURL
let gasUrl = "https://script.google.com/macros/s/xxxxxxx/exec"; // みなさんのGASのURLに差し替える
const doGAS = async () => {
// OpenWeatherから気温と天気を取得
const openWeatherData = await doOpenWeather();
try {
// JSONデータから必要なデータを取得
const temp = openWeatherData["main"]["temp"]; // 気温
const weather = openWeatherData["weather"][0]["main"]; // 天気
// 最終URLを作成
gasUrl = `${gas}?temp=${temp}&weather=${weather}`
await axios.get(gasUrl);
} catch(error) {
console.log(`Error message: ${error.message}`);
}
}
// 実行
doGAS();
残りのコードで、取得した情報をスプレッドシートに送信しています。
基本的にはさきほどのコードと同じで、URLクエリパラメータを活用してデータを送信しています。
// OpenWeatherから気温と天気を取得
const openWeatherData = await doOpenWeather();
36,37行目に追加しました。
コード前半で作成した、doOpenWeather()
を使用して東京のデータを取得しています。非同期処理のためawait
が必要です。
// JSONデータから必要なデータを取得
const temp = openWeatherData["main"]["temp"]; // 気温
const weather = openWeatherData["weather"][0]["main"]; // 天気
40~42行目に追加しました。
OpenWeatherから受け取ったままだと、不要なデータが多いため「気温」と「天気」だけを抜き出しています(JSONの扱い方は第9弾で解説しています。)。
// 最終URLを作成
gas = `${gas}?temp=${temp}&weather=${weather}`
44,45行目に追加しました。
先ほど抜き出した「気温」と「天気」をURLクエリパラメータとしてURLに渡しています。このURLクエリパラメータ経由でスプレッドシートにデータが送信されます。
※glitchは、サイトを閉じてもプロジェクトが実行されます。スプレッドシートにデータが送信され続けるので、doGAS();
は// doGAS();
とコメントにして実行されないようにしましょう。
以上がGASでした。
今回はAPIサービスとの連携を行いましたが、他にも様々なことができて便利です。
また、これで基礎編は一通り終了です。
次からは、今回行った最後の「天気情報取得」→「スプレッドシートに送信」の流れを「Eco-Drive Riiiver」で行えるようにします。
コードの内容で不明点があった方は適宜復習していただければと思います。
ご覧くださいましてありがとうございました。