Glideを使いノーコードベースでPWAアプリを作ってみる

# はじめに
[社内活動](https://qiita.com/organizations/creative)の忘備録として本記事を残します。
## やったこと
### 目標：自動的に情報を収集し発信する仕組みを作ってみる
#### 1. Input：インターネットからデータを取ってくる仕組みづくり
- Google Apps Scriptと公開APIを用いたWebサービスからの情報取得
- スプレッドシートを用いたWebスクレイピング
#### 2. Output：収集した情報を発信する仕組みづくり
- ノーコードツールを用いたPWA(Webアプリ)の構築

## PWA(Progressive Web Apps)とは
### 特徴
- WebサイトのコンテンツをアプリとしてスマートフォンやPCにインストール可能にする技術
- ホーム画面にアイコンを追加することで、ネイティブアプリのような起動が可能
- プッシュ通知を受信可能


# Glideとは
- Googleスプレッドシートからアプリを作成できるアメリカ発のノーコードツール
    - GAS(Google Apps Script)を併用することで高度な処理も可能に
- テンプレートが非常に豊富に用意されており、基本的な機能は簡単に実装可能
- 500,000人と企業が100 万以上のアプリを作成
- 詳細は以下URL参照
https://www.glideapps.com/


# 手順0 用意するもの
- Googleアカウント、Glideアカウント
　→作成方法は省略

# 手順1 Glideでアプリの"がわ"を作る

# 手順2 スプレッドシートでコンテンツを準備する
アプリ内で表示するコンテンツをGoogleスプレッドシート上に集める
## コンテンツ①：天気予報
### OpenWeatherMapのAPIを使用する

```js:getForecastOsaka.gs
function getForecast() {
//Open Weather MapのAPIキーを定義する(各自APIキーで書き換え)
let apiKey = 'apiKey';
let apiUrl = 'https://api.openweathermap.org/data/2.5/forecast?q=';
//天気予報を取得する都市を定義する(今回は東京を設定)
let city = 'Osaka,JP';
//APIリクエストするURLにAPIキーと取得都市のパラメータをセット
let requestUrl = apiUrl + city + '&appid=' + apiKey + '&lang=ja&units=metric';
//UrlFetchAppでOpen Weather MapのAPIから天気予報を取得する
let response = UrlFetchApp.fetch(requestUrl).getContentText();
//取得したデータはJSON形式のため、JSONとして変換する
let json = JSON.parse(response);
//スプレッドシートに書き込むための配列を初期化する
let weatherInfo = [];
//主要7都市分のAPIリクエストをForループで実行する
for (let i = 0; i < json['list'].length; i++) {
weatherInfo[i] = [];
//Open Weather Mapから取得した天気予報の中から必要な情報を2次元配列に書き込み
weatherInfo[i][0] = json['list'][i]['dt_txt'];
weatherInfo[i][1] = json['list'][i]['weather'][0]['description'];
weatherInfo[i][2] = json['list'][i]['main']['temp_min'];
weatherInfo[i][3] = json['list'][i]['main']['temp_max'];
weatherInfo[i][4] = json['list'][i]['main']['humidity'];
weatherInfo[i][5] = json['list'][i]['main']['pressure'];
}
//スクリプトに紐付いたスプレッドシートの天気予報シートを読み込み
let mySheet = SpreadsheetApp.getActive().getSheetByName('天気予報');
//スプレッドシートにOpen Weather Mapから取得した天気予報を書き込み
mySheet.getRange(1,1).setValue(city);
mySheet.getRange(3, 1, weatherInfo.length, weatherInfo[0].length).setValues(weatherInfo);
}
```

### スクリプト実行結果

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2603007/8b179a9c-aa58-0a7c-a903-22e4912933ca.png)



## コンテンツ②：電車の運行状況

```js:getTrain.gs
function getTrain() {
 var sheet = SpreadsheetApp.getActive().getSheetByName('運行情報');
 sheet.getRange('B3')
         .setFormula('=IMPORTXML(C3,D3)'); 
 sheet.getRange('B4')
         .setFormula('=IMPORTXML(C4,D4)'); 
 sheet.getRange('B5')
         .setFormula('=IMPORTXML(C5,D5)'); 
 sheet.getRange('B6')
         .setFormula('=IMPORTXML(C6,D6)'); 
 sheet.getRange('B7')
         .setFormula('=IMPORTXML(C7,D7)'); 
}
```

### スクリプト実行結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2603007/fc694736-fa2f-7116-8cf1-75df411d0c16.png)

## コンテンツ③：今日のネコ占い(開発中)
ランダム要素・乱数

```js:スプレッドシート内関数
#乱数生成
=RAND()

#運勢判定
=IF(C2>95, "Verry Happy!!", IF(C2>80, "Happy!", IF(C2>60, "Not so BAD", 
IF(C2>40, "SoSo...", IF(C2>20, "unnnm", "BAD...")))))

#判定結果画像表示
=IF(C2>95, "https://drive.google.com/file/d/1ccDt4g98WOe1PGuKsROXWLWsdzLiJ5Ch/", 
IF(C2>80, "https://drive.google.com/file/d/1qUGi75iLCwLcOoC9S5NU3oGFwsEqWz6N/", 
IF(C2>60, "https://drive.google.com/file/d/1KtNqFhX-Y_ZxXLsKRX20jJQYLj-hiLeM/", 
IF(C2>40, "https://drive.google.com/file/d/1xBVafmEdAw7vwhUTYfVvY4xfhlrtedLZ/", 
IF(C2>20, "https://drive.google.com/file/d/1GIoyl6OxkXo_1dnl5yRDPkZx_uatiq-S/", 
"https://drive.google.com/file/d/1wTnvc_x9_n37p-Wut06d98yZZQrRFxxh/")))))
}
```

### スクリプト実行結果
![スクリーンショット 2022-05-26 090304.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2603007/1ebffb92-9b3d-da42-1fa4-ccbfca7ab1c4.png)

# 手順3 実装・公開
## コンテンツ①：天気予報
![2022-05-26 090946.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2603007/07dbbfc9-6823-e109-df64-95439bc14da0.png)
![2022-05-26 090959.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2603007/ed9d1b97-3572-5ae5-8768-19c27bf07be2.png)
## コンテンツ②：電車の運行状況
![2022-05-26 091010.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2603007/89e81389-8e29-ad50-84db-fc8c1de2e6c8.png)
![2022-05-26 091017.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2603007/2bf5b37c-055d-55f9-7b2c-151cdc71c025.png)
![2022-05-26 091027.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2603007/3c5ec10e-e286-d765-d7de-5c24cd586682.png)
## コンテンツ③：今日のネコ占い(開発中)
### 生成した乱数をグラフとして表示
![2022-05-26 090757.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2603007/80e9b63c-6b08-62f1-39c9-092143411569.png)

# 今後の課題
- インタラクティブに情報をやり取りできる仕組みづくり
- 洗練されたインターフェース作成
- ストリーミング配信など、よりリッチなコンテンツの取り扱い
    - 猫の癒し動画再生
    - 猫のASMR!?
    - TwitterやInstagramでバズっている猫動画のスクレイピング
    - etc...


# 参考文献
https://auto-worker.com/blog/?p=3298