【PHP】Google APIで口コミを取得する

Google APIで口コミを取得するお話

飲食店等を運営しているとGoogle先生の口コミが結構重要になるようです。

一店舗ならまだ手作業で頑張れそうですが複数店舗運営していると管理が大変。

ということで各店舗の口コミ一覧を取得しつつ返信してるかどうかまで確認できる仕組みを作成したいと思います。

参考サイト
https://notes.sharesl.net/articles/2527/

スポンサーリンク

API

まずは店舗データを管理しているGoogleアカウントでプロジェクトを作成しておきます。

Google Cloud Platform
Google Cloud Platform lets you build, deploy, and scale applications, websites, and services on the same infrastructure as Google.

下記リンクからAPIの利用申請をします。

Business Profile APIs: Application Form For Basic Access
The Business Profile APIs lets you programmatically manage your business information such as name, address, phone number, hours, photos, and more. Access to thi...

英語だらけで意味不明ですが翻訳しながらなんとかなりました。

申請してから数日後に確認のメールがくるので返信するとAPIが利用できるようになります。

APIが使えるようになったら利用するAPIを有効化します。

とりあえず下記があればなんとかなりそうでした。

Google My Business API
My Business Business Information API
My Business Account Management API

その他必要なものは適宜有効化しておくといいかもです。

それから下記ライブラリを入手しておく。

GitHub - googleapis/google-api-php-client: A PHP client library for accessing Google APIs
A PHP client library for accessing Google APIs. Contribute to googleapis/google-api-php-client development by creating an account on GitHub.

OAuth2.0の認証が必要なので下記を参考にトークンを取得。

【PHP】Google Business Profile APIを使ってクチコミを取得する|notes by SHARESL
Google Business Profile APIを使ってクチコミをPHPで取得する方法について。APIの利用申請やOAuth認証・クライアントライブラリを使ったPHPからAPIへのアクセス方法をサンプルコードをもとに説明しています。

一覧を取得するコードは下記を参照。

【PHP】Google Business Profile APIを使ってクチコミを取得する|notes by SHARESL
Google Business Profile APIを使ってクチコミをPHPで取得する方法について。APIの利用申請やOAuth認証・クライアントライブラリを使ったPHPからAPIへのアクセス方法をサンプルコードをもとに説明しています。

できあがったのがこんな感じ。

require_once 'vendor/autoload.php';
require_once 'MyBusiness.php';

// APIクライアントの作成
function getBpApiClient(){
  $client = new \Google\Client();
  $client->setApplicationName('my-google-reviews-app'); //アプリケーションの名前(任意・何でもOK)
  $client->setScopes(["https://www.googleapis.com/auth/plus.business.manage"]); // APIのスコープ
  $client->setAuthConfig('client_secret.json'); // 認証情報のJSONを読み込み
  // リフレッシュトークン用の設定
  $client->setAccessType('offline');
  $client->setApprovalPrompt('force');
  // トークンファイルがある場合はそこからアクセストークンを取得
  if (file_exists('my_token.json')) {
    $access_token = json_decode(file_get_contents('my_token.json'), true);
    $client->setAccessToken($access_token);
  }
  //トークンが期限切れの場合は再取得して設定
  if ($client->isAccessTokenExpired()) {
    $refresh_token = $client->getRefreshToken();
    $client->fetchAccessTokenWithRefreshToken($refresh_token);
    $access_token = $client->getAccessToken();
    $access_token['refresh_token'] = $refresh_token;
    $client->setAccessToken($access_token);
    // トークンの保存
    file_put_contents('my_token.json', json_encode($access_token));
  }
  return $client;
}

  $cflg="0";
  $client = getBpApiClient();
  if(empty($client)){
    return;
  }
  try{
    $account_service = new \Google_Service_MyBusinessAccountManagement($client);
    $account = $account_service->accounts->listAccounts()->getAccounts();
    $account_name = !empty($account[0]) ? $account[0]->getName() : null;
  }
  catch(Exception $e) {
    echo $e;
    return;
  }

global $db;
$sql = "select * from google_shop";
$google_shop = select_query($sql);
foreach($google_shop as $res){
  $shopcd  = $res["shopcd"];
  $shop_name  = $res["name"];
  $shop_name2  = $res["name2"];
  if($shop_name2==""){
    if($shop_name=="居酒屋〇〇"){
      try{
        $info_service = new \Google_Service_MyBusinessBusinessInformation($client);
        $accounts_locations = $info_service->accounts_locations->listAccountsLocations($account_name, [
          'readMask' => 'name,title,metadata',
          'filter'   => 'title='.$shop_name.' AND metadata.place_id='.$place_id
        ]);
      }
      catch(Exception $e) {
        echo $e;
        continue;
      }
    }else{
      try{
        $info_service = new \Google_Service_MyBusinessBusinessInformation($client);
        $accounts_locations = $info_service->accounts_locations->listAccountsLocations($account_name, [
          'readMask' => 'name,title,metadata',
          'filter'   => 'title='.$shop_name
        ]);
      }
      catch(Exception $e) {
        echo $e;
        continue;
      }
    }
  }else{
    try{
      $info_service = new \Google_Service_MyBusinessBusinessInformation($client);
      $accounts_locations = $info_service->accounts_locations->listAccountsLocations($account_name, [
        'readMask' => 'name,title,metadata',
        'filter'   => 'title='.$shop_name.' AND title='.$shop_name2
      ]);
    }
    catch(Exception $e) {
      echo $e;
      continue;
    }
  }
  $locations = $accounts_locations->getLocations(); //ロケーション情報を取得
  $location = !empty($locations[0]) ? $locations[0] : null;
  if(empty($location)){
    echo "empty";
    continue;
  }
  $location_name  = $location->getName();
  $batch_get_reviews_request = new Google_Service_MyBusiness_BatchGetReviewsRequest();
  // locationName
  $batch_get_reviews_request->setLocationNames(["${account_name}/${location_name}"]);
  $batch_get_reviews_request->setPageSize(50);
  //$batch_get_reviews_request->setIgnoreRatingOnlyReviews(true);
  $gmb_service = new \Google_Service_MyBusiness($client);
  $batch_get_reviews = $gmb_service->accounts_locations->batchGetReviews($account_name, $batch_get_reviews_request);
  $reviews_obj = $batch_get_reviews->getLocationReviews();
  $location_meta = $location->getMetadata();
  $place_id      = $location_meta->getPlaceId();
  $review_url    = "https://search.google.com/local/reviews?placeid=${place_id}";
  $reviews = $gmb_service->accounts_locations_reviews;
  $list_reviews_response = $reviews->listAccountsLocationsReviews("${account_name}/${location_name}", [
    'orderBy' => 'update_time desc'
  ]);
  $average_rating     = $list_reviews_response->getAverageRating();
  $total_review_count = $list_reviews_response->getTotalReviewCount();
  $sql="update
        google_shop
      set
        average_rating = ".$db->quoteSmart($average_rating).",
        count = ".$db->quoteSmart($total_review_count)."
      where
        shopcd = ".$db->quoteSmart($shopcd)."
    ";
  $db->query( $sql );
  $timezone = new DateTimeZone('Asia/Tokyo');
  foreach ((object)$reviews_obj as $r){
    $review = $r->getReview();
    $sql = "select * from google_api where reviewid = '".$review->getReviewId()."'";
    $api_data = select_query($sql);
    $dflg=0;
    foreach($api_data as $res){
      $dflg=1;
    }
    if($dflg==1){
      if($api_data[0]["reply"]==""){
        $dflg=2;
      }else{
        continue;
      }
    }
    $comment = $review->getComment();
    if(empty($comment)){
      $comment = "(評価のみ)";
    }
    if(strpos($comment,'(Translated by Google)') !== false){
      $n = strpos($comment,'(Translated by Google)');
      $comment = substr($comment, 0,$n);
    }
    if($comment==""){
      $comment="(評価のみ)";
    }
    $create_time = $review->getUpdateTime();
    $datetime    = new DateTimeImmutable($create_time, $timezone);
    $date        = $datetime->format('Y-m-d');
    $reviewer = $review->getReviewer();
    $rate        = $review->getStarRating();
    $rate_number = 0;
    switch ($rate){
      case 'ONE':
        $rate_number = 1;
        break;
      case 'TWO':
        $rate_number = 2;
        break;
      case 'THREE':
        $rate_number = 3;
        break;
      case 'FOUR':
        $rate_number = 4;
        break;
      case 'FIVE':
        $rate_number = 5;
        break;
      default:
        $rate_number = 0;
    }
    $reply = $review->getReviewReply();
    $reply_comment = !empty($reply) ? $reply->getComment() : "";
    if($dflg==2){
      if($reply_comment==""){
      }else{
          $sql = "update google_api set
              reply = ".$db->quoteSmart($reply_comment)."
            where
              reviewid = ".$db->quoteSmart($review->getReviewId())."
            ";
        $db->query( $sql );
      }
    }else{
      $sql = "insert into
              google_api(
                adate,
                shopcd,
                reviewid,
                cdate,
                name,
                comment,
                rating,
                reply
              )
              values
              (
              sysdate(),
              ".$db->quoteSmart($shopcd).",
              ".$db->quoteSmart($review->getReviewId()).",
              ".$db->quoteSmart($date).",
              ".$db->quoteSmart($reviewer->getDisplayName()).",
              ".$db->quoteSmart($comment).",
              ".$db->quoteSmart($rate_number).",
              ".$db->quoteSmart($reply_comment)."
              )
            ";
      $db->query( $sql );
      }
  }
}

filterの部分がなかなか手ごわい感じで、例えば居酒屋〇〇、居酒屋〇〇2号店、という感じで登録しているとうまく取得できなくなる。

居酒屋〇〇 2号店、みたいにスペースを使って登録しておくとANDを使うことができるのだけれど今回はそれが許されず四苦八苦した結果、下記のように「place_id」が使えることがわかりました。

        $accounts_locations = $info_service->accounts_locations->listAccountsLocations($account_name, [
          'readMask' => 'name,title,metadata',
          'filter'   => 'title='.$shop_name.' AND metadata.place_id='.$place_id
        ]);

place_idは下記とかで取得できます。

Place ID Finder  |  Maps JavaScript API  |  Google for Developers

これをCronで1時間に1回とか回せば最新の口コミ情報+返信したかどうかのデータが取得できるようになりました。

コメント

タイトルとURLをコピーしました