PHP で Google Drive API を使って、指定フォルダ配下のすべてのSpreadsheetにアクセスする

Google Cloud Platform が必要になる都度、お久しぶりで忘れていることも多いので、まとめ。

大まかな事前準備

  • GCPにプロジェクトがあれば選択。なければ作る
  • サービスキーを作成。JSONファイルを開発環境に配置(Gitには取り込まないよう注意)
  • 作成したキーに対して各サービスでアクセス権を付与
  • プロジェクトに必要なAPIを有効化する事も忘れずに

特に最後。プロジェクト内で該当のAPI(今回の場合、Google Drive APIやGoogle Sheets API)を有効にすることをお忘れなく。(よく忘れて “Access Not Configured. Drive API has not been used in project…. ” などで弾かれます(笑))

要はここで作ったサービスアカウント(ボット用のGアカウントのようなもの)を使って、各Googleのサービスにアクセスするイメージです。なので、Gドライブやアナリティクスなど、プログラムからアクセスする各サービス側にこのサービスアカウントへのアクセス権限を付与しておく必要があります。

GドライブからSpreadsheetを全て取得

$client = new Google_Client();

$key_file =  './key/ss.json'; // サービスキーのjsonファイル
$client->setAuthConfig($key_file);
$client->setScopes([
    \Google_Service_Drive::DRIVE, // Gドライブのスコープ
]);

$driveService = new \Google_Service_Drive($client);

$folderName = 'hogehoge_fugafuga'; // フォルダー名

$result = $driveService->files->listFiles([
    'q' => "name='$folderName'",
    "q" => "mimeType='application/vnd.google-apps.spreadsheet'", // Spreadsheetのみに限定する場合
]);

foreach ( $result->getFiles() as $file) {
    echo $file->getName() . "\n";
}

こんな感じですかね。

通常、フォルダ配下のすべてのファイルを探す場合、フォルダのファイルチェック処理を再帰的にコールしてサブフォルダーに深く潜って行くのですが、GドライブAPIの場合、検索の概念で、全階層から一発で必要なファイルがすべて取得できます。超楽です(*´∀`*)

ちなみに、フォルダー名はURLバーなどのこの部分。

Spreadsheetなどを開けば、この末尾はファイルIDになったりします。Gドライブ関連は、だいたい固有のIDがURLに含まれています。

Spreadsheetで各ファイルから値を取得する

サービスの複合利用する場合ですね。
これで動くけど、クライアントのスコープを増やして、サービスを取得するのでいいのかな。

$client = new Google_Client();

$key_file =  './key/ss.json'; // サービスキーのjsonファイル
$client->setAuthConfig($key_file);
$client->setScopes([
    \Google_Service_Sheets::SPREADSHEETS, // スプレッドシートのスコープ
    \Google_Service_Drive::DRIVE, // Gドライブのスコープ
]);

$driveService = new \Google_Service_Drive($client);
$sheetsService = new Google_Service_Sheets($client);

$folderName = 'hogehoge_fugafuga'; // フォルダー名

$list = $driveService->files->listFiles([
    'q' => "name='$folderName'",
    "q" => "mimeType='application/vnd.google-apps.spreadsheet'", // Spreadsheetのみに限定する場合
]);

foreach ( $list->getFiles() as $file) {
    echo $file->getName() . "\n";

    //1枚目のシート名の取得
    $spreadsheets = $sheetsService->spreadsheets->get($file->getId());
    $sheetTitle = $spreadsheets->getSheets()[0]->getProperties()->getTitle();

    //データを取得(A列だけ)
    $data = $sheetsService->spreadsheets_values->get($file->getId(), $sheetTitle . '!A:A');

    //データを取得(シート内の全データ)
    $allData = $sheetsService->spreadsheets_values->get($file->getId(), $sheetTitle );

    var_dump( $data );
    var_dump( $allData );
}

取得したデータは

こんな感じでデータが配列に格納されます。

Google_Service_Sheets_ValueRange::__set_state(array(
   'collection_key' => 'values',
   'majorDimension' => 'ROWS',
   'range' => '\'フォームの回答 1\'!A1:I103',
   'values' => 
  array (
    0 => 
    array (
      0 => 'タイムスタンプ',
      1 => '朝ごはんは食べますか?',
    ),
    1 => 
    array (
      0 => '2021/05/14 15:59:37',
      1 => 'はい',
    ),
    2 => 
    array (
      0 => '2021/05/14 16:00:07',
      1 => 'いいえ',
    ),
  ),
   'internal_gapi_mappings' => 
  array (
  ),
   'modelData' => 
  array (
  ),
   'processed' => 
  array (
  ),
))

あとは自由に調理するだけ。