💻

【slack api (Block kit)】×【GAS】で投票アプリを作る:3回目

2023/02/19に公開

第3回では投票した内容をGoogleスプレッドシートに書き込むところまでを行います。

1.集計兼ログ記録用のスプレッドシートを作成する

●Google Driveでスプレッドシートを作成

Google Driveでスプレッドシートを作成して「集計」シートと「ログ」シートを作成します。
集計シートの1行目にはヘッダ情報として下記を入力してください。
・投票者:ID
・投票者:氏名
・得票者:ID
・得票者:氏名
・投票理由
・投票日時

2.リクエストログをスプレッドシートを書き込む

スプレッドシートにslackからのリクエスト内容を記録する処理を作成します。

●スプレッドシードのIDをスクリプトプロパティとして設定

スプレッドシートのIDを確認します。
スプレッドシートのIDはスプレッドシートのURLでわかります。

スプレッドシートのIDを確認したらIDを前回作成したGASのスクリプトプロパティとして追加します。

プロパティ:SPREAD_SHEET_ID
値:スプレッドシートのID

●GASにリクエスト内容をスプレッドシートに記録する処理を作成する

前回作成したGASに画像の赤枠部分を追加します。

const spreadSheetId = PropertiesService.getScriptProperties().getProperty("SPREAD_SHEET_ID");
//リクエスト内容を'ログ'シートに記録
const ss = SpreadsheetApp.openById(spreadSheetId)
const sheetLog = ss.getSheetByName('ログ')
sheetLog.appendRow([e.parameter.payload])

●動作確認を行いスプレッドシートにリクエスト内容が記録されることを確認する

ここまでで一度デプロイ(※)を行い、投票アプリを操作して動作確認を行ってください。
投票開始ボタンや投票確定ボタンを押したら、スプレッドシートにリクエスト内容が記録されるようになるはずです。
※デプロイ時にGoogleからスプレッドシートへのアクセス許可が求められますので、許可を行ってください。

記録されたリクエストを見ると画面操作によってtypeが異なることがわかります。
・投票開始ボタンを押した場合はblock_actions
・投票確定ボタンを押した場合はview_submissions

この違いを利用して今回は投票開始ボタン押下時、投票確定ボタン押下時で処理を分けるようにします。

3.投票アプリにユーザー情報を閲覧できる権限を設定する

投票内容をスプレッドシートに記録するにあたり下準備を行います。

●投票確定ボタンを押した際のリクエストパラメータ内容について

投票確定ボタンの押下時、slackからのリクエスト内容としては
投票理由は入力した内容がそのまま入っているのですが、投票者は氏名でなくユーザーIDが渡されます。

投票確定ボタンを押した際のリクエスト内容の抜粋
{
    "state": {
        "values": {
            "block_vote_getter": {
	        //得票者の選択メニューの入力内容
                "action_vote_getter": {
                    "type": "users_select",
                    "selected_user": "U04KZV9D8CT" //投票者の設定内容
                }
            },
            "block_vote_reason": {
	        //投票理由のテキストエリアの入力内容
                "action_vote_reason": {
                    "type": "plain_text_input",
                    "value": "テスト" //投票理由の設定内容
                }
            }
        }
    }
}

そのため、このままでは氏名をスプレッドシートに記録することができません。
そこでslackから提供されているAPIを利用してユーザー情報を取得し、その中に含まれているユーザー名から氏名を取得するようにします。

今回使用するAPIはこちらのusers.infoです。
https://api.slack.com/methods/users.info

このAPIを使用するにあたりslackアプリに権限users:readが必要になるため、こちらをslackアプリに設定していきます。

https://api.slack.com/apps

上記リンクから自身で作成したアプリの設定画面を開いてOAuth & Permissions設定画面を表示してください。

users:read権限を付与したら、画面上部に「設定を反映するためにはアプリを再インストールする必要があります」といった旨の警告がでるため、赤枠のリンクをクリックして再インストールを行ないます。

再インストール時、「投票アプリの投稿先」は投票開始ボタンを表示しているチャネル(最初にインストールしたときと同じ)で設定してください。

これでusers:readの権限設定は完了です。

4.GASにユーザー情報を取得する関数を作成する

「users.info」APIを利用してユーザーIDを引数としてユーザー情報を取得する関数getUserInfoを作成します。

●関数getUserInfoを作成

前回作成したGASに下記の関数を作成します。

const getUserInfo = (userId) => {

  const options = {
    "method": "GET",
    "contentType": "application/x-www-form-urlencoded",
    "payload": {
      "token": botUserOAuthToken,
      "user": userId
    }
  }

  const response = UrlFetchApp.fetch('https://slack.com/api/users.info', options);

  const responseObj = JSON.parse(response);

  return responseObj.user
}

optionsで指定している内容は画像赤枠の部分が元ネタとなっています。

これでスプレッドシートに投票内容を記録するための準備が整いました。

5.投票内容をスプレッドシートに記録する

準備が整ったので、投票内容をスプレッドシートに記録する処理を作成していきます。

●処理内容を分ける分岐処理を作成

投票開始ボタンと投票確定ボタンで処理内容を分けるため、次のように分岐処理を追加して、前回までに作成した処理のうち、リクエスト検証より後の処理内容をblock_actions側に配置します。

●投票データ設定して、スプレッドシートにデータを記録する処理を作成

分岐処理を作成したらview_submission側に
・投票データの設定処理
・スプレッドシートに投票データを記録する処理
を追加します。

//●モーダル画面Submit

// 画面入力情報
const inputValues = json.view.state.values

// 投票者ユーザー情報
const voterInfo = getUserInfo(json.user.id)

// 得票者ユーザー情報
const voteGetterInfo = getUserInfo(inputValues.block_vote_getter.action_vote_getter.selected_user)

// 投票理由
const voterReason = inputValues.block_vote_reason.action_vote_reason.value

// 投票データ
const voteData = [
  voterInfo.id,//投票者:ID
  voterInfo.real_name,//投票者:氏名
  voteGetterInfo.id,//得票者:ID
  voteGetterInfo.real_name,//得票者:氏名
  voterReason, //投票理由
  Utilities.formatDate(new Date(), "Asia/Tokyo", "yyyy/MM/dd HH:mm:ss"),//投票日時
]

// 投票データをスプレッドシートに記録する
const sheetResult = SpreadsheetApp.openById(spreadSheetId).getSheetByName('集計');
sheetResult.appendRow(voteData)

ここまで実装が完了したら再度デプロイをして動作確認を行ってください。
投票確定ボタンを押したら入力内容がスプレッドシートに記録されるようになっている事が確認できるはずです。

第3回はここまでです。今回でおおよその機能が作り終わりました。
次回は仕上げとして投票完了画面の表示等を行います。

Discussion