一:概述

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

二: 准备工作

  • 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.com/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. 谷歌客户端类

<?phpdeclare(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操作类

<?phpdeclare(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操作类

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

<?phpdeclare(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网站操作类

<?phpdeclare(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.com/webmaster-tools/v1/sitespublic 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操作类

<?phpdeclare(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.com/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.com/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.com/}catch (\Throwable $e){$this->errorHandle($e,$this->mark);}return true;}
}

后续更新效果查询部分。

PHP对接谷歌search console 第二篇

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

PHP对接谷歌search console 第一篇相关推荐

  1. 谷歌 console_使用Google Search Console有效增加网站流量的15条提示

    谷歌 console Google Search Console is a powerful free tool created by Google to help website owners un ...

  2. 技术小白成长之路 - 谷歌云端 GCP Cloud Engineering - 第一篇 - 核心架构 Core Infrastructure

    谷歌云端 GCP Cloud Engineering Certificate - 第一篇 - 核心架构 Core Infrastructure 谷歌云端平台GCP简介 1. 谷歌云端平台GCP资源层次 ...

  3. 我在CSDN的第一篇博客-iOS开发-关于Debug的一些技巧(NSLog方面)

    唠叨几句 本来想写点感言的,不过想了想觉得有点儿矫情,还是算了.开博客原因很简单,就是想锻炼一下自己表达能力,并且总结一些需要积累的东西. 第一篇博客,还是写点有用的东西吧. 刚刚看到的一篇关于Deb ...

  4. ROB 第一篇 DFS BFS (寻迹算法)

    ROB 第一篇 DFS & BFS DFS & BFS 简单介绍 原理 DFS BFS 总结 DFS & BFS 简单介绍 DFS (depth first search) 和 ...

  5. My 的第一篇博客!!!

    我的第一篇博客 一.序言 很早就考虑着要写博客了,在这之前都是停留在了想,前两天刚给自己换了个昵称----转正开始写博客!这个也是示意自己不要忘记,在B站上也听到很多次关于大佬讲到写博客的好处,凑着马 ...

  6. 微信小程序商城项目实战(第一篇:项目搭建与首页)

    商城项目第一篇 项目搭建 项目结构 编写整个项目中需要用到的功能 request.js 全局样式 组件(搜索框) 首页 代码编写 效果图 项目搭建 后端接口:https://www.showdoc.c ...

  7. Webpack系列-第一篇基础杂记

    系列文章 Webpack系列-第一篇基础杂记 Webpack系列-第二篇插件机制杂记 Webpack系列-第三篇流程杂记 前言 公司的前端项目基本都是用Webpack来做工程化的,而Webpack虽然 ...

  8. 国际化困境(第一篇)

    (和我前一篇文章一样,这篇文章也需要读者动手写些程序,参与其中,实验过程可能需要反复重启电脑,另外最好准备一套英文Windows系统,哦,如果再有一套Windows Vista英文版,那再好不过,总之 ...

  9. 微信公众号开发入门教程第一篇

    微信公众号开发入门教程第一篇 关键字:微信公众平台开发 作者:方倍工作室 在这篇微信公众平台开发教程中,我们假定你已经有了PHP语言程序.MySQL数据库.计算机网络通讯.及HTTP/XML/CSS/ ...

最新文章

  1. 我终于加上博士大佬的微信!攒了近百个技术问题,一口气解决!(文末有福利)...
  2. 逆水寒服务器新消息,游戏新消息:逆水寒太火爆服务器爆满王思聪都挤不进去...
  3. Altium Designer BGA扇出
  4. nvcc 已退出,返回代码为1
  5. 开放源代码GIS资源集锦
  6. ( ̄▽ ̄) 关于河北ETC记账卡的默认密码
  7. java异步线程内存可见性实验
  8. .net Redis缓存优化提高加载速度和服务器性能(二)
  9. 【Mac】mac下使用 找不到或无法加载主类
  10. 抖音春晚红包百亿互动量级背后,火山引擎浮出水面
  11. 诺基亚E63常见设置指南
  12. Coursera机器学习week11 笔记
  13. “天鹅”类谜解大全!-
  14. 求齐次线性方程组的基础解系matlab,MATLAB学习笔记:齐次线性方程组的基础解系...
  15. 数据防泄密软件可以解决哪些安全问题?
  16. 插画惯用风格_2020年最佳插画家的10种鼓舞人心的插画风格
  17. 锐龙r76800h和酷睿i512500h核显对比 r7 6800h和i5 12500h哪个好
  18. 佳能打印机手机显示未连接服务器失败,佳能打印机连不上手机
  19. java并发-java并发大师
  20. 指针及其应用4——结构体指针

热门文章

  1. 跟着 伍逸 老师学GDI+之Pen.DashCap、Pen.StartCap和Pen.EndCap属性
  2. Java之父呼吁大家弃用Java 8
  3. Java基础 - 坦克大战(第四章,线程基础)
  4. APP产品的数据分析体系
  5. 追剧必备电视盒子软件:电视家陪你一起追《谢谢你医生》
  6. 微信小程序视频上传案例
  7. 集美大学计算机专业2020,2020年集美大学计算机应用技术考研调剂
  8. 《硅谷钢铁侠》Elon Musk:“兄弟们,我觉得我们可以自己造火箭。”
  9. 智慧数字经营小程序存在的意义和价值分析
  10. 2018年4月高等教育国际金融全国统一命题考试