開発情報・ナレッジ

投稿者: ShiningStar株式会社 2024年7月5日 (金)

SPIRAL上でGoogleDriveのファイルをダウンロードし、DBへ格納する方法

SPIRALのカスタムプログラムでGoogleDriveのファイルをダウンロードし、
SPIRALのDBへファイルを格納するサンプルプログラムをご紹介いたします。


全体像

GoogleDriveのAPIを用いてGoogleDrive内のファイルをダウンロードし、
そのファイルをSPIRALのAPIを用いてDBへアップロードします。

GoogleDriveのファイルをダウンロードするにはGoogleAPIのアクセストークンが必要なので取得します。
また、ダウンロードしたいファイルを指定するのにファイルIDも必要な為
GoogleDriveのAPIを用いてファイルIDを取得します。
ダウンロードが出来たらSPIRALのAPIを用いてファイルをアップロードします。

DB設定

任意のDBを作成し、ファイル型フィールドを用意してください。
この際ファイル型フィールドの差し替えキーワードを控えておいてください。
SPIRALのAPIの仕様上ファイル型フィールド以外にもう一つフィールドが必要なので、
登録日時フィールドを差し替えキーワードregistDateにして追加してください。

設定方法

Google側の設定(OAuth認証の作成)
Google側に任意のプロジェクトを作成していください。
その後Google側設定画面へアクセスしてください。
認証情報より「+認証情報を作成」をクリックして「OAuthクライアントID」をクリックしてください。
アプリケーションの種類は「ウェブアプリケーション」
承認済みのリダイレクトURIには「http://localhost/oauth2callback.php」と入力してください。
そのまま作成まで進み、モーダルに「クライアントID」と「クライアントシークレット」が表示されますので、必ず控えてください。

次に「OAuth同意画面」をクリックしてください。
「OAuth consent screen」では任意の情報を入力してください。
「スコープ」では何も入力しなくて大丈夫です。
「Test users」ではテストユーザにご自身のログインされているGoogleアカウント(Gmail)を入力してください。

ファイルのダウンロードをするにはアクセストークンが必要です。
しかし、アクセストークンには有効期限等があるので継続的にファイルのダウンロードが出来るように、
リフレッシュトークンを生成して、リフレッシュトークンからアクセストークンを都度生成する形にします。
設定値ファイルをカスタムモジュールに作成

<?php
$client_id = 'クライアントIDを入力';
$client_secret = 'クライアントシークレットを入力';
$redirect_uri = 'http://localhost/oauth2callback.php'; 
            

モジュール名をconfig.phpとしてカスタムモジュールに保存して上記を貼り付けてください。
その後ご自身のGoogleの接続情報を記載してください
ステップ1 リフレッシュトークンの取得

<?php
require_once "config.php";

$auth_code = ''; // 認証コードをここに入力

if (empty($auth_code)) {
    // 認証コードが入力されていない場合、認証URLを生成
    $auth_url = 'https://accounts.google.com/o/oauth2/auth?' . http_build_query([
        'client_id' => $client_id,
        'redirect_uri' => $redirect_uri,
        'response_type' => 'code',
        'scope' => 'https://www.googleapis.com/auth/drive.readonly',
        'access_type' => 'offline',
    ]);

    echo '認証URLをブラウザで開いて、認証コードを取得してください:';
    echo PHP_EOL . PHP_EOL;
    echo $auth_url . PHP_EOL;
} else {
    // 認証コードが入力されている場合、アクセストークンとリフレッシュトークンを取得
    $token_url = 'https://oauth2.googleapis.com/token';
    $post_fields = [
        'code' => $auth_code,
        'client_id' => $client_id,
        'client_secret' => $client_secret,
        'redirect_uri' => $redirect_uri,
        'grant_type' => 'authorization_code',
    ];

    $ch = curl_init($token_url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post_fields));

    $response = curl_exec($ch);

    if ($response === false) {
        echo 'Error: ' . curl_error($ch);
        curl_close($ch);
        exit();
    }

    curl_close($ch);

    $token_data = json_decode($response, true);
    var_dump($token_data);
}
?>
 
            

上記プログラムをカスタムプログラムに設置して実行してください。
そうすると認証URLが出力されますので、そのURLをブラウザに貼り付けて遷移してください。
遷移するとエラーが表示されると思いますが、大丈夫です。
リダイレクトされた後URLに
http://localhost/oauth2callback.php?code=XXX&scope=YYYY
といった形でcodeのパラメータが付与されていますので、
このcodeパラメータ「XXX」を$auth_codeに代入して再度実行してください。
実行結果より「refresh_token」の値を控えてください。
作成したカスタムモジュールを編集

<?php
$client_id = 'クライアントIDを入力';
$client_secret = 'クライアントシークレットを入力';
$redirect_uri = 'http://localhost/oauth2callback.php';

$refresh_token = "ステップ2で取得したリフレッシュトークンを入力"; 
            

$refresh_tokenの行を追記してください。
先ほど控えた値を$refresh_tokenの値に入力してください。
ステップ2 ファイルIDの取得

<?php
require_once "config.php";
$folder_id = ""; //フォルダIDを指定

$token_url = 'https://oauth2.googleapis.com/token';
$post_fields = [
    'refresh_token' => $refresh_token,
    'client_id' => $client_id,
    'client_secret' => $client_secret,
    'grant_type' => 'refresh_token',
];

$ch = curl_init($token_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post_fields));

$response = curl_exec($ch);
curl_close($ch);

$token_data = json_decode($response, true);
$access_token = $token_data['access_token'];

$folder_id = isset($folder_id) ? $folder_id : null;

// Google Drive APIを使用してファイルリストを取得
if ($folder_id) {
    // フォルダIDが存在する場合、フォルダ内のファイルを取得
    $drive_url = 'https://www.googleapis.com/drive/v3/files?q=' . urlencode("'" . $folder_id . "' in parents");
} else {
    // フォルダIDが存在しない場合、全てのファイルを取得
    $drive_url = 'https://www.googleapis.com/drive/v3/files';
}

$ch = curl_init($drive_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Authorization: Bearer ' . $access_token,
]);

$response = curl_exec($ch);

if ($response === false) {
    echo 'Error: ' . curl_error($ch);
    curl_close($ch);
    exit();
}

curl_close($ch);

$file_list = json_decode($response, true);
if (isset($file_list['error'])) {
    echo 'Error: ' . $file_list['error']['message'];
    exit();
}

// ファイルリストを表示
foreach ($file_list['files'] as $file) {
    echo 'File ID: ' . $file['id'] . ' - File Name: ' . $file['name'] . PHP_EOL;
}
?> 
            

上記プログラムをカスタムプログラムに設置して実行してください。
実行結果にファイルIDとファイル名が記載されますので、File ID:の後のIDを控えてください。
$file_list['files']にファイルのリストが格納されています。
フォルダの絞り込み等を行いたい場合は
$drive_url = 'https://www.googleapis.com/drive/v3/files?q=' . urlencode("'" . $folder_id . "' in parents");

の様な形でAPIの接続先にパラメータを付与してリクエストを行ってください
パラメータの仕様については下記Google公式リファレンスをご確認ください。
Method: files.list
ファイルやフォルダを検索する
ステップ3 ファイルダウンロード及びSPIRALへアップロード

<?php
//変更不要
require_once "config.php";
define("MULTIPART_BOUNDARY", "SPIRAL_API_MULTIPART_BOUNDARY");

// スパイラルAPI接続用設定値
define("API_TOKEN", "");
define("API_SECRET", "");
define("DB_TITLE", ""); //格納したいDBタイトル
define("RESIST_DATE_FIELD_NAME", "registDate"); //登録日時フィールド名
define("RESIST_DATE", "now"); //登録日時のvalue値
define("FILE_FIELD", "file"); //ファイル型フィールドの差し替えキーワード

$file_id = ''; //ステップ3で控えたfileId
$file_name = "image.png"; //ファイル名(拡張子をファイルと合わせてください)

// スパイラルAPIのURLを取得するための設定
$locator = "https://www.pi-pe.co.jp/api/locator";
$locator_token = API_TOKEN; // ロケータ用トークン

// ロケータのAPI用のHTTPヘッダ
$locator_headers = array(
    "X-SPIRAL-API: locator/apiserver/request",
    "Content-Type: application/json; charset=UTF-8",
);

// リクエストデータを作成
$locator_parameters = array();
$locator_parameters["spiral_api_token"] = $locator_token; // ロケータ用トークン

// JSON形式にエンコード
$locator_json = json_encode($locator_parameters);

// cURLでロケータURLを取得
$curl = curl_init($locator);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $locator_json);
curl_setopt($curl, CURLOPT_HTTPHEADER, $locator_headers);
$response = curl_exec($curl);

// エラーがあればエラー内容を表示
if (curl_errno($curl)) {
    echo curl_error($curl);
    exit;
}
$response_json = json_decode($response, true);
curl_close($curl);

// スパイラルAPIのURLを取得
$api_url = $response_json['location'];

// トークンを取得するためのURLとPOSTフィールド
$token_url = 'https://oauth2.googleapis.com/token';
$post_fields = [
    'refresh_token' => $refresh_token,
    'client_id' => $client_id,
    'client_secret' => $client_secret,
    'grant_type' => 'refresh_token',
];

// cURLでアクセストークンを取得
$ch = curl_init($token_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post_fields));
$response = curl_exec($ch);
curl_close($ch);

$token_data = json_decode($response, true);
$access_token = $token_data['access_token'];

// Google Driveからファイルをダウンロード
$download_url = "https://www.googleapis.com/drive/v3/files/{$file_id}?alt=media";
$ch = curl_init($download_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Authorization: Bearer ' . $access_token,
]);
$file_content = curl_exec($ch);
curl_close($ch);

// スパイラルAPI用のHTTPヘッダ
$api_headers = array(
    "X-SPIRAL-API: database/insert/request",
    "Content-Type: multipart/form-data; boundary=" . MULTIPART_BOUNDARY,
);

// 送信するJSONデータを作成
$parameters = array();
$parameters["spiral_api_token"] = API_TOKEN; // トークン
$parameters["db_title"] = DB_TITLE; // DBのタイトル
$parameters["passkey"] = time(); // エポック秒
$parameters["data"] = array(array("name" => RESIST_DATE_FIELD_NAME, "value" => RESIST_DATE));

// 署名を付ける
$key = $parameters["spiral_api_token"] . "&" . $parameters["passkey"];
$parameters["signature"] = hash_hmac('sha1', $key, API_SECRET, false);

// POSTデータを生成
$postdata = "--" . MULTIPART_BOUNDARY . "\r\n";
$postdata .= "Content-Type: application/json; charset='UTF-8';\r\n";
$postdata .= "Content-Disposition: form-data; name='json'\r\n\r\n";
$postdata .= json_encode($parameters);
$postdata .= "\r\n\r\n";
$postdata .= "--" . MULTIPART_BOUNDARY . "\r\n";
$postdata .= "Content-Type: application/octet-stream;\r\n";
$postdata .= "Content-Disposition: form-data; name=\"" . FILE_FIELD . "\"; filename=\"" . $file_name . "\"\r\n\r\n";
$postdata .= $file_content;
$postdata .= "\r\n\r\n";
$postdata .= "--" . MULTIPART_BOUNDARY . "--\r\n";

// curlライブラリを使って送信
$curl = curl_init($api_url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $postdata);
curl_setopt($curl, CURLOPT_HTTPHEADER, $api_headers);
$response = curl_exec($curl);
curl_close($curl);

// 結果を表示
echo mb_convert_encoding(print_r(json_decode($response, true), true), 'CP932', 'UTF-8');

?> 
            

上記プログラムをカスタムプログラムに設置して実行してください。
設定値をご自身の環境に合わせて修正してください。
$file_idにはステップ3で控えた値を入力してください。
修正が完了し、実行すると指定したファイルがSPIRALへアップロードされます。

その他

外部(Google)との連携になりますので、データの取扱や認証情報の取り扱いには十分お気をつけください。
特にクライアントIDやクライアントシークレット、認証キー等は他人に絶対に知られない様にしてください。
知られてしまうとGoogleアカウント上のデータが他人に操作、閲覧されてしまう可能性がございます。

解決しない場合はこちら コンテンツに関しての
要望はこちら