tag:crieit.net,2005:https://crieit.net/tags/Google%E3%82%B9%E3%83%97%E3%83%AC%E3%83%83%E3%83%89%E3%82%B7%E3%83%BC%E3%83%88/feed
「Googleスプレッドシート」の記事 - Crieit
Crieitでタグ「Googleスプレッドシート」に投稿された最近の記事
2020-05-27T15:21:26+09:00
https://crieit.net/tags/Google%E3%82%B9%E3%83%97%E3%83%AC%E3%83%83%E3%83%89%E3%82%B7%E3%83%BC%E3%83%88/feed
tag:crieit.net,2005:PublicArticle/15913
2020-05-27T15:21:26+09:00
2020-05-27T15:21:26+09:00
https://crieit.net/posts/google-twilio-studio-rest-api-node-jp
Googleスプレッドシートのシフト表を使ってTwilio Studioフローの転送先をNode.jsから更新する方法
<p><img src="https://twilio-cms-prod.s3.amazonaws.com/images/bequajswJOH0AUI_wEGCzYL1tE1Lk7xoDRK3nmBGdPsuLw.width-808.png" alt="Header" /><br />
<a target="_blank" rel="nofollow noopener" href="https://www.twilio.com/blog/call-forwarding-studio-remote-work">以前の記事</a>で、在宅勤務に伴う電話問い合わせの一時休止を解決する方法として、Twilio Studioを利用し個人電話に転送する方法を紹介しました。</p>
<p><img src="https://twilio-cms-prod.s3.amazonaws.com/images/n6KNulbJGD3QxKIb-krEiNGnVjw963EqHHcaTmPpBLYAER.width-800.png" alt="Twilio Studio - Flow" /></p>
<p>今回は<a target="_blank" rel="nofollow noopener" href="https://www.twilio.com/blog/load-data-from-google-spreadsheet-jp">別の記事</a>で紹介したGoogleスプレッドシートのシフトデータをもとに転送先となる個人をNode.jsで変更する方法を紹介します。</p>
<p>前提条件</p>
<ul>
<li>Twilioアカウントを持っていること(<a target="_blank" rel="nofollow noopener" href="https://www.twilio.com/blog/how-to-create-twilio-account-jp">無料トライアルのサインアップ方法</a>)</li>
<li>期間限定の問い合わせ番号となる<a target="_blank" rel="nofollow noopener" href="https://support.twilio.com/hc/en-us/articles/360044841214-Twilio-%E3%83%95%E3%83%AA%E3%83%BC%E3%83%88%E3%83%A9%E3%82%A4%E3%82%A2%E3%83%AB%E3%82%A2%E3%82%AB%E3%82%A6%E3%83%B3%E3%83%88%E3%81%AB%E9%96%A2%E3%81%97%E3%81%A6#h_167b5625-0036-44e6-936f-108ed091cb80">電話番号を購入</a>していること<br />
(<a target="_blank" rel="nofollow noopener" href="https://support.twilio.com/hc/en-us/articles/360044400214-%E8%A6%8F%E5%88%B6%E6%83%85%E5%A0%B1%E3%81%AB%E9%96%A2%E3%82%8F%E3%82%8B%E6%9B%B8%E9%A1%9E%E3%81%AE%E6%8F%90%E5%87%BA%E6%96%B9%E6%B3%95">日本の番号を取得する場合</a>)</li>
<li><a target="_blank" rel="nofollow noopener" href="https://www.twilio.com/blog/call-forwarding-studio-remote-work">こちらの記事</a>に則りフローを作成、公開済みであること</li>
<li><a target="_blank" rel="nofollow noopener" href="https://www.twilio.com/blog/load-data-from-google-spreadsheet-jp">こちらの記事</a>に則りGoogleスプレッドシートからデータを取得するNode.jsアプリケーションを作成済みであること</li>
</ul>
<h2 id="Node.jsプロジェクトの作成とパッケージのインストール"><a href="#Node.js%E3%83%97%E3%83%AD%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E3%81%AE%E4%BD%9C%E6%88%90%E3%81%A8%E3%83%91%E3%83%83%E3%82%B1%E3%83%BC%E3%82%B8%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB">Node.jsプロジェクトの作成とパッケージのインストール</a></h2>
<p><a target="_blank" rel="nofollow noopener" href="https://www.twilio.com/blog/load-data-from-google-spreadsheet-jp">以前の記事</a>に沿って作成したNode.jsアプリケーションのフォルダーに移動し、<a target="_blank" rel="nofollow noopener" href="https://www.npmjs.com/package/twilio">twilio-node</a>パッケージをインストールします。</p>
<pre><code>npm i twilio
</code></pre>
<p>次に.envファイルにTwilioへの接続情報やStudioフローのIDを保存する環境変数を追加します。</p>
<pre><code>SPREADSHEET_ID=
STAFF_WORKSHEET_ID=
SHIFT_WORKSHEET_ID=
TWILIO_ACCOUNT_SID=
TWILIO_AUTH_TOKEN=
TWILIO_STUDIO_FLOW_SID=
</code></pre>
<h2 id="Twilio Studio REST API v2を使ったフローの取得と更新"><a href="#Twilio+Studio+REST+API+v2%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%9F%E3%83%95%E3%83%AD%E3%83%BC%E3%81%AE%E5%8F%96%E5%BE%97%E3%81%A8%E6%9B%B4%E6%96%B0">Twilio Studio REST API v2を使ったフローの取得と更新</a></h2>
<p>今回利用するTwilio Studio REST API v2は4月末に<a target="_blank" rel="nofollow noopener" href="https://www.twilio.com/blog/automate-flow-deployments-studio-rest-api-v2-beta">パブリックベータとしてアナウンス</a>されたばかりの機能です。この新しいAPIを使って定義済みのフロー設定を外部から更新できます。</p>
<p><a target="_blank" rel="nofollow noopener" href="https://www.twilio.com/console">Twilioコンソール</a>を開きACCOUNT SIDと、AUTH TOKENをそれぞれ.envファイルの <code>TWILIO_ACCOUNT_SID</code>ならびに <code>TWILIO_STUDIO_FLOW_SID</code> の値として設定します。</p>
<p><img src="https://twilio-cms-prod.s3.amazonaws.com/images/cfc6YMp-DykS55Rahs24kn2759AIZSMNsfhTto3dnHBibZ.width-800.png" alt="AccountSid & AuthToken" /></p>
<p>次に、<a target="_blank" rel="nofollow noopener" href="https://www.twilio.com/console/studio/dashboard">Studioコンソール</a>を開き、call forwardingフローのSIDを <code>TWILIO_STUDIO_FLOW_SID</code> の値として設定します。</p>
<p>index.jsを開き、<a target="_blank" rel="nofollow noopener" href="https://www.twilio.com/blog/load-data-from-google-spreadsheet-jp">前回の記事</a>でテストに使用したコードを変更します。このコードでは、シフト担当者の電話番号を取得した状態で、Twilio Nodeクライアントを利用しStudioフローを取得します。</p>
<pre><code class="js">loadShiftPhoneNumbers().then (
numbers => {
// twilio client
const client = require('twilio')
(process.env.TWILIO_ACCOUNTSID,
process.env.TWILIO_AUTH_TOKEN);
// Studioのフローを取得
client.studio.flows(process.env.TWILIO_STUDIO_FLOW_SID)
.fetch()
.then(flow => {})
.catch(error => console.error(error))
;})
.catch( error => console.error(error));
</code></pre>
<p>フローの定義情報は、definitionというプロパティに保持されているため、そちらを取得します。また、各ウィジェットについては、statesというプロパティに配列として定義されています。このstates配列からウィジェットの名前をキーとして着信を転送するウィジェットを取得し、更に転送先番号を更新します。</p>
<pre><code class="js">loadShiftPhoneNumbers().then (
numbers => {
// twilio client
const client = require('twilio')
(process.env.TWILIO_ACCOUNTSID,
process.env.TWILIO_AUTH_TOKEN);
// Studioのフローを取得
client.studio.flows(process.env.TWILIO_STUDIO_FLOW_SID)
.fetch()
.then(flow => {
// フローの定義を取得
let definition = flow.definition;
// forward_callウィジェットを取得
let callForwardWidget = definition.states.find(
item => item.name == 'forward\_call');
// 転送先番号をシフトの電話番号で更新
callForwardWidget.properties.to = numbers;
})
.catch(error => console.error(error));
})
.catch( error => console.error(error));
</code></pre>
<p>後は更新した定義をStudio REST API v2を使い、反映させます。この際、statusプロパティで反映したフローを下書き状態(draft)にしておくことも、即座に公開(published)にすることもできます。</p>
<pre><code class="js">loadShiftPhoneNumbers().then (
numbers => {
// twilio client
const client = require('twilio')
(process.env.TWILIO_ACCOUNTSID,
process.env.TWILIO_AUTH_TOKEN);
// Studioのフローを取得
client.studio.flows(process.env.TWILIO_STUDIO_FLOW_SID)
.fetch()
.then(flow => {
// フローの定義を取得
let definition = flow.definition;
// forward_callウィジェットを取得
let callForwardWidget = definition.states.find(
item => item.name == 'forward\_call');
// 転送先番号をシフトの電話番号で更新
callForwardWidget.properties.to = numbers;
// 更新した定義を反映し、即座に公開
client.studio.flows(process.env.TWILIO_STUDIO_FLOW_SID)
.update({
definition: definition,
commitMessage: 'シフトの更新 - 2020/05/15',
status: 'published'})
.then(res => console.log(res))
.catch(error => console.error(error));
})
.catch(error => console.error(error));
})
.catch( error => console.error(error));
</code></pre>
<p>index.jsを実行し、ログにエラーが含まれていないこと、Studioのフローが実際に変更されていることを確認しましょう。</p>
<pre><code>node index.js
</code></pre>
<h2 id="まとめ"><a href="#%E3%81%BE%E3%81%A8%E3%82%81">まとめ</a></h2>
<p>ご覧いただいたように、パブリックベータとして公開されたREST API v2を活用することで、外部のデータやシステムと連携した上でTwilio Studioのフローを更新することができるようになりました。非常に強力なAPIなので、ぜひご活用ください。</p>
<p>今回のサンプルはこちらの<a target="_blank" rel="nofollow noopener" href="https://github.com/neri78/twilio-studio-google-spreadsheet">GitHubリポジトリ</a>からクローンし、環境変数にそれぞれ値を設定することで確認することも可能です。</p>
<h2 id="新型コロナウイルス感染症への支援策について"><a href="#%E6%96%B0%E5%9E%8B%E3%82%B3%E3%83%AD%E3%83%8A%E3%82%A6%E3%82%A4%E3%83%AB%E3%82%B9%E6%84%9F%E6%9F%93%E7%97%87%E3%81%B8%E3%81%AE%E6%94%AF%E6%8F%B4%E7%AD%96%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6">新型コロナウイルス感染症への支援策について</a></h2>
<p>Twilioでは新型コロナウィルス感染症により引き起こされるさまざまな社会問題を解決する会社、団体、開発者グループに向けて無料クレジットの進呈など支援を行なっています。詳しくは<a target="_blank" rel="nofollow noopener" href="https://www.twilio.com/blog/covid-19-response-japan">こちらの記事</a>をご覧ください。</p>
<p>また、Twilioを自社のシステム、ソリューションやパッケージに組み込みたいとお考えの場合は、<a target="_blank" rel="nofollow noopener" href="https://www.twilio.com/japan/help/sales">営業部までお問い合わせ</a>ください。</p>
<h2 id="このエントリについての問い合わせ"><a href="#%E3%81%93%E3%81%AE%E3%82%A8%E3%83%B3%E3%83%88%E3%83%AA%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6%E3%81%AE%E5%95%8F%E3%81%84%E5%90%88%E3%82%8F%E3%81%9B">このエントリについての問い合わせ</a></h2>
<p>不明点があればぜひ、お問い合わせください。オンライン登壇のご依頼等もこちらまで!</p>
<ul>
<li>Twitter (<a target="_blank" rel="nofollow noopener" href="https://twitter.com/neri78">@Neri78</a>)</li>
<li>Email: <a target="_blank" rel="nofollow noopener" href="mailto:dikehara@twilio.com">[email protected]</a></li>
<li>Github: <a target="_blank" rel="nofollow noopener" href="https://github.com/neri78">https://github.com/neri78</a></li>
<li>Twitch: <a target="_blank" rel="nofollow noopener" href="https://twitch.tv/neri78">https://twitch.tv/neri78</a></li>
</ul>
Neri78
tag:crieit.net,2005:PublicArticle/15903
2020-05-20T16:34:57+09:00
2020-05-20T18:07:54+09:00
https://crieit.net/posts/google-spreadsheet-sheets-api
GoogleスプレッドシートからNode.jsでシフトデータを読み出す方法
<p><img src="https://twilio-cms-prod.s3.amazonaws.com/images/JfSEBIrPI4CAu3k18bqViRLlvPl1fZIbJ9LpKwl1J86O0d.width-808.png" alt="Header Image" /><br />
<a target="_blank" rel="nofollow noopener" href="https://console.cloud.google.com/?hl=ja">Google Cloud Platform(GCP)</a>には<a target="_blank" rel="nofollow noopener" href="https://developers.google.com/sheets/api">Google Sheets API</a>が提供されており、このAPIを利用してGoogleスプレッドシートのデータにアクセスすることができます。今回はGoogleスプレッドシートのスタッフ、シフトデータをNode.jsで読み込む方法を紹介します。</p>
<p>前提条件</p>
<ul>
<li><a target="_blank" rel="nofollow noopener" href="https://console.cloud.google.com/?hl=ja">Google Cloud Platform (GCP)のアカウント</a>の作成、ならびに有効な支払い方法が登録されていること</li>
<li><a target="_blank" rel="nofollow noopener" href="https://www.google.com/intl/ja_jp/sheets/about/">Googleスプレッドシート</a>を利用できること</li>
</ul>
<h2 id="シフトを管理するGoogleスプレッドシート"><a href="#%E3%82%B7%E3%83%95%E3%83%88%E3%82%92%E7%AE%A1%E7%90%86%E3%81%99%E3%82%8BGoogle%E3%82%B9%E3%83%97%E3%83%AC%E3%83%83%E3%83%89%E3%82%B7%E3%83%BC%E3%83%88">シフトを管理するGoogleスプレッドシート</a></h2>
<p><a target="_blank" rel="nofollow noopener" href="https://docs.google.com/spreadsheets/d/1KHozXisufSbldqeTtkTO3-fRT9McdVxrzVz7YyCWSqM/edit?usp=sharing">こちら</a>にスプレッドシートのサンプルを用意しました。ファイルメニューからこのスプレッドシートを自分のGoogleアカウントで利用できるようにコピーします。スプレッドシートの中身をみてみましょう。Shiftシートには日ごとの担当者を4名まで設定しています。<br />
<img src="https://twilio-cms-prod.s3.amazonaws.com/images/JTcbF8FiG0AyceVQcR4FQNszfxEwj5zwFtf9w0KPLfcwJj.width-800.png" alt="Google Spreadsheet - Shift" /></p>
<p>また、Staffシートには担当者ごとの連絡先電話番号が<a target="_blank" rel="nofollow noopener" href="https://www.twilio.com/docs/glossary/what-e164">E.164フォーマット</a>で登録されています。</p>
<p><img src="https://twilio-cms-prod.s3.amazonaws.com/images/-ke-JpIzwIkEdVu41E8aa4OsC8YPLq9zHavppvy7FuI04C.width-800.png" alt="Google Spreadsheet - Staff" /></p>
<h2 id="GCPでSheets APIを有効化"><a href="#GCP%E3%81%A7Sheets+API%E3%82%92%E6%9C%89%E5%8A%B9%E5%8C%96">GCPでSheets APIを有効化</a></h2>
<p>はじめてGCPを利用する場合は、<a target="_blank" rel="nofollow noopener" href="https://console.cloud.google.com/cloud-resource-manager">コンソール</a>からプロジェクトを作成します。<br />
<img src="https://twilio-cms-prod.s3.amazonaws.com/images/ooE7wJ3JEVutwUGFPfuZC9JorRaxWpFOD4K4DS9syz0L99.width-800.png" alt="GCP - Create a project" /></p>
<p>例ではプロジェクト名を <code>google-sheet-studio</code> としましたが、任意のプロジェクト名で構いません。<br />
<img src="https://twilio-cms-prod.s3.amazonaws.com/images/AfZdHBVKjtKyGBsHpFbVGErsr-LOfmrkXp5xIYYN0hLnU0.width-800.png" alt="GCP - project name" /></p>
<p>作成ボタンをクリックするとリソースの管理画面に戻り、プロジェクトの作成が開始されます。数十秒〜数分程度で作成が完了します。</p>
<p>次に<a target="_blank" rel="nofollow noopener" href="https://console.cloud.google.com/apis/library">API ライブラリ</a>を開きます。</p>
<p><img src="https://twilio-cms-prod.s3.amazonaws.com/images/GDhetd6rJRyWJZNxq1leRhhn7bwz3hqWkj74w0eeSCHQhv.width-800.png" alt="GCP - Open API Library" /></p>
<p>先ほど作成したプロジェクトが選択されていることを確認します。</p>
<p><img src="https://twilio-cms-prod.s3.amazonaws.com/images/F085blQIr1lxDfm7NuuO1Om1XrHR8RUZazZMvc0CRydar-.width-800.png" alt="GCP - API Library with a project" /></p>
<p>Google Sheets APIを検索し、プロジェクトに追加します。</p>
<p><img src="https://twilio-cms-prod.s3.amazonaws.com/images/5QjQstd86zQXHcCP_oPQVO5uIvSOipkjGwBqZjTQyKcEpL.width-800.png" alt="GCP - search sheets API" /></p>
<p>詳細画面から <code>有効にする</code> ボタンをクリックするとGoogle Sheets APIが有効になります。</p>
<p><img src="https://twilio-cms-prod.s3.amazonaws.com/images/iHS-ff4E5U65OLwx-Hz52VM2VCeCDb14rjwmseU2cb3C1W.width-800.png" alt="GCP - enable sheets API" /></p>
<p>APIが有効化されると、概要画面に遷移します。次に <code>認証情報を作成</code> ボタンをクリックし、このAPIを使用するための認証情報を作成します。</p>
<p><img src="https://twilio-cms-prod.s3.amazonaws.com/images/mdPFFkjpFUewRvZtgR4HhhwNtONnuvGvs4o3Mbb8YWXGnT.width-800.png" alt="GCP - Add auth info" /></p>
<p>認証情報の追加画面において次の設定を行い、<code>必要な認証情報</code> ボタンをクリックします。</p>
<ul>
<li>使用する API - Google Sheets API</li>
<li>API を呼び出す場所 - ウェブサーバー(node.js、Tomcat など)</li>
<li>アクセスするデータの種類 - アプリケーション データ</li>
<li>App Engine または Compute Engine でこの API を使用する予定はありますか? - いいえ、使用していません</li>
</ul>
<p><img src="https://twilio-cms-prod.s3.amazonaws.com/images/d7DzQucz1snBQJBnUZ8AxaWun3kguQxe8_xf6HS2NrjFgr.width-800.png" alt="GCP - Create a service account" /></p>
<p>続けてサービスアカウント名とロールを設定します。例では、<code>test</code> およびロールを <code>Project</code> の <code>閲覧者</code> とし、キーのタイプを <code>JSON</code> としました。</p>
<p><img src="https://twilio-cms-prod.s3.amazonaws.com/images/y-iIsGp2LwAvFexgqbUx_lANXcg-bhKlka14JOcK1sb97D.width-800.png" alt="GCP - Create a service account - name" /></p>
<p><code>次へ</code> ボタンをクリックすると認証情報を含んだJSONファイルが作成されダウンロードされます。このファイルはGoogle Sheets APIを利用するために必要になります。作成されたJSONファイルを開くと <code>client_email</code> という名前のキーの値に先ほど作成したサービス アカウント IDが記載されています。Googleスプレッドシートを共有する際にこの情報が必要になります。</p>
<p><img src="https://twilio-cms-prod.s3.amazonaws.com/images/JgW7p51hA5u-4yggqHymFjLMI_rGBvu0wAHDCpVJXsZeJq.width-800.png" alt="gcp - service account" /></p>
<h2 id="Googleスプレッドシートの共有とURLや情報の確認"><a href="#Google%E3%82%B9%E3%83%97%E3%83%AC%E3%83%83%E3%83%89%E3%82%B7%E3%83%BC%E3%83%88%E3%81%AE%E5%85%B1%E6%9C%89%E3%81%A8URL%E3%82%84%E6%83%85%E5%A0%B1%E3%81%AE%E7%A2%BA%E8%AA%8D">Googleスプレッドシートの共有とURLや情報の確認</a></h2>
<p>次に、Google Sheets APIからアクセスをできるようにGoogleスプレッドシートをサービス アカウントに共有します。先ほど複製したGoogleスプレッドシートを開き、右上の <code>共有</code> ボタンをクリックします。表示された共有ダイアログに先ほどのサービス アカウント IDを入力します。</p>
<p><img src="https://twilio-cms-prod.s3.amazonaws.com/images/eNfWeKahkSszuRfCxD4PgtaVRVJm-vLmfv19RvvXM4xgxb.width-800.png" alt="Google Spreadsheet - share the sheet" /></p>
<p>Enterキーを押すと、権限の設定を行えます。書き込み権限は必要ないため閲覧者としました。<code>共有</code> ボタンをクリックし、共有を完了します。</p>
<p><img src="https://twilio-cms-prod.s3.amazonaws.com/images/z5tAPOALrfoTztQVwEDWn1fmusPZP25PbsepJd8VsMp8P7.width-800.png" alt="Google Spreadsheet - share as a viewer" /></p>
<p>更に、このGoogleスプレッドシートから次の情報を控えておきます。</p>
<ul>
<li>スプレッドシートID(https://docs.google.com/spreadsheets/d/ の後に表示されている英数文字列のうち、次の’/’ の前の値。例: https://docs.google.com/spreadsheets/d/ <strong>12312321xxx21232131212</strong> /edit#gid=0 の太字部分)</li>
<li>Shift、StaffそれぞれのワークシートのID(URLが <strong>#gid=0</strong> の場合は、 <strong>0</strong> となる )</li>
</ul>
<p>これでシートから情報を取得する前準備が整いました。</p>
<h2 id="Node.jsプロジェクトの作成とパッケージのインストール"><a href="#Node.js%E3%83%97%E3%83%AD%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E3%81%AE%E4%BD%9C%E6%88%90%E3%81%A8%E3%83%91%E3%83%83%E3%82%B1%E3%83%BC%E3%82%B8%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB">Node.jsプロジェクトの作成とパッケージのインストール</a></h2>
<p><a target="_blank" rel="nofollow noopener" href="https://developers.google.com/sheets/api">Google Sheets API</a>を利用することでGoogleスプレッドシートのデータにアクセスすることができます。このAPIに対応する<a target="_blank" rel="nofollow noopener" href="https://github.com/googleapis/google-api-nodejs-client/tree/master/src/apis/sheets">Node.jsクライアントライブラリ</a>も用意されており、<a target="_blank" rel="nofollow noopener" href="https://developers.google.com/sheets/api/quickstart/nodejs">クイックスタート</a>のようにセルの値を取得することもできるのですが、取得するセルの範囲を指定する必要があり、使いにくいと感じるかもしれません。そのため、今回はGoogle Sheets APIを使いやすくラップした<a target="_blank" rel="nofollow noopener" href="https://developers.google.com/sheets/api/quickstart/nodejs">google-spreadsheet</a>パッケージを利用します。このパッケージを利用すると、セルの範囲を指定することなく、ワークシートから行オブジェクトとしてデータを読み込むことができます。</p>
<p>Node.jsアプリケーションを作成し、<a target="_blank" rel="nofollow noopener" href="https://www.npmjs.com/package/google-spreadsheet">google-spreadsheet</a>と環境変数を.envファイルからロードできる<a target="_blank" rel="nofollow noopener" href="https://www.npmjs.com/package/dotenv">dotenv</a>パッケージをインストールします。</p>
<pre><code class="bash">npm i google-spreadsheet dotenv
</code></pre>
<p>次にGoogleスプレッドシートやシートのIDを記録しておく.envファイルを作成します。</p>
<pre><code class="bash">touch .env
</code></pre>
<p>.envファイルには次の環境変数を追加しておきます。</p>
<pre><code>SPREADSHEET_ID=
SHIFT_WORKSHEET_ID=
STAFF_WORKSHEET_ID=
</code></pre>
<p><code>SPREADSHEET_ID</code>、<code>STAFF_WORKSHEET_ID</code>、<code>SHIFT_WORKSHEET_ID</code> には先ほど控えておいたGoogleスプレッドシートのIDやそれぞれのシートのIDを追加します。</p>
<p>最後にGCPからダウンロードしたJSONファイルをプロジェクトフォルダーにコピーし、わかりやすいように名前を <code>credentials.json</code> と変更します。これで準備完了です。</p>
<h2 id="Googleスプレッドシートからシフト表を取得"><a href="#Google%E3%82%B9%E3%83%97%E3%83%AC%E3%83%83%E3%83%89%E3%82%B7%E3%83%BC%E3%83%88%E3%81%8B%E3%82%89%E3%82%B7%E3%83%95%E3%83%88%E8%A1%A8%E3%82%92%E5%8F%96%E5%BE%97">Googleスプレッドシートからシフト表を取得</a></h2>
<p>ここからはGoogleスプレッドシートからシフト表を取得するコードを実装します。Node.jsアプリケーションに新しくjsファイルを追加します。<code>index.js</code> という名前で作成しました。</p>
<pre><code class="bash">touch index.js
</code></pre>
<p>index.jsをエディタで開き、環境変数の読み込みや必要なパッケージをインポートします。</p>
<pre><code class="js">'use strict';
require('dotenv').config();
const { GoogleSpreadsheet } = require('google-spreadsheet');
</code></pre>
<p>次にGoogleスプレッドシートからシフトデータを読み取り、担当者の電話番号を返す非同期関数を実装します。</p>
<pre><code class="js">// Googleスプレッドシートからシフト情報をロードし、担当者の電話番号を取得
async function loadShiftPhoneNumbers() {
// 処理を実装
}
</code></pre>
<p>この <code>loadShiftPhoneNumbers</code> 関数でGoogleスプレッドシートをロードします。ここでGCPへの接続に必要になるのが先ほどコピーし、名前を変更した <code>credentials.json</code> です。</p>
<pre><code class="js">// Googleスプレッドシートからシフト情報をロードし、担当者の電話番号を取得
async function loadShiftPhoneNumbers() {
// スプレッドシートIDと資格情報を用いてGoogleスプレッドシートをロード
const doc = new GoogleSpreadsheet(process.env.SPREADSHEET\_ID);
const credentials = require('./credentials.json');
await doc.useServiceAccountAuth(credentials);
await doc.loadInfo();
}
</code></pre>
<p>ワークシートを取得する場合は、<a target="_blank" rel="nofollow noopener" href="https://theoephraim.github.io/node-google-spreadsheet/#/classes/google-spreadsheet?id=worksheets">GoogleSpreadsheet.sheetsById、またはGoogleSpreadsheet.sheetsbyIndex</a>を利用できます。さらに、<a target="_blank" rel="nofollow noopener" href="https://theoephraim.github.io/node-google-spreadsheet/#/classes/google-spreadsheet-worksheet?id=fn-getrows">GoogleSpreadsheetWorksheet.getRows</a>メソッドを使用し、ワークシートの行を取得できます。残念ながら特定の列の値をキーにフィルタリングはできないようなので全ての行を取得します。</p>
<pre><code class="js">// Googleスプレッドシートからシフト情報をロードし、担当者の電話番号を取得
async function loadShiftPhoneNumbers() {
// スプレッドシートIDと資格情報を用いてGoogleスプレッドシートをロード
const doc = new GoogleSpreadsheet(process.env.SPREADSHEET\_ID);
const credentials = require('./credentials.json');
await doc.useServiceAccountAuth(credentials);
await doc.loadInfo();
//シフト情報を取得
const shiftSheet = await doc.sheetsById[process.env.SHIFT_WORKSHEET_ID];
const shiftRows = await shiftSheet.getRows();
// 従業員情報を取得
const staffSheet = await doc.sheetsById[process.env.STAFF_WORKSHEET_ID];
const staffRows = await staffSheet.getRows();
}
</code></pre>
<p><a target="_blank" rel="nofollow noopener" href="https://theoephraim.github.io/node-google-spreadsheet/#/classes/google-spreadsheet-worksheet?id=fn-getrows">GoogleSpreadsheetWorksheet.getRows</a>メソッドはGoogleSpreadsheetRowの配列を返します。また、この<a target="_blank" rel="nofollow noopener" href="https://theoephraim.github.io/node-google-spreadsheet/#/classes/google-spreadsheet-row">GoogleSpreadsheetRow</a>オブジェクトは最初の行をプロパティのキーとしてアクセスできるため、<a target="_blank" rel="nofollow noopener" href="https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/find">Array.prototype.find()</a>メソッドを利用し、Date列をキーとして特定の日付のデータを抜き出すことができます。この記事では、2020年5月15日を例として取得します。実際のアプリケーションでは <code>new Date()</code> などを利用し、当日のデータを取得することになるでしょう。</p>
<pre><code class="js">// Googleスプレッドシートからシフト情報をロードし、担当者の電話番号を取得
async function loadShiftPhoneNumbers() {
// スプレッドシートIDと資格情報を用いてGoogleスプレッドシートをロード
const doc = new GoogleSpreadsheet(process.env.SPREADSHEET\_ID);
const credentials = require('./credentials.json');
await doc.useServiceAccountAuth(credentials);
await doc.loadInfo();
//シフト情報を取得
const shiftSheet = await doc.sheetsById[process.env.SHIFT_WORKSHEET_ID];
const shiftRows = await shiftSheet.getRows();
// 従業員情報を取得
const staffSheet = await doc.sheetsById[process.env.STAFF_WORKSHEET_ID];
const staffRows = await staffSheet.getRows();
// シフト情報からDate列の値と指定した日付をロケール情報に基づいて取得
let shiftRow = shiftRows.find(row =>
new Date(row.Date).toLocaleDateString() ===
new Date('2020/5/15').toLocaleDateString());
}
</code></pre>
<p>あとは、取得した行から必要なデータを読み取り、アプリケーションで使用できます。</p>
<p>データの活用例として、このシフトデータから担当者の電話番号をカンマ区切りの文字列で取得する方法も実装します。</p>
<p><code>shiftRow.Employee1</code>のように各列のキーを指定してデータを取得することもできますが、<code>shiftRow._rawData shiftRow</code> には、行のデータが配列として保持されています。2020年5月15日のデータは、<code>['5/15/2020', 'Mitsuharu', 'Yoshihiro']</code> となります。この配列を<a target="_blank" rel="nofollow noopener" href="https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/slice">Array.prototype.slice()</a>メソッドで最初の日付データを除外した配列とし、さらに、<a target="_blank" rel="nofollow noopener" href="https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/map">Array.prototype.map()</a>メソッドでシフト担当の従業員の電話番号の配列へと変換します。そして、最後に、<a target="_blank" rel="nofollow noopener" href="https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/join">Array.prototype.join()</a>メソッドで文字列として返すという処理を実装しました。</p>
<pre><code class="js">// Googleスプレッドシートからシフト情報をロードし、担当者の電話番号を取得
async function loadShiftPhoneNumbers() {
// スプレッドシートIDと資格情報を用いてGoogleスプレッドシートをロード
const doc = new GoogleSpreadsheet(process.env.SPREADSHEET\_ID);
const credentials = require('./credentials.json');
await doc.useServiceAccountAuth(credentials);
await doc.loadInfo();
//シフト情報を取得
const shiftSheet = await doc.sheetsById[process.env.SHIFT_WORKSHEET_ID];
const shiftRows = await shiftSheet.getRows();
// 従業員情報を取得
const staffSheet = await doc.sheetsById[process.env.STAFF_WORKSHEET_ID];
const staffRows = await staffSheet.getRows();
// シフト情報からDate列の値と指定した日付をロケール情報に基づいて取得
let shiftRow = shiftRows.find(row =>
new Date(row.Date).toLocaleDateString() ===
new Date('2020/5/15').toLocaleDateString());
// 元データ['5/15/2020', 'Mitsuharu', 'Yoshihiro']
// Date列(最初の列)を取り除き、シフト担当の従業員を含む配列を取得する
let employeesOnDuty = shiftRow._rawData.slice(1);
// ['Mitsuharu', 'Yoshihiro']
// 名前から電話番号の配列に置換
employeesOnDuty = employeesOnDuty.map(m =>
staffRows.find(row => row.Name === m).PhoneNumber);
// ['+815012341235', '+815012341237']
return employeesOnDuty.join(',');}
</code></pre>
<p>ここまで実装を終えた段階で、きちんとデータを読み込めるかどうかを確認しましょう。<br />
loadShiftNumbers関数のスコープ外に次のコードを追加します。</p>
<pre><code class="js">// 実装した関数が正しく動作するかテスト
loadShiftPhoneNumbers()
.then (numbers => console.log(numbers))
.catch(error => console.error(error));
</code></pre>
<p>index.jsを実行し、次のような結果がコンソールに出力されていれば成功です。</p>
<pre><code>node index.js
</code></pre>
<p>実行結果</p>
<pre><code>+815012341235,+815012341237
</code></pre>
<p>想定した結果が得られない場合は、出力されたエラーを参考にGCPの設定や、JSONファイルの読み込みなどを確認してください。</p>
<h2 id="まとめ"><a href="#%E3%81%BE%E3%81%A8%E3%82%81">まとめ</a></h2>
<p>ご覧いただいたように、Google Sheets APIを使うことでGoogleスプレッドシートをデータソースとしたアプリケーションを構築することができます。ぜひご活用ください。</p>
<h2 id="このエントリについての問い合わせ"><a href="#%E3%81%93%E3%81%AE%E3%82%A8%E3%83%B3%E3%83%88%E3%83%AA%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6%E3%81%AE%E5%95%8F%E3%81%84%E5%90%88%E3%82%8F%E3%81%9B">このエントリについての問い合わせ</a></h2>
<p>不明点があればぜひ、お問い合わせください。オンライン登壇のご依頼等もこちらまで!</p>
<ul>
<li>Twitter (<a target="_blank" rel="nofollow noopener" href="https://twitter.com/neri78">@Neri78</a>)</li>
<li>Email: <a target="_blank" rel="nofollow noopener" href="mailto:dikehara@twilio.com">[email protected]</a></li>
<li>Github: <a target="_blank" rel="nofollow noopener" href="https://github.com/neri78">https://github.com/neri78</a></li>
<li>Twitch: <a target="_blank" rel="nofollow noopener" href="https://twitch.tv/neri78">https://twitch.tv/neri78</a></li>
</ul>
Neri78