admin管理员组

文章数量:1530251

一:概述

  • 谷歌接口文档官方地址:https://developers.google/webmaster-tools/v1/api_reference_index
  • 对接功能说明:OAuth授权、资源(网站)增删改查、站点地图增删改查、站点效果分析
  • 控制台地址:https://console.developers.google/

二: 准备工作

  • 1.创建谷歌应用
  • 2.在应用内,启用需要的api
  • 3.创建OAuth客户端ID
  • 4.Oauth同意屏幕提交审核
注意:Oauth同意屏幕审核通过之前,接口也是可以使用的,但是在授权的时候,谷歌的授权屏幕会有安全提示

2.1 创建谷歌应用



2.2启用必要的api

以下两个api点击启用。

2.3 创建凭据


下载下来备用

2.4 OAuth同意屏幕

1.主要是告诉谷歌你调用接口的网站域名
2.点击 添加或移除范围 按钮,会列出启用的api对应的范围,选中自己需要的
3.配置应用上线之前,可以访问应用的谷歌账户
这些都完成之后,基本信息就填写完成了。点击发布应用,进入发布的相关流程

备注:测试阶段,也是可以正常调用接口的,但是授权的时候会有未验证的提示信息,点击下面的继续就可以

三:开始

3.1 composer 包安装

  • 扩展包地址:https://github/googleapis/google-api-php-client
  • 说明:国内会有时下载不下来,如果长时间下载不下来,可以打包下载,放在vendor目录里面,然后执行composer dumpautoload 自动加载

3.2 基本逻辑说明

添加网站资源的逻辑顺序

  1. 正确范围的授权成功
  2. 获取meta标签
  3. meta标签加到网站下
  4. 验证meta标签
  5. 添加网站

删除网站资源的逻辑顺序

1.删除网站的meta标签
2.删除网站验证的资源
3.删除网站

3.3 开发

我使用的是hyperf框架进行开发的,涉及到配置文件,获取类等不同的框架会有不同的写法,大家根据自己的现状进行修改

  1. 设置谷歌配置文件
  2. 谷歌客户端类
  3. 基础父类
  4. OAuth操作类
  5. SiteVerification操作类
  6. Site网站操作类
  7. SiteMap操作类

1.设置谷歌配置文件

declare(strict_types=1);

$client_secret = '上面下载下来备用的文件内容';
return [
    'auth_config' => json_decode($client_secret, true),
    'redirect_url' => '谷歌回调链接,与谷歌项目中配置的要一致'
];

2. 谷歌客户端类

<?php

declare(strict_types=1);

namespace App\Common;

use Hyperf\Utils\ApplicationContext;

class GoogleClient
{

    const SCOPES = [
        \Google_Service_Oauth2::OPENID,
        \Google_Service_Oauth2::USERINFO_EMAIL,
        \Google_Service_Oauth2::USERINFO_PROFILE,
        \Google_Service_SiteVerification::SITEVERIFICATION,
        \Google_Service_Webmasters::WEBMASTERS
    ];
    public static function getInstance()
    {
        $instance = ApplicationContext::getContainer()->get(\Google_Client::class);
        $instance->setAuthConfig(config('google.auth_config'));
        $instance->setRedirectUri(config('google.redirect_url'));
        $instance->addScope(self::SCOPES);
        $instance->setAccessType('offline');
        $instance->setApprovalPrompt("force");
        $instance->setIncludeGrantedScopes(true);
        return $instance;
    }
	//从token中获取用户已同意授权的权限列表
    public static function getGrantScopes(array $accessToken)
    {
        $scope = $accessToken['scope']??'';
        return explode(' ',$scope);
    }

}

3.基础父类

<?php
declare(strict_types=1);

namespace App\Utils\Google;


use App\Common\Log;
use App\Constants\ErrorCode;

class Base
{

    protected function getWebMaster($token)
    {
        $client = new \Google_Client();
        $client->setAccessToken($token);
        $webMaster = new \Google_Service_SearchConsole($client);
        return $webMaster;
    }

    protected function errorHandle(\Throwable $e,$mark)
    {
        $error = json_decode(stripslashes($e->getMessage()),true);
        Log::getInstance()->error($mark,['error'=>$e->getMessage(),'code'=>$e->getCode(),'trace'=>$e->getTrace()]);
        $message = $error['error']['message']??ErrorCode::HANDLE_ERROR;
        $code = $error['error']['code']??'';
        if(!in_array($code,[404,403])){
            throws_rpc($message);
        }

    }
}

4.OAuth操作类

<?php

declare(strict_types=1);

namespace App\Utils\Google;

use App\Common\FactoryTrait;
use App\Common\GoogleClient;
use App\Common\Log;
use Google\Service\Oauth2;

class OAuth
{
    use FactoryTrait;

    public function createAuthUrl($state)
    {
        $client = GoogleClient::getInstance();
        $client->setState($state);
        return $client->createAuthUrl();
    }

    public function getProfileByCode($code)
    {
        $client = GoogleClient::getInstance();
        $client->authenticate($code);
        $accessToken = $client->getAccessToken();
        Log::getInstance()->info("google_access_token",[$accessToken]);

       // $client->setAccessToken($accessToken);

        $error ='';
        if(is_array($accessToken)&&!isset($accessToken['error'])){
            $userInfo = (new Oauth2($client))->userinfo->get([]);
            if(get_class($userInfo)==Oauth2\Userinfo::class){
                $googleUser = [
                    'open_id' => $userInfo->getId(),
                    'email' => $userInfo->getEmail(),
                    'name' => $userInfo->getName(),
                    'picture' => $userInfo->getPicture(),
                    'token' => $accessToken['access_token'],
                    'refresh_token' => $accessToken['refresh_token'],
                    'detail' => json_encode($accessToken),
                    'code' => $code
                ];
                Log::getInstance()->info('谷歌回调中获取谷歌用户信息',['googleUser'=>$googleUser]);
            }else{
                $error = 'Failed to obtain user information after verifying code in Google callback';
                Log::getInstance()->error("谷歌回调中验证code后获取用户信息失败",[$userInfo]);
            }

        }else{
            $error = 'Failed to verify code'.$accessToken['error']??'';
            Log::getInstance()->error($error);
        }

        return [
            'error' => $error,
            'googleUser' => $googleUser??[]
        ];
    }

    public function getToken(array $accessToken)
    {
        $client = GoogleClient::getInstance();
        $client->setAccessToken($accessToken);
        $refreshed = false;
        if($client->isAccessTokenExpired()){
            $accessToken = $client->fetchAccessTokenWithRefreshToken();
            $refreshed = true;
        }

        $return = [
            'refreshed' => $refreshed,
            'accessToken' => $accessToken
        ];

        Log::getInstance()->info("google token refresh result",['params'=>func_get_args(),'result'=>$return]);
        return $return;
    }
}

5.SiteVerification操作类

这个部分在开发的时候我是实际调用的其他服务封装好的,下面的例子是练手,未验证。如果使用的话还需要再调试一下。

<?php

declare(strict_types=1);

namespace App\Utils\Google;

use Google\Service\SiteVerification as GoogleSiteVerification;
use Google\Service\SiteVerification\SiteVerificationWebResourceGettokenRequest;
use Google\Service\SiteVerification\SiteVerificationWebResourceResource;

class SiteVerification extends Base
{
    protected $mark = 'GOOGLE_SITE_VERIFICATION';

    public function getMeta($token,$domain)
    {
        try{
            $client = new \Google_Client();
            $client->setAccessToken($token);

            $request = new SiteVerificationWebResourceGettokenRequest();
            //参数可能有层级调整
            $response = (new GoogleSiteVerification($client))->webResource->getToken($request,[
                'verificationMethod' => 'META',
                'site' =>[
                    'identifier' => $domain,
                    'type' => 'SITE'
                ]
            ]);
            $meta = $response->getToken();
        }catch (\Throwable $e){
            $this->errorHandle($e,$this->mark);
        }

        return $meta;
    }

    public function insertResource($token,$domain)
    {
        try{
            $client = new \Google_Client();
            $client->setAccessToken($token);

            $request = new SiteVerificationWebResourceResource();
            $response = (new GoogleSiteVerification($client))->webResource->insert("META",$request,[
                'site' =>[
                    'identifier' => $domain,
                    'type' => 'SITE'
                ]
            ]);
            $resourceId = $response->getId();
        }catch (\Throwable $e){
            $this->errorHandle($e,$this->mark);
        }


        return $resourceId;
    }

    public function deleteResource($token,$domain)
    {
        try{
            $client = new \Google_Client();
            $client->setAccessToken($token);

            (new GoogleSiteVerification($client))->webResource->delete($domain);

        }catch (\Throwable $e){
            $this->errorHandle($e,$this->mark);
        }
        return true;
    }
}

6.Site网站操作类

<?php

declare(strict_types=1);

namespace App\Utils\Google;


use App\Common\FactoryTrait;
use App\Common\Log;

class Site extends Base
{
    use FactoryTrait;

    private $mark = 'GOOGLE_SEARCH_CONSOLE_SITE';

    //https://developers.google/webmaster-tools/v1/sites
    public function add($token,$domain)
    {
        try{
            $webMaster = $this->getWebMaster($token);
            $result = $webMaster->sites->add($domain);
            Log::getInstance()->info("search console add site result",['params'=>func_get_args(),'result'=>$result]);
        }catch (\Throwable $e){
            $this->errorHandle($e,$this->mark);
        }
        return true;
    }

    public function delete($token,$domain)
    {
        try{
            $webMaster = $this->getWebMaster($token);
            $result = $webMaster->sites->delete($domain);
            Log::getInstance()->info("search console delete site result",['params'=>func_get_args(),'result'=>$result]);
        }catch (\Throwable $e){
            $this->errorHandle($e,$this->mark);
        }
        return true;
    }

    public function get($token,$domain)
    {
        try{
            $webMaster = $this->getWebMaster($token);
            $result = $webMaster->sites->get($domain);
            Log::getInstance()->info("search console get site result",['params'=>func_get_args(),'result'=>$result]);
        }catch (\Throwable $e){
            $this->errorHandle($e,$this->mark);
        }
        return $result;
    }

    public function list($token)
    {
        try{
            $webMaster = $this->getWebMaster($token);
            $result = $webMaster->sites->listSites();
            Log::getInstance()->info("search console list site result",['params'=>func_get_args(),'result'=>$result]);
        }catch (\Throwable $e){
            $this->errorHandle($e,$this->mark);
        }
        return $result;
    }

}

7.SiteMap操作类

<?php

declare(strict_types=1);

namespace App\Utils\Google;

use App\Common\FactoryTrait;
use App\Common\Log;
use App\Constants\ErrorCode;

class SiteMap extends Base
{
    use FactoryTrait;

    private $mark = 'GOOGLE_SEARCH_CONSOLE_SITE_MAP';
    //提交站点地图
    public function submit($token,$domain,$path)
    {
        try{
            $webMaster = $this->getWebMaster($token);
            $result = $webMaster->sitemaps->submit($domain,$path);
            Log::getInstance()->info("search console add site map result",['params'=>func_get_args(),'result'=>$result]);
        }catch (\Throwable $e){
            $this->errorHandle($e,$this->mark);
        }
        return true;
    }
    //返回值里面的状态及其他信息
    public function lists($token,$domain)
    {
        Log::getInstance()->info("获取站点地图",['params'=>func_get_args()]);
        try{
            $webMaster = $this->getWebMaster($token);
            $response = $webMaster->sitemaps->listSitemaps($domain);
            $siteMapList = $response->getSitemap();
            Log::getInstance()->debug("站点地图列表",$siteMapList);
            if($siteMapList&&is_array($siteMapList)){

                foreach ($siteMapList as &$map){

                    if($map->getLastDownloaded()!==null){
                        $lastDownloaded = substr($map->getLastDownloaded()??'',0,10);
                        $lastDownloaded = date('Y年m月d日',strtotime($lastDownloaded));
                        $map->setLastDownloaded($lastDownloaded);
                    }

                    if($map->getLastSubmitted()!==null){
                        $lastSubmitted = substr($map->getLastSubmitted()??'',0,10);
                        $lastSubmitted = date('Y年m月d日',strtotime($lastSubmitted));
                        $map->setLastSubmitted($lastSubmitted);
                    }

                }

            }

        }catch (\Throwable $e){
            $message = json_decode($e->getMessage(),true);
            Log::getInstance()->error("获取站点地图列表遇到了错误",['message'=>$message?:$e->getMessage()]);
            $code = $message['error']['code'];
            $message = ErrorCode::SITE_MAP_CODE[$code]??($message['error']['message']??ErrorCode::SITE_MAP_ERROR);
            throws_rpc($message);
        }
        return $siteMapList;
        //返回数据说明,没有成功收录与排除的数量
        //https://developers.google/webmaster-tools/search-console-api-original/v3/sitemaps#resource
    }

    //获取站点地图详情
    public function get($token,$domain,$path)
    {
        Log::getInstance()->info("站点地图详情参数",['params'=>func_get_args()]);
        try {
            $webMaster = $this->getWebMaster($token);
            $response = $webMaster->sitemaps->get($domain, $path);//http://www.example/
            Log::getInstance()->info("站点地图详情结果",['result'=>$response]);
        }catch (\Throwable $e){
            $this->errorHandle($e,$this->mark);
        }
        return $response;
    }

    //删除站点地图详情
    public function delete($token,$domain,$path)
    {
        try {
            $webMaster = $this->getWebMaster($token);
            $webMaster->sitemaps->delete($domain, $path);//http://www.example/
        }catch (\Throwable $e){
            $this->errorHandle($e,$this->mark);
        }
        return true;
    }
}

后续更新效果查询部分。

PHP对接谷歌search console 第二篇

备注:若是感觉这篇文章对你有用,点个赞再走吧。如有疑问,欢迎批评指正、共同探讨。

本文标签: 第一篇PHPSearchConsole