1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

G Suiteの共有ドライブにgoogle/apiclient:"^2.0"(php)を利用して、APIのサービスアカウントでスプレッドシートを作成する

Last updated at Posted at 2019-09-06

PHP / Laravel / API / サービスアカウントで簡単にスプレッドシートを作りたい

Laravelフレームワーク環境下で、簡単にスプレッドシートを作ったり、更新したりできないものかと思いまして作成しました。
きっかけはスプレッドシートを活用して業務改善を行いたいというクライアントの要望になります。
G Suiteにはマイドライブと共有ドライブ(旧:チームドライブ)がありまして、共有ドライブに作る作り方がわからなかったので試行錯誤しました。

業務環境

  • GoogleのG Suite Businessエディションを利用中。
  • 共有ドライブが存在する。

Webアプリ環境

  • PHP 7.1
  • Laravel 5.5
  • Composerにて、google/apiclient:"^2.0" 導入

google/apiclient:"^2.0"

GoogleがPHPから簡単にAPIを利用できるように用意してくれているライブラリです。
https://github.com/googleapis/google-api-php-client

以下のコマンドで導入できます。

composer.phar require google/apiclient:"^2.0"

すでにPHPのパスが通っている場合は以下のコマンドだったり、
composer.phar require google/apiclient:"^2.0"

パスが通ってない場合は以下のコマンドだったり、
php ./composer.phar require google/apiclient:"^2.0"

Composerのbatがある場合は .phar を省略できたりと、様々です。
composer require google/apiclient:"^2.0"

本題

App\Services以下にサービスとして実装します。
APIを呼び出すにはGoogle_Clientが必要なので親サービスを作成して実装しました。

Google API Consoleでプロジェクトを作成して、認証情報でサービスアカウントを作成します。
この解説はたくさんネット上に出てるので省略します。

サービスアカウントを作成した時にダウンロードできる認証情報jsonを定数CREDENTIALS_PATH にセットしています。
ここではstorageディレクトリ以下にtest_api_credentialディレクトリを作成してその中に設置しています。

あらかじめ共有ドライブ内にAPP_DATAフォルダを作成し、フォルダIDを取得しておきます。
定数APP_DATAに共有ドライブのフォルダIDをセットします。

AbstractGoogleService

API共通で使える親サービスを作成します。

<?php

namespace App\Services;

use Google_Client;

class AbstractGoogleService
{
    /**
     * @var Credentials json
     */
    const CREDENTIALS_PATH = __DIR__ . '/../../storage/test_api_credential/test api-xxxxxxxxxxxx.json';

    /**
     * @var 共有ドライブのフォルダID
     */
    const APP_DATA = '0BC0P_ZneDOxfUk9PVB';

    /**
     * @var Google_Client
     */
    protected $client;

    /**
     * constructer
     */
    public function __construct()
    {
        putenv('GOOGLE_APPLICATION_CREDENTIALS=' . self::CREDENTIALS_PATH);

        $this->client = new Google_Client();
        $this->client->useApplicationDefaultCredentials();
    }
}

色々やってみたのですが、直接、共有ドライブにスプレッドシートは作成できないようです。
ですので、マイドライブにスプレッドシートを作成し、
そのマイドライブのスプレッドシートを共有ドライブにコピーして、
マイドライブのスプレッドシートを削除します。

結果的に、共有ドライブにスプレッドシートを作成することができます。

なんとも手間のかかる、、、

GoogleSheetsService

以下は、スプレッドシートタイトルをセットして、マイドライブにスプレッドシートを作成し、
スプレッドシートIDを返すメソッドです。
Google Sheets APIで実現しています。

<?php

namespace App\Services;

use App\Services\AbstractGoogleService;
use Google_Service_Sheets;
use Google_Service_Sheets_Spreadsheet;

class GoogleSheetsService extends AbstractGoogleService
{
    /**
     * @var Google_Service_Sheets
     */
    private $service;

    /**
     * constructer
     */
    public function __construct()
    {
        parent::__construct();
        $this->client->addScope(Google_Service_Sheets::SPREADSHEETS);

        $this->service = new Google_Service_Sheets($this->client);
    }

    /**
     * スプレッドシートをマイドライブに作成する
     *
     * @param string|null $title スプレッドシートタイトル
     * @return string Spreadsheet ID
     */
    public function create($title = null)
    {
        // スプレッドシートタイトルをセットする
        $spreadsheet = new Google_Service_Sheets_Spreadsheet([
            'properties' => [
                'title' => $title
            ],
        ]);

        // スプレッドシートをマイドライブに作成する
        $spreadsheet = $this->service->spreadsheets->create($spreadsheet, [
            'fields' => 'spreadsheetId',
        ]);

        return $spreadsheet->spreadsheetId;
    }
}

GoogleDriveService

次はGoogle Drive APIです。
ここでコピーと削除を行っています。

<?php

namespace App\Services;

use App\Services\AbstractGoogleService;
use Google_Service_Drive;
use Google_Service_Drive_DriveFile;

class GoogleDriveService extends AbstractGoogleService
{
    /**
     * @var Google_Service_Drive
     */
    private $service;

    /**
     * constructer
     */
    public function __construct()
    {
        parent::__construct();
        $this->client->addScope(Google_Service_Drive::DRIVE);

        $this->service = new Google_Service_Drive($this->client);
    }

    /**
     * 指定したファイルIDで共有ドライブに移動する
     *
     * @param $fileId ファイルID
     * @param $folderId フォルダID
     * @return string Move File
     */
    public function move($fileId, $folderId)
    {
        // 削除用にマイドライブのファイルIDの親IDを取得
        $file = $this->service->files->get($fileId, [
            'supportsAllDrives' => true,
            'fields' => 'parents',
        ]);
        $previousParents = implode(',', $file->parents);

        // 共有ドライブにファイルをコピーして、マイドライブにあるファイルを削除する
        $emptyFileMetadata = new Google_Service_Drive_DriveFile();
        $moveFile = $this->service->files->update($fileId, $emptyFileMetadata, [
            'supportsAllDrives' => true,
            'addParents' => $folderId,
            'removeParents' => $previousParents,
            'fields' => 'name, id, parents',
        ]);

        return sprintf("Move File: %s (%s) Folder: %s", $moveFile->name, $moveFile->id, implode(',', $moveFile->parents));
    }
}

ApiController

作成したサービスをコントローラーから呼び出します。


<?php

namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Services\GoogleDriveService;
use App\Services\GoogleSheetsService;

class ApiController extends Controller
{
    /**
     * G Suite APIサンプル
     *
     * @param 
     * @return 
     */
    public function api(
        Request $request,
        GoogleDriveService $googleDriveService,
        GoogleSheetsService $googleSheetsService
    ) {
        /**
         * スプレッドシートを共有ドライブに作成する
         */
        // スプレッドシートをマイドライブに作成する
        $title = 'スプレッドシート' . date('Y-m-d H:i:s');
        $spreadsheetId = $googleSheetsService->create($title);

        // 指定したスプレッドシートIDで共有ドライブに移動する
        $moveString = $googleDriveService->move($spreadsheetId, GoogleDriveService::APP_DATA);
    }
}

ルーティング

Laravelのルーティングはroutes\web.phpですね。
URLで呼び出せるようにルーティングします。


Route::get('/api', 'ApiController@api')->name('api');

動作確認

http://127.0.0.1/api
http://localhost/api
http://your_settei_sita_domain/api
など設定したドメインでアクセスします。

  • マイドライブにスプレッドシートが作成されていないこと。
  • 共有ドライブにスプレッドシートが作成されていること。

が確認できると思います。

1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?