From 64ac7851c8504fb67dcdabf69d4207d2c3c24ff5 Mon Sep 17 00:00:00 2001 From: goenning Date: Wed, 24 Jan 2024 09:13:56 +0000 Subject: [PATCH] open source it --- .gitignore | 4 + LICENSE | 21 ++ README.md | 40 ++ output.png | Bin 0 -> 29205 bytes package-lock.json | 820 +++++++++++++++++++++++++++++++++++++++++ package.json | 15 + src/index.mjs | 108 ++++++ src/shared/auth.mjs | 22 ++ src/shared/gsc.mjs | 112 ++++++ src/shared/sitemap.mjs | 44 +++ src/shared/utils.mjs | 26 ++ 11 files changed, 1212 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 README.md create mode 100644 output.png create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 src/index.mjs create mode 100644 src/shared/auth.mjs create mode 100644 src/shared/gsc.mjs create mode 100644 src/shared/sitemap.mjs create mode 100644 src/shared/utils.mjs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7fea616 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +service_account.json +.cache +node_modules +.vscode \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..1705250 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 Guilherme Oenning + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..644f245 --- /dev/null +++ b/README.md @@ -0,0 +1,40 @@ +# Google Indexing Script + +Use this script to get your entire site indexed on Google in less than 48 hours. No tricks, no hacks, just a simple script and a Google API. + +You can read more about the motivation behind it and how it works on this blog post https://seogets.com/blog/google-indexing-script + +> [!IMPORTANT] +> This script uses [Google Indexing API](https://developers.google.com/search/apis/indexing-api/v3/quickstart). While there is no absolute guarantee that every page will be indexed, recent tests conducted in December 2023 have shown a notably high success rate. + +## Requirements + +- Install [Node.js](https://nodejs.org/en/download) +- An account on [Google Search Console](https://search.google.com/search-console/about) with the verified sites you want to index +- An account on [Google Cloud](https://console.cloud.google.com/) + +## Preparation + +1. Download or close this repository +2. Follow this [guide](https://developers.google.com/search/apis/indexing-api/v3/prereqs) from Google. By the end of it, you should have a project on Google Cloud with the Indexing API enabled, a service account with the `Owner` permission on your sites. +3. Download the JSON file with the credentials of the service account and save it in the same folder as the script. The file should be named `service_account.json` + +## Usage + +1. Open a terminal and navigate to the folder where you cloned repository +2. Run `npm install` to install the dependencies +3. Run `node run index ` to index all the pages of your site. Replace `` with your site domain. For example, if your site is `https://seogets.com`, you should run `node run index seogets.com` + +Here's an example of what you should expect: + +![](./output.png) + +**Important Notes:** + +- Your site must have 1 or more sitemaps submitted to Google Search Console. Otherwise, the script will not be able to find the pages to index. +- You can run the script as many times as you want. It will only index the pages that are not already indexed. +- Sites with a large number of pages might take a while to index, be patient. + +## 📄 License + +MIT License diff --git a/output.png b/output.png new file mode 100644 index 0000000000000000000000000000000000000000..f9cefc5af0baf34b3da1b3952579ae9c9445daac GIT binary patch literal 29205 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 Y*4=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, + "node_modules/@szmarczak/http-timer": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", + "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", + "dependencies": { + "defer-to-connect": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@types/cacheable-request": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz", + "integrity": "sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==", + "dependencies": { + "@types/http-cache-semantics": "*", + "@types/keyv": "^3.1.4", + "@types/node": "*", + "@types/responselike": "^1.0.0" + } + }, + "node_modules/@types/http-cache-semantics": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz", + "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==" + }, + "node_modules/@types/keyv": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", + "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/node": { + "version": "20.11.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.5.tgz", + "integrity": "sha512-g557vgQjUUfN76MZAN/dt1z3dzcUsimuysco0KeluHgrPdJXkP/XdAURgyO2W9fZWHRtRBiVKzKn8vyOAwlG+w==", + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@types/responselike": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.3.tgz", + "integrity": "sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/agent-base": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz", + "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==", + "dependencies": { + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/bignumber.js": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz", + "integrity": "sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==", + "engines": { + "node": "*" + } + }, + "node_modules/buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" + }, + "node_modules/cacheable-lookup": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", + "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==", + "engines": { + "node": ">=10.6.0" + } + }, + "node_modules/cacheable-request": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.4.tgz", + "integrity": "sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==", + "dependencies": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^4.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^6.0.1", + "responselike": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/call-bind": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", + "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", + "dependencies": { + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.1", + "set-function-length": "^1.1.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/clone-response": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz", + "integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==", + "dependencies": { + "mimic-response": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decompress-response/node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/defer-to-connect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", + "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", + "engines": { + "node": ">=10" + } + }, + "node_modules/define-data-property": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", + "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", + "dependencies": { + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gaxios": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-6.1.1.tgz", + "integrity": "sha512-bw8smrX+XlAoo9o1JAksBwX+hi/RG15J+NTSxmNPIclKC3ZVK6C2afwY8OSdRvOK0+ZLecUJYtj2MmjOt3Dm0w==", + "dependencies": { + "extend": "^3.0.2", + "https-proxy-agent": "^7.0.1", + "is-stream": "^2.0.0", + "node-fetch": "^2.6.9" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/gcp-metadata": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-6.1.0.tgz", + "integrity": "sha512-Jh/AIwwgaxan+7ZUUmRLCjtchyDiqh4KjBJ5tW3plBZb5iL/BPcso8A5DlzeD9qlw0duCamnNdpFjxwaT0KyKg==", + "dependencies": { + "gaxios": "^6.0.0", + "json-bigint": "^1.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", + "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", + "dependencies": { + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/google-auth-library": { + "version": "9.4.2", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.4.2.tgz", + "integrity": "sha512-rTLO4gjhqqo3WvYKL5IdtlCvRqeQ4hxUx/p4lObobY2xotFW3bCQC+Qf1N51CYOfiqfMecdMwW9RIo7dFWYjqw==", + "dependencies": { + "base64-js": "^1.3.0", + "ecdsa-sig-formatter": "^1.0.11", + "gaxios": "^6.1.1", + "gcp-metadata": "^6.1.0", + "gtoken": "^7.0.0", + "jws": "^4.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/googleapis": { + "version": "131.0.0", + "resolved": "https://registry.npmjs.org/googleapis/-/googleapis-131.0.0.tgz", + "integrity": "sha512-fa4kdkY0VwHDw/04ItpQv2tlvlPIwbh6NjHDoWAVrV52GuaZbYCMOC5Y+hRmprp5HHIMRODmyb2YujlbZSRUbQ==", + "dependencies": { + "google-auth-library": "^9.0.0", + "googleapis-common": "^7.0.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/googleapis-common": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/googleapis-common/-/googleapis-common-7.0.1.tgz", + "integrity": "sha512-mgt5zsd7zj5t5QXvDanjWguMdHAcJmmDrF9RkInCecNsyV7S7YtGqm5v2IWONNID88osb7zmx5FtrAP12JfD0w==", + "dependencies": { + "extend": "^3.0.2", + "gaxios": "^6.0.3", + "google-auth-library": "^9.0.0", + "qs": "^6.7.0", + "url-template": "^2.0.8", + "uuid": "^9.0.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/got": { + "version": "11.8.6", + "resolved": "https://registry.npmjs.org/got/-/got-11.8.6.tgz", + "integrity": "sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==", + "dependencies": { + "@sindresorhus/is": "^4.0.0", + "@szmarczak/http-timer": "^4.0.5", + "@types/cacheable-request": "^6.0.1", + "@types/responselike": "^1.0.0", + "cacheable-lookup": "^5.0.3", + "cacheable-request": "^7.0.2", + "decompress-response": "^6.0.0", + "http2-wrapper": "^1.0.0-beta.5.2", + "lowercase-keys": "^2.0.0", + "p-cancelable": "^2.0.0", + "responselike": "^2.0.0" + }, + "engines": { + "node": ">=10.19.0" + }, + "funding": { + "url": "https://github.com/sindresorhus/got?sponsor=1" + } + }, + "node_modules/gtoken": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-7.0.1.tgz", + "integrity": "sha512-KcFVtoP1CVFtQu0aSk3AyAt2og66PFhZAlkUOuWKwzMLoulHXG5W5wE5xAnHb+yl3/wEFoqGW7/cDGMU8igDZQ==", + "dependencies": { + "gaxios": "^6.0.0", + "jws": "^4.0.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", + "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", + "dependencies": { + "get-intrinsic": "^1.2.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", + "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/http-cache-semantics": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", + "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==" + }, + "node_modules/http2-wrapper": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", + "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==", + "dependencies": { + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.0.0" + }, + "engines": { + "node": ">=10.19.0" + } + }, + "node_modules/https-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.2.tgz", + "integrity": "sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA==", + "dependencies": { + "agent-base": "^7.0.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/is-gzip": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-gzip/-/is-gzip-2.0.0.tgz", + "integrity": "sha512-jtO4Njg6q58zDo/Pu4027beSZ0VdsZlt8/5Moco6yAg+DIxb5BK/xUYqYG2+MD4+piKldXJNHxRkhEYI2fvrxA==", + "engines": { + "node": ">=4" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/json-bigint": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", + "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", + "dependencies": { + "bignumber.js": "^9.0.0" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==" + }, + "node_modules/jwa": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz", + "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==", + "dependencies": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jws": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", + "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", + "dependencies": { + "jwa": "^2.0.0", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "engines": { + "node": ">=8" + } + }, + "node_modules/mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "engines": { + "node": ">=4" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/normalize-url": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", + "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/object-inspect": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/p-cancelable": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", + "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/qs": { + "version": "6.11.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.2.tgz", + "integrity": "sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==", + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/resolve-alpn": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", + "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==" + }, + "node_modules/responselike": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", + "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==", + "dependencies": { + "lowercase-keys": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/sax": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.3.0.tgz", + "integrity": "sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA==" + }, + "node_modules/set-function-length": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.0.tgz", + "integrity": "sha512-4DBHDoyHlM1IRPGYcoxexgh67y4ueR53FKV1yyxwFMY7aCqcN/38M1+SwZ/qJQ8iLv7+ck385ot4CcisOAPT9w==", + "dependencies": { + "define-data-property": "^1.1.1", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.2", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/sitemapper": { + "version": "3.2.8", + "resolved": "https://registry.npmjs.org/sitemapper/-/sitemapper-3.2.8.tgz", + "integrity": "sha512-xs1W76bRtJYn6WLQePX1QQaBBjhZgaimu1LbskJ9/8nv71Y+YSM3XRMdLYSiLeObCKuUh45zk+AOUUMKbVMbmg==", + "dependencies": { + "got": "^11.8.0", + "is-gzip": "2.0.0", + "p-limit": "^3.1.0", + "xml2js": "^0.4.23" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + }, + "node_modules/url-template": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz", + "integrity": "sha512-XdVKMF4SJ0nP/O7XIPB0JwAEuT9lDIYnNsK8yGVe43y0AWoKeJNdv3ZNWh7ksJ6KqQFjOO6ox/VEitLnaVNufw==" + }, + "node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "node_modules/xml2js": { + "version": "0.4.23", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz", + "integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==", + "dependencies": { + "sax": ">=0.6.0", + "xmlbuilder": "~11.0.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/xmlbuilder": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", + "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..44d8424 --- /dev/null +++ b/package.json @@ -0,0 +1,15 @@ +{ + "name": "google-indexing-script", + "private": true, + "version": "0.0.0", + "scripts": { + "index": "node ./src/index.mjs" + }, + "dependencies": { + "googleapis": "131.0.0", + "sitemapper": "3.2.8" + }, + "prettier": { + "printWidth": 120 + } +} diff --git a/src/index.mjs b/src/index.mjs new file mode 100644 index 0000000..8927548 --- /dev/null +++ b/src/index.mjs @@ -0,0 +1,108 @@ +import { getAccessToken } from "./shared/auth.mjs"; +import { + convertToSiteUrl, + getPublishMetadata, + requestIndexing, + getEmojiForStatus, + getPageIndexingStatus, +} from "./shared/gsc.mjs"; +import { getSitemapPages } from "./shared/sitemap.mjs"; +import { batch } from "./shared/utils.mjs"; +import { readFileSync, existsSync, mkdirSync, writeFileSync } from "fs"; + +const CACHE_TIMEOUT = 1000 * 60 * 60 * 24 * 14; // 14 days +const input = process.argv[2]; + +if (!input) { + console.error("❌ Please provide a domain or site URL as the first argument."); + console.error(""); + process.exit(1); +} + +const accessToken = await getAccessToken(); +const siteUrl = convertToSiteUrl(input); +console.log(`🔎 Processing site: ${siteUrl}`); +const cachePath = `.cache/${siteUrl.replace("http://", "http_").replace("https://", "https_").replace("/", "_")}.json`; + +const [sitemaps, pages] = await getSitemapPages(accessToken, siteUrl); + +if (sitemaps.length === 0) { + console.error("❌ No sitemaps found, add them to Google Search Console and try again."); + console.error(""); + process.exit(1); +} + +console.log(`👉 Found ${pages.length} URLs in ${sitemaps.length} sitemap`); + +const statusPerUrl = existsSync(cachePath) ? JSON.parse(readFileSync(cachePath, "utf8")) : {}; +const pagesPerStatus = {}; + +const indexableStatuses = [ + "Discovered - currently not indexed", + "Crawled - currently not indexed", + "URL is unknown to Google", + "Forbidden", + "Error", +]; + +const shouldRecheck = (status, lastCheckedAt) => { + const shouldIndexIt = indexableStatuses.includes(status); + const isOld = new Date(lastCheckedAt) < new Date(Date.now() - CACHE_TIMEOUT); + return shouldIndexIt || isOld; +}; + +await batch( + async (url) => { + let result = statusPerUrl[url]; + if (!result || shouldRecheck(result.status, result.lastCheckedAt)) { + const status = await getPageIndexingStatus(accessToken, siteUrl, url); + result = { status, lastCheckedAt: new Date().toISOString() }; + statusPerUrl[url] = result; + } + + pagesPerStatus[result.status] = pagesPerStatus[result.status] ? [...pagesPerStatus[result.status], url] : [url]; + }, + pages, + 50, + (batchIndex, batchCount) => { + console.log(`📦 Batch ${batchIndex + 1} of ${batchCount} complete`); + } +); + +console.log(``); +console.log(`👍 Done, here's the status of all ${pages.length} pages:`); +mkdirSync(".cache", { recursive: true }); +writeFileSync(cachePath, JSON.stringify(statusPerUrl, null, 2)); + +for (const [status, pages] of Object.entries(pagesPerStatus)) { + console.log(`• ${getEmojiForStatus(status)} ${status}: ${pages.length} pages`); +} +console.log(""); + +const indexablePages = Object.entries(pagesPerStatus).flatMap(([status, pages]) => + indexableStatuses.includes(status) ? pages : [] +); + +if (indexablePages.length === 0) { + console.log(`✨ There are no pages that can be indexed. Everything is already indexed!`); +} else { + console.log(`✨ Found ${indexablePages.length} pages that can be indexed.`); + indexablePages.forEach((url) => console.log(`• ${url}`)); +} +console.log(``); + +for (const url of indexablePages) { + console.log(`📄 Processing url: ${url}`); + const metadata = await getPublishMetadata(accessToken, url); + if (metadata === 404) { + await requestIndexing(accessToken, url); + console.log("🚀 Indexing requested successfully. It may take a few days for Google to process it."); + } else { + console.log(`🕛 Indexing already requested previously. It may take a few days for Google to process it.`); + } + console.log(``); +} + +console.log(`👍 All done!`); +console.log(`💖 Brought to you by https://seogets.com - SEO Analytics.`); +console.log(``); diff --git a/src/shared/auth.mjs b/src/shared/auth.mjs new file mode 100644 index 0000000..615da16 --- /dev/null +++ b/src/shared/auth.mjs @@ -0,0 +1,22 @@ +import { google } from "googleapis"; +import { existsSync, readFileSync } from "fs"; + +export async function getAccessToken() { + if (!existsSync("./service_account.json")) { + console.error("❌ service_account.json not found, please follow the instructions in README.md"); + console.error(""); + process.exit(1); + } + + const key = JSON.parse(readFileSync("./service_account.json", "utf8")); + const jwtClient = new google.auth.JWT( + key.client_email, + null, + key.private_key, + ["https://www.googleapis.com/auth/webmasters.readonly", "https://www.googleapis.com/auth/indexing"], + null + ); + + const tokens = await jwtClient.authorize(); + return tokens.access_token; +} diff --git a/src/shared/gsc.mjs b/src/shared/gsc.mjs new file mode 100644 index 0000000..1bce788 --- /dev/null +++ b/src/shared/gsc.mjs @@ -0,0 +1,112 @@ +import { fetchRetry } from "./utils.mjs"; + +export function convertToSiteUrl(input) { + if (input.startsWith("http://") || input.startsWith("https://")) { + return input.endsWith("/") ? input : `${input}/`; + } + return `sc-domain:${input}`; +} + +export async function getPageIndexingStatus(accessToken, siteUrl, inspectionUrl) { + try { + const response = await fetchRetry(`https://searchconsole.googleapis.com/v1/urlInspection/index:inspect`, { + method: "POST", + headers: { + "Content-Type": "application/json", + Authorization: `Bearer ${accessToken}`, + }, + body: JSON.stringify({ + inspectionUrl, + siteUrl, + }), + }); + + if (response.status === 403) { + console.error(`🔐 This service account doesn't have access to this site.`); + return "Forbidden"; + } + + if (response.status >= 300) { + console.error(`❌ Failed to get indexing status.`); + console.error(`Response was: ${response.status}`); + console.error(await response.text()); + return "Error"; + } + + const body = await response.json(); + return body.inspectionResult.indexStatusResult.coverageState; + } catch (error) { + console.error(`❌ Failed to get indexing status.`); + console.error(`Error was: ${error}`); + throw error; + } +} + +export function getEmojiForStatus(status) { + switch (status) { + case "Submitted and indexed": + return "✅"; + case "Duplicate without user-selected canonical": + return "😵"; + case "Crawled - currently not indexed": + case "Discovered - currently not indexed": + return "👀"; + case "Page with redirect": + return "🔀"; + case "URL is unknown to Google": + return "❓"; + default: + return "❌"; + } +} + +export async function getPublishMetadata(accessToken, url) { + const response = await fetchRetry( + `https://indexing.googleapis.com/v3/urlNotifications/metadata?url=${encodeURIComponent(url)}`, + { + method: "GET", + headers: { + "Content-Type": "application/json", + Authorization: `Bearer ${accessToken}`, + }, + } + ); + + if (response.status === 403) { + console.error(`🔐 This service account doesn't have access to this site.`); + console.error(`Response was: ${response.status}`); + } + + if (response.status >= 500) { + console.error(`❌ Failed to get publish metadata.`); + console.error(`Response was: ${response.status}`); + console.error(await response.text()); + } + + return response.status; +} + +export async function requestIndexing(accessToken, url) { + const response = await fetchRetry("https://indexing.googleapis.com/v3/urlNotifications:publish", { + method: "POST", + headers: { + "Content-Type": "application/json", + Authorization: `Bearer ${accessToken}`, + }, + body: JSON.stringify({ + url: url, + type: "URL_UPDATED", + }), + }); + + if (response.status === 403) { + console.error(`🔐 This service account doesn't have access to this site.`); + console.error(`Response was: ${response.status}`); + } + + if (response.status >= 300) { + console.error(`❌ Failed to request indexing.`); + console.error(`Response was: ${response.status}`); + console.error(await response.text()); + } +} diff --git a/src/shared/sitemap.mjs b/src/shared/sitemap.mjs new file mode 100644 index 0000000..bad2ed4 --- /dev/null +++ b/src/shared/sitemap.mjs @@ -0,0 +1,44 @@ +import Sitemapper from "sitemapper"; +import { fetchRetry } from "./utils.mjs"; + +async function getSitemapsList(accessToken, siteUrl) { + const url = `https://www.googleapis.com/webmasters/v3/sites/${encodeURIComponent(siteUrl)}/sitemaps`; + + const response = await fetchRetry(url, { + headers: { + "Content-Type": "application/json", + Authorization: `Bearer ${accessToken}`, + }, + }); + + if (response.status === 403) { + console.error(`🔐 This service account doesn't have access to this site.`); + return []; + } + + if (response.status >= 300) { + console.error(`❌ Failed to get list of sitemaps.`); + console.error(`Response was: ${response.status}`); + console.error(await response.text()); + return []; + } + + const body = await response.json(); + return body.sitemap.map((x) => x.path); +} + +export async function getSitemapPages(accessToken, siteUrl) { + const sitemaps = await getSitemapsList(accessToken, siteUrl); + + const pages = []; + for (const url of sitemaps) { + const Google = new Sitemapper({ + url, + }); + + const { sites } = await Google.fetch(); + pages.push(...sites); + } + + return [sitemaps, [...new Set(pages)]]; +} diff --git a/src/shared/utils.mjs b/src/shared/utils.mjs new file mode 100644 index 0000000..23c2793 --- /dev/null +++ b/src/shared/utils.mjs @@ -0,0 +1,26 @@ +const createChunks = (arr, size) => + Array.from({ length: Math.ceil(arr.length / size) }, (v, i) => arr.slice(i * size, i * size + size)); + +export async function batch(task, items, batchSize, onBatchComplete) { + const chunks = createChunks(items, batchSize); + for (let i = 0; i < chunks.length; i++) { + await Promise.all(chunks[i].map(task)); + onBatchComplete(i, chunks.length); + } +} + +export async function fetchRetry(url, options, retries = 3) { + try { + const response = await fetch(url, options); + if (response.status >= 500) { + const body = await response.text(); + throw new Error(`Server error code ${response.status}\n${body}`); + } + return response; + } catch (err) { + if (retries <= 0) { + throw err; + } + return fetchRetry(url, options, retries - 1); + } +}