『7回目の出直し🌻』

好きなことを自分のペースで、のんびり更新

GoogleのIndexing APIを使って、ブログの更新を通知する(1)準備まで

Google Indexing APIを使って、ブログのURLを直接Googleに伝えよう!

注意
2024年9月にIndexing APIに変更がありました。使い方を間違えるとスパム扱いするとGoogleのドキュメントに明記されましたのでお気をつけください。この記事はルール変更前に書かれたものです。

Index登録を自動化

前回の実験で、Search Consoleから手作業でURL単位の更新リクエストを送ると、Googleのクローラーがタイムリーな感じでクローリングしてくれることがわかりました。リクエストから5分~10分くらいで見に来てくれました。これを使わない手はない!

ただ、150個もあるURLをちくちく手作業でやってられないのですね。ということで、ここはプログラムの出番です。
自作のプログラムからGoogle Indexing APIを呼び出し、自動的に更新リクエストを投げ込むことにします。

参考にするドキュメント

https://developers.google.com/search/apis/indexing-api/v3/prereqs

前準備が長いので、APIが使えるところまでを記事にします。プログラム作成は次の機会に

注意事項

Google Indexing APIは、特殊なデータが埋め込まれたページで使えると書いてありました。

現在、Indexing API は、JobPosting または BroadcastEvent が VideoObject に埋め込まれたページをクロールするためにのみ使用できます。

ダメ元でAPIを呼び出してみたら、クローラーがやってきてインデックスが更新されました。
公式に使えるようになったのか、たまたま使えたのかは未確認事項です。今後もずっと使い続けることができるのかは分かりません。悪い影響があっても責任は取れませんのでご注意ください。

はまりポイント

最近はサーチコンソールからオーナーとして登録できるようになっているので、旧ウェブマスターツールを使わなくてもゴールまでいけます。この部分は読み飛ばしてよいです。

Google Search Consoleが新しくなったため、ドキュメント通りにやっても上手くいかないところがあります。その部分だけは旧版のウェブマスターセントラルで実施する必要があります。

画面には「確認済みのプロパティ」というのが無かったので、おかしいとは思ったのですが全く気が付かず。どうやっても403 Forbiddenが返ってきてしまい、諦めかけたところでこの記事に出会いました。
https://qiita.com/kuro96al/items/b9552d8f2c998fa84d43

Google Inedx APIで、[ドキュメントどおりに所有者設定](https://developers.google.com/search/apis/indexing-api/v3/prereqs#verify-site)をしたにも関わらず、https://indexing.googleapis.com/v3/urlNotifications:publish から 403 Forbiddenが返ってきてしまう場合は、Webmaster Tool(ウェブマスターツール/ウェブマスターセントラル)で「確認済みのプロパティ」を設定する必要があります!

助かった、ありがとうございます。

使うもの

今回、前準備段階で使うのはこの2つです

  • Google Index API
  • Google API Console or Cloud Console

APIを使えるところまでの準備

スクショがいっぱいなので本文は長いですが、内容は簡単です。

Google API Consoleでの作業

まずはAPIの準備です。
今回はIndexing API用のプロジェクトを作って、新規のプロジェクトに対してサービスアカウントの設定も行います。
既存のプロジェクトを持っている人は、適当に読み替えながら進んでください。

新しいプロジェクトを作る


https://console.developers.google.com/apis/dashboard で作業します

リソースの管理画面へ行き、「プロジェクトを作成」を押す

新しいプロジェクトの設定画面。名前とプロジェクトIDはお好みで入力して「作成」ボタン

Index APIを有効にする

プロジェクトができたら、プロジェクトにAPIを追加します。

APIの選択画面で、「Index API」を探して

有効にするボタンを押し

プロジェクトでIndexAPIが使えるようになります

サービスアカウントの追加

次は、プロジェクトにサービスアカウントを追加します。

左メニューの「認証情報」から画面を開きます。

まだ何もない状態です。
画面上にある「認証情報を作成」を押し、「サービスアカウント」を選ぶと設定画面が出てきます。

赤枠はお好みで入力してください。終わったら「続行」ボタンを押し

次の画面は権限の設定です。オーナーに設定し「続行」

ステップ3は、何もせずに完了します

ここまででサービスアカウントが1つ追加できた状態です。

サービスアカウントに認証キーを設定

作ったサービスアカウントの編集ボタンを押し

編集画面が開きます。上段、中段は変更なしでよくて、一番下までいきます

鍵を追加>新しい鍵を作成で

JSONを選んで「作成」ボタン

ダイアログが閉じてJSON形式のファイルが落ちてきます。このファイルはあとで使います。

これでサービスアカウントの設定は終わりです。

Search Consoleとウェブマスターツール

対象となるドメインのサーチコンソールを開き、サービスアカウントをオーナー登録します。

サービスアカウントのメールアドレスを確認

作成したJSONファイルの中にメールアドレスが入っています。必要になるのでメモしておきます。

JSONファイルにあるclient_emailの値です。

{
  "type": "service_account",
  "project_id": "",
  "private_key_id": "",
  "private_key": "-----BEGIN PRIVATE KEY-----
\n-----END PRIVATE KEY-----\n",
  "client_email": "★★ここです",
  "client_id": "",
  "auth_uri": "",
  "token_uri": "",
  "auth_provider_x509_cert_url": "",
  "client_x509_cert_url": ""
}

サーチコンソールの設定画面へ

左ナビゲーションの設定メニューを押し

設定画面の上部にあるユーザと権限をクリック

ユーザ追加

右上のユーザーを追加ボタンを押し、新規追加ダイアログを出す。

新規追加ダイアログ

  • メールアドレス欄に、上で控えたサービスアカウントのメールアドレス
  • 権限は、オーナーを選択

最後に追加を押します。

これで、オーナーがひとり増えていれば完成です。

(旧手順)ウェブマスターツール

こののやり方は古いです。2022年10月時点では使いません。

次は、サイト側の設定をします。Indexing APIドキュメントのこの部分です。

ウェブマスターツールにログイン

2の部分です。
ドキュメントだとサーチコンソールになっていますが、ウェブマスターツールに入ります。2020年6月20日時点ではサーチコンソールではできません。

ウェブマスターツールはここから↓
https://www.google.com/webmasters/verification/home?hl=ja

2021年9月追記

サーチコンソールから、ウェブマスターツールに行くことができるようになっていました。 複数人いる場合は誰のところでもよいので、三点オプションを触って「プロパティ所有者の管理」を押します。

手順

自分の管理したいドメインが出ているはずなので、「詳細の確認」を押します

画面下のほうのサイト管理者欄にある、ボタンを押します

メールアドレスの入力欄が出てくるので、前の手順で作ったサービスユーザのメールアドレスを入れます。
入力したメールアドレスを忘れてしまった場合は、ダウンロードしたJSONファイルから探しましょう。

JSONファイルにあるclient_emailの値です。

{
  "type": "service_account",
  "project_id": "",
  "private_key_id": "",
  "private_key": "-----BEGIN PRIVATE KEY-----
\n-----END PRIVATE KEY-----\n",
  "client_email": "★ここです",
  "client_id": "",
  "auth_uri": "",
  "token_uri": "",
  "auth_provider_x509_cert_url": "",
  "client_x509_cert_url": ""
}

画面が切り替わり、2人目ができてればOKです

サーチコンソール

サーチコンソールでは作業はありません。確認のみです。

左側の設定メニューからユーザ権限の一覧へ行って

2人目のサービスアカウントがオーナーとして登録されていることを確認です

まとめ

今回は下準備までのため、ここで終わりです。認証のところで躓かなければもっと早く終わったのに。とっても疲れました。

次の記事では、ブログの全URLを拾ってきて、ゴリゴリとAPIにリクエストを投げるプログラムを作ります。

kanaxx.hatenablog.jp

参考資料

Index API クイックスタート
https://developers.google.com/search/apis/indexing-api/v3/quickstart

Google Search Consoleのコミュニティーのスレッド
- Index API: Permission denied. Failed to verify the URL ownership.
https://support.google.com/webmasters/thread/4763732?hl=en&msgid=6359270

ウェブマスターセントラル
https://www.google.com/webmasters/verification/home?hl=ja

Googleのコンソール
https://console.developers.google.com/apis/dashboard
https://console.cloud.google.com/apis/dashboard

 
`; const notFoundHTML =`

探してみましたが、記事が見つかりませんでした。
右のサイドバーの検索で見つかるかもしれません

`; redirectWhen404(myEndpoint,myKey, doRedirect); async function redirectWhen404(microCmsURL, microCmsKey, doRedirect){ let pathName = window.location.pathname; console.info('Hatenablog-redirect| path=%s', pathName); //previewは対象外 if( pathName == '/preview' || pathName == '_404'){ console.log('Hatenablog-redirect| %s is not supported this script.',pathName); return; } let notFoundPage = isThisPage404(); console.log('Hatenablog-redirect| 404=%s', notFoundPage); if( !notFoundPage ){ return; } //microCMSへの確認をするURLを選別 //apiの呼び出し回数が気にならなければ、条件なしでもよい。 //if( !pathName.startsWith('/entry/') && !pathName.startsWith('/archive/category/') ){ // console.log('Hatenablog-redirect| This page is not supported this script.'); // return; //} let div = document.querySelector('.entry-content'); let messageArea = div.getElementsByTagName('p')[0]; if(showMessage){ startWaiting(messageArea, waitingHTML); } let apiResult = await findRedirectPath(pathName); console.log(apiResult); if(!apiResult){ //microCMS does not return 200 if(showMessage){ exitWaiting(messageArea, notFoundHTML, appendSearchForm); } }else if(apiResult.totalCount !=1){ console.log('Hatenablog-redirect| new Pathname is not found from api = %s', pathName); //行先のない404のとき //カスタム404っぽくするために、DOMをいじるならここでどうぞ if(showMessage){ exitWaiting(messageArea, notFoundHTML, appendSearchForm); } }else{ let newPathName = apiResult.contents[0].newPathName; console.info('Hatenablog-redirect|* Redirect to %s', newPathName); if(doRedirect){ //ここで転送 //http(s)から始まってるなら、そのまま転送してあげる if( newPathName.startsWith('http://') || newPathName.startsWith('https://') ){ window.location.href = newPathName; }else{ window.location.href = window.location.origin + newPathName; } } return; } async function findRedirectPath(pathName){ let parameter = `?fields=motoPathName,newPathName&filters=motoPathName[equals]${pathName}`; let url = microCmsURL + parameter; let config = { method: "GET", headers: { "Content-Type": "application/json; charset=utf-8", "X-MICROCMS-API-KEY": microCmsKey, }, }; let response = await fetch(url, config); if( response.status != 200){ console.error('microCMS returns status %s',response.status); return null; } let json = await response.json(); return json; } function getCanonical(){ var links = document.getElementsByTagName("link"); for ( i in links) { if (links[i].rel && links[i].rel.toLowerCase() == "canonical") { return links[i].href; } } return ""; } function isThisPage404(){ if( getCanonical() == "" ){ return true; } return false; } function startWaiting(element, html){ element.innerHTML = html; } function exitWaiting(element, html, appendForm){ //let divForm = document.querySelector('div#___gcse_0').cloneNode(true); //let f = divForm.querySelector('div.hatena-module-body').cloneNode(true); element.innerHTML = html; //if(appendForm && divForm){ // element.appendChild(divForm); //} } }
`; var time1 = articles[0].querySelector('time').dateTime; var time2 = articles[1].querySelector('time').dateTime; console.log('article1=%s/article2=%s', time1, time2); // if(articles[0].dataset.uuid < articles[1].dataset.uuid){ if(time1 < time2 || articles[0].dataset.uuid == articles[1].dataset.uuid){ articles[0].classList.add('fix-on-top-article') articles[0].insertAdjacentHTML('afterbegin',html); } console.info('fix-on-top/end'); } addCssClassToFixedArticle();