概要
今回、知見共有・技術向上意欲の促進を図ることを目的に、社員が会社や個人の所有する書籍の把握を容易にするために書籍管理アプリを作成しました。(あとGASを使ってみたかった😌笑)
GAS(Google Apps Script)を中心に、様々なサービスを連携します。
記事では主要な作業部分のみ解説しています。
構成図
サービス | 用途 |
---|---|
Glideapps | UI/CRUD |
Pic2shop | バーコードスキャン |
Google SpreadSheet | データベース |
Google Apps Script | スクリプト |
Slack | 通知 |
完成画面
実際にできたものがこちらです。
https://booklist.glideapp.io/
https://github.com/mgmgmgmi/BookList
※アプリは社内用なので公開していないです…要望があればコピーして公開します。
社内向けのものを作ったので公開しました。
ホーム画面 / 詳細画面 / 編集画面
書籍一覧を閲覧・編集できます。
slack通知
書籍登録時や貸借時にSlackで通知を行います。
開発環境について
今回はclaspを利用しました。
GASのコードとGitを連携してバージョン管理できるスグレモノです。
自分の好きなエディタで実装できるのも嬉しいポイントです。
参考:claspを使い、Google Apps Scriptプロジェクトをgitでバージョン管理する - Qiita
実装
1. GAS×スプレッドシートの連携
詳しい解説はコチラ
DB代わりのスプレッドシートのカラムは以下のような構造にしました。
A列目にISBNコードを入力すると、B~F列に書籍情報が登録されます。
書籍の登録時に書籍情報を取得するため、Google Books APIを使用しています。
2. スプレッドシート×GlideAppsの連携
GlideAppsとのサービス連携
GlideApps からGoogleアカウントで認証を行います。
その後、該当のスプレッドシートを指定してGlideAppsのプロジェクトを作成します。
参考:簡単過ぎる!GoogleスプレッドシートからPWAアプリを開発できる「Glide」を使ってみた! - paiza開発日誌
3. GAS×slackの連携
Slack APIを用いた投稿リクエストの実装
Slackに対する投稿は、Slack APIのchat.postMessageを利用します。
トークンとチャンネルIDは自分のものを確認して記載してください。
function postSlack(text){
const token = 'hogehoge';
const channel = 'fugafuga';
//Slack投稿
const response = UrlFetchApp.fetch(
'https://slack.com/api/chat.postMessage?'
+ 'token=' + token
+ '&channel=' + channel
+ '&text=' + encodeURIComponent(text)
);
//レスポンス確認
Logger.log(JSON.parse(response.getContentText()));
}
ここでの注意点は、textなどパラメータの値に特殊文字等が入っているとGASのバリデーションにかかってエラーになります。
そのためencodeURIComponent関数でエンコードを行います。
スクリプトプロパティを利用したトークンの管理
Web APIを利用する際、Slack含めサービスによってはAPIキーなどの認可情報が必要な場合があります。
間違ってGitなどにアップしないように、ローカルでの開発では環境変数や外部ファイルなどに格納することが多いと思います。
クラウドで動作するGASでは環境変数の代わりにスクリプトプロパティという機能を利用します。
GASプロジェクトのメニューから ファイル > プロジェクトのプロパティ > スクリプトのプロパティ を開き、名前と値を入れて保存します。
取得する際には、以下のようにプロパティの名前を指定して値を取得することができます。
const properties = PropertiesService.getScriptProperties();
const token = properties.getProperty('SLACK_TOKEN');
const channel = properties.getProperty('SLACK_CHANNEL');
参考:【初心者向けGAS】プロパティストアの概要とスクリプトプロパティの編集方法
4. pic2shop×GASの連携
バーコードの読み取り機能として、Pic2shopというアプリを利用します。
ユーザがバーコード読み取りを行う際、このアプリのダウンロードが必要になります。
カスタムURLスキームによるpic2shopアプリの呼び出し
アプリを起動する場合、カスタムURLスキームを利用します。
Pic2shopでは以下のようなURLでアプリの機能を呼び出します。
pic2shop://scan?callback=(コールバック関数)
コールバック関数の引数として、今回はGETパラメータでGASのWebアプリケーションに渡すことにしました。
バーコードを読み込んだ結果はEAN
という文字に格納されます。
※pic2shopに渡す際はURLエンコードが必要です。
https://(WebアプリケーションのURL)?isbn=EAN
GladeAppsのリンクから呼び出したかったので、 URL(pic2shop://scan?callback=https%3A%2F%2F...%3Fisbn%3DEAN
)をスプレッドシートに記載して表示しました。
参考:iPhoneで簡単にバーコードリーダーを作る方法 – 伊藤清徳の垂直落下式ムーンサルトプレス
GASのWebアプリケーションにおけるパラメータ受け取り部分の実装
GlideAppsにAPIなどがあればよいのですが、対応していないため代わりにGASのWebアプリケーションで値を受け取ってスプレッドシートに登録します。
GASのWebアプリケーションを有効化し、GETパラメータを受け取る準備をします。
参考:Google Apps Scriptをウェブアプリケーションとして公開する手順
そしてパラメータを受け取るためのトリガーであるdoGet関数を実装します。
function doGet(e){
const isbn = e.parameter.isbn;
Logger.log(isbn); //確認
return HtmlService.createHtmlOutput(JSON.stringify(e));
}
ブラウザ等でhttps://(WebアプリケーションのURL)?isbn=EAN
へアクセスし、GASのログでisbnの値が受け取れていることを確認します。
5. 登録後の画面作成
画面作成と値の受け渡し
Webアプリケーションの画面の作成はHtmlServiceクラスを用います。
GAS <=> HTML間の値の受け渡しは、[スクリプトレット(scriptlets)](https://developers.google.com/apps-script/guides/html/templates#scriptlets)と呼ばれる3つの特別なタグ` ... ?>` `= ... ?>` `!= ... ?>`を利用します。
function doGet(e){
const isbn = e.parameter.isbn;
//GASからスプレッドシートへの書き込み
addBook(isbn);
// index.htmlの読み込み
var htmlTemplate = HtmlService.createTemplateFromFile("index");
// isbnの値をHTMLへ渡す
htmlTemplate.isbn = isbn;
return htmlTemplate.evaluate();
}
<!DOCTYPE html>
<html>
<body>
<p>ISBNコード: <?= isbn; ?> </p>
</body>
</html>
参考:Google Apps Script (GAS)のScriptletsを使って外にあるJavaScriptやCSSを読み込む – CodeAid(コードエイド)
画面レイアウトの変更
最後にHTMLファイルにてBootstrapやCSSの読み込みなどを行います。
Bootstrapの読み込みは公式ドキュメントにある通り、以下を記述して利用します。
<head>タグ内
<head>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
</head>
<body>タグ内の最後の行
<body>
...
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
</body>
参考:GASでWebページを作成する際にCSSフレームワークBootstrapを導入する方法
CSSの読み込みは、css.htmlファイルを作成したのち、<head>タグ内に以下を記述して利用します。
(.cssはGASの対象外のため、.htmlとして保存します)
<head>
<?!= HtmlService.createHtmlOutputFromFile('css').getContent(); ?>
</head>
<style>
body {
font-family: -apple-system, BlinkMacSystemFont, Roboto, sans-serif
font-size:14px;
}
</style>
参考:GASでWebページを作るときにHTMLとCSSを別ファイルに記述する方法
最後に
細かいカスタマイズは難しいですが、すでにある便利なサービスを組み合わせることで一週間程度で機能の大部分の実装を終えることができました。
ツールを利用することで開発効率を上げられるのはいいなと思いました。
あと単純に実装楽しかったです!笑
記事に間違いや不明な点があれば遠慮なくご指摘ください。