{"meta":{"title":"REST API と JavaScript を使用したスクリプト","intro":"Octokit.js SDK を使用して REST API と対話するスクリプトを記述します。","product":"REST API","breadcrumbs":[{"href":"/ja/rest","title":"REST API"},{"href":"/ja/rest/guides","title":"ガイド"},{"href":"/ja/rest/guides/scripting-with-the-rest-api-and-javascript","title":"JavaScript を使用したスクリプト"}],"documentType":"article"},"body":"# REST API と JavaScript を使用したスクリプト\n\nOctokit.js SDK を使用して REST API と対話するスクリプトを記述します。\n\n## Octokit.js について\n\nGitHubの REST API と対話するために JavaScript を使用してスクリプトを記述する場合は、GitHubOctokit.js SDK を使用することをお勧めします。 Octokit.js は GitHubによって管理されます。 SDK によってベスト プラクティスが実装されており、JavaScript を使用して REST API を簡単に操作できます。 Octokit.js は、最新のあらゆるブラウザー、Node.js、Deno で動作します。 Octokit.js について詳しくは、[Octokit.js の README](https://github.com/octokit/octokit.js/#readme) を参照してください。\n\n## 前提条件\n\nこのガイドでは、JavaScript と GitHub REST API について理解していることを前提としています。 REST API の詳細については、「[REST API を使用した作業の開始](/ja/rest/using-the-rest-api/getting-started-with-the-rest-api)」を参照してください。\n\nOctokit.js ライブラリを使うには、`octokit` をインストールしてインポートする必要があります。 このガイドでは、ES6 に従って import ステートメントを使用します。 さまざまなインストールとインポートの方法について詳しくは、[Octokit.js の README の「使用法」セクションを参照してください](https://github.com/octokit/octokit.js/#usage)。\n\n## インスタンス化と認証\n\n> \\[!WARNING]\n> 認証の資格情報はパスワードと同じように扱ってください。\n>\n> 資格情報をセキュリティで保護するために、資格情報をシークレットとして格納し、 GitHub Actionsを使用してスクリプトを実行できます。 詳しくは、「[GitHub Actions でのシークレットの使用](/ja/actions/how-tos/write-workflows/choose-what-workflows-do/use-secrets)」をご覧ください。\n\n> 資格情報を Codespaces シークレットとして格納し、 Codespacesでスクリプトを実行することもできます。 詳しくは、「[GitHub Codespaces のアカウント固有のシークレットの管理](/ja/codespaces/managing-your-codespaces/managing-your-account-specific-secrets-for-github-codespaces)」をご覧ください。\n\n> これらのオプション 使用できない場合別の CLI サービスを使用して資格情報を安全に格納することを検討してください。\n\n### personal access tokenを使用した認証の実行\n\n個人用に GitHub REST API を使用する場合は、 personal access tokenを作成できます。\npersonal access tokenの作成の詳細については、「[個人用アクセス トークンを管理する](/ja/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens)」を参照してください。\n\nまず、`Octokit` を `octokit` からインポートします。 次に、personal access token のインスタンスを作成するときに、`Octokit` を渡します。 次の例では、 `YOUR-TOKEN` を personal access tokenへの参照に置き換えます。\n\n```javascript copy\nimport { Octokit } from \"octokit\";\n\nconst octokit = new Octokit({ \n  auth: 'YOUR-TOKEN',\n});\n```\n\n### GitHub Appを使用した認証の実行\n\n組織や他のユーザーに代わって API を使用する場合は、GitHubがGitHub Appを使用することを推奨しています。 エンドポイントを GitHub Appsで使用できる場合は、そのエンドポイントの REST リファレンス ドキュメントに、必要な GitHub App トークンの種類が示されます。 詳細については、「[GitHub アプリの登録](/ja/apps/creating-github-apps/registering-a-github-app/registering-a-github-app)」および「[GitHub アプリでの認証について](/ja/apps/creating-github-apps/authenticating-with-a-github-app/about-authentication-with-a-github-app)」を参照してください。\n\n`Octokit` を `octokit` からインポートする代わりに、`App` をインポートします。 次の例では、`APP_ID` をアプリの ID への参照に置き換えます。\n`PRIVATE_KEY` をアプリの秘密キーへの参照に置き換えます。\n`INSTALLATION_ID` を、代わりに認証するアプリのインストールの ID に置き換えます。 アプリの ID を見つけて、アプリの設定ページで秘密キーを生成できます。 詳しくは、「[GitHub アプリの秘密キーの管理](/ja/apps/creating-github-apps/authenticating-with-a-github-app/managing-private-keys-for-github-apps)」をご覧ください。 インストール ID は `GET /users/{username}/installation`、`GET /repos/{owner}/{repo}/installation`、または `GET /orgs/{org}/installation` のエンドポイントで取得できます。 詳細については、 [AUTOTITLE を](/ja/rest/apps/apps)参照してください。\n\n```javascript copy\nimport { App } from \"octokit\";\n\nconst app = new App({\n  appId: APP_ID,\n  privateKey: PRIVATE_KEY,\n});\n\nconst octokit = await app.getInstallationOctokit(INSTALLATION_ID);\n```\n\n### GitHub Actions での認証\n\nGitHub Actions ワークフローで API を使用する場合GitHubは、トークンを作成するのではなく、組み込みの`GITHUB_TOKEN`で認証することをお勧めします。\n`GITHUB_TOKEN` キーを使用して、`permissions` へのアクセス許可を付与できます。\n`GITHUB_TOKEN` の詳細については、「[GITHUB\\_TOKEN](/ja/actions/concepts/security/github_token)」を参照してください。\n\nワークフローがワークフローのリポジトリの外部にあるリソースにアクセスする必要がある場合は、`GITHUB_TOKEN` を使用できません。 その場合は、資格情報をシークレットとして格納し、次の例で `GITHUB_TOKEN` を実際のシークレットの名前に置き換えます。 シークレットの詳細については、「[GitHub Actions でのシークレットの使用](/ja/actions/how-tos/write-workflows/choose-what-workflows-do/use-secrets)」を参照してください。\n\n`run` キーワードを使用して、GitHub Actions ワークフローで JavaScript スクリプトを実行する場合は、`GITHUB_TOKEN`の値を環境変数として格納できます。 スクリプトは、`process.env.VARIABLE_NAME` として環境変数にアクセスできます。\n\nたとえば、このワークフロー ステップでは、`GITHUB_TOKEN` という環境変数に `TOKEN` が格納されます。\n\n```yaml\n- name: Run script\n  env:\n    TOKEN: ${{ secrets.GITHUB_TOKEN }}\n  run: |\n    node .github/actions-scripts/use-the-api.mjs\n```\n\nワークフローが実行するスクリプトは、認証に `process.env.TOKEN` を使用します。\n\n```javascript copy\nimport { Octokit } from \"octokit\";\n\nconst octokit = new Octokit({ \n  auth: process.env.TOKEN,\n});\n```\n\n### 認証なしでのインスタンス化\n\nREST API は認証なしで使用できますが、レート制限が低く、一部のエンドポイントを使用することができません。 認証を行わずに `Octokit` のインスタンスを作成するには、 `auth` 引数を渡さないでください。\n\n```javascript copy\nimport { Octokit } from \"octokit\";\n\nconst octokit = new Octokit({ );\n```\n\n## リクエストの提出\n\nOctokit では、要求を行う複数の方法がサポートされています。 エンドポイントの HTTP 動詞とパスがわかっている場合は、`request` メソッドを使用して要求を行うことができます。\n`rest` メソッドを使用すると、IDE と入力でのオートコンプリートを利用できます。 ページ分割されたエンドポイントの場合は、`paginate` メソッドを使用して複数のページのデータを要求できます。\n\n### `request` メソッドを使用して要求を行う\n\n`request` メソッドを使用して要求を行うには、HTTP メソッドとパスを最初の引数として渡します。 オブジェクト内の本文、クエリ、またはパスのパラメーターを 2 番目の引数として渡します。 たとえば、`GET` 要求を `/repos/{owner}/{repo}/issues` に行い、`owner`、`repo`、`per_page` パラメーターを渡すには、次のようにします。\n\n```javascript copy\nawait octokit.request(\"GET /repos/{owner}/{repo}/issues\", {\n  owner: \"github\",\n  repo: \"docs\",\n  per_page: 2\n});\n```\n\n`request` メソッドでは `Accept: application/vnd.github+json` ヘッダーが自動的に渡されます。 追加のヘッダーまたは別の `Accept` ヘッダーを渡すには、2 番目の引数として渡されるオブジェクトに `headers` プロパティを追加します。\n`headers` プロパティの値は、キーがヘッダー名で値がヘッダー値のオブジェクトです。 たとえば、`content-type` の値を持つ `text/plain` ヘッダーと、`x-github-api-version` の値を持つ `2026-03-10` ヘッダーを送信するには、次のようにします。\n\n```javascript copy\nawait octokit.request(\"POST /markdown/raw\", {\n  text: \"Hello **world**\",\n  headers: {\n    \"content-type\": \"text/plain\",\n    \"x-github-api-version\": \"2026-03-10\",\n  },\n});\n```\n\n### `rest` エンドポイント メソッドを使用して要求を行う\n\nすべての REST API エンドポイントには、Octokit に関連付けられた `rest` エンドポイント メソッドがあります。 これらのメソッドは、通常、便宜上 IDE でオートコンプリートされます。 任意のパラメーターをオブジェクトとしてメソッドに渡すことができます。\n\n```javascript copy\nawait octokit.rest.issues.listForRepo({\n  owner: \"github\",\n  repo: \"docs\",\n  per_page: 2\n});\n```\n\nさらに、TypeScript などの型指定された言語を使用している場合は、これらのメソッドで使用する型をインポートできます。 詳しくは、[plugin-rest-endpoint-methods.js の README の「TypeScript」セクション](https://github.com/octokit/plugin-rest-endpoint-methods.js/#typescript)を参照してください。\n\n### ページ分割された要求の作成\n\nエンドポイントがページ分割されていて、複数のページの結果をフェッチする場合は、`paginate` メソッドを使用できます。\n`paginate` は、最後のページに達するまで結果の次のページをフェッチし、すべての結果を 1 つの配列として返します。 いくつかのエンドポイントは、ページ分割された結果を配列として返すのではなく、ページ分割された結果をオブジェクト内の配列として返します。 生の結果がオブジェクトであっても、`paginate` は常にアイテムの配列を返します。\n\nたとえば、上記の例では `github/docs` リポジトリからすべての issue が取得されます。 一度に 100 の issue が要求されますが、データの最後のページに達するまで関数は返されません。\n\n```javascript copy\nconst issueData = await octokit.paginate(\"GET /repos/{owner}/{repo}/issues\", {\n  owner: \"github\",\n  repo: \"docs\",\n  per_page: 100,\n  headers: {\n    \"x-github-api-version\": \"2026-03-10\",\n  },\n});\n```\n\n`paginate` メソッドは省略可能な map 関数を受け入れます。これを使用して、応答から必要なデータのみを収集できます。 これにより、スクリプトによるメモリ使用量が削減されます。 map 関数は、最後のページに到達する前にページネーションを終了するために呼び出すことができる第2引数 `done` を取ることができます。 これにより、ページのサブセットをフェッチできます。 たとえば、次の例では、タイトルに \"test\" を含む issue が返されるまで、結果がフェッチされます。 返されたデータのページには、issue のタイトルと作成者のみが格納されます。\n\n```javascript copy\nconst issueData = await octokit.paginate(\"GET /repos/{owner}/{repo}/issues\", {\n  owner: \"github\",\n  repo: \"docs\",\n  per_page: 100,\n  headers: {\n    \"x-github-api-version\": \"2026-03-10\",\n  },\n},\n    (response, done) => response.data.map((issue) => {\n    if (issue.title.includes(\"test\")) {\n      done()\n    }\n    return ({title: issue.title, author: issue.user.login})\n  })\n);\n```\n\nすべての結果を一度にフェッチする代わりに、`octokit.paginate.iterator()` を使用して一度に 1 つのページを反復処理できます。 たとえば、次の例では、一度に 1 ページの結果をフェッチし、次のページをフェッチする前に、ページの各オブジェクトを処理します。 タイトルに \"test\" を含む issue に達すると、スクリプトは反復を停止し、処理された各オブジェクトの issue タイトルと issue 作成者を返します。 反復子は、ページ分割されたデータをフェッチするための最もメモリ効率の高いメソッドです。\n\n```javascript copy\nconst iterator = octokit.paginate.iterator(\"GET /repos/{owner}/{repo}/issues\", {\n  owner: \"github\",\n  repo: \"docs\",\n  per_page: 100,\n  headers: {\n    \"x-github-api-version\": \"2026-03-10\",\n  },\n});\n\nlet issueData = []\nlet breakLoop = false\nfor await (const {data} of iterator) {\n  if (breakLoop) break\n  for (const issue of data) {\n    if (issue.title.includes(\"test\")) {\n      breakLoop = true\n      break\n    } else {\n      issueData = [...issueData, {title: issue.title, author: issue.user.login}];\n    }\n  }\n}\n```\n\n`paginate` エンドポイント メソッドでも、`rest` メソッドを使用できます。\n`rest` エンドポイント メソッドを最初の引数として渡します。 任意のパラメーターを 2 番目の引数として渡します。\n\n```javascript copy\nconst iterator = octokit.paginate.iterator(octokit.rest.issues.listForRepo, {\n  owner: \"github\",\n  repo: \"docs\",\n  per_page: 100,\n  headers: {\n    \"x-github-api-version\": \"2026-03-10\",\n  },\n});\n```\n\nページネーションの詳細については、「[REST API でのページネーションの使用](/ja/rest/using-the-rest-api/using-pagination-in-the-rest-api)」を参照してください。\n\n## エラーのキャッチ\n\n### すべてのエラーの捕捉\n\n場合によっては、 GitHub REST API からエラーが返されることがあります。 たとえば、アクセス トークンの有効期限が切れている場合や、必要なパラメーターを省略した場合にエラーが発生します。 Octokit.js は `400 Bad Request`、`401 Unauthorized`、`403 Forbidden`、`404 Not Found`、`422 Unprocessable Entity` 以外のエラーが発生すると、要求を自動的に再試行します。 再試行後も API エラーが発生した場合、Octokit.js は、応答の HTTP 状態コード (`response.status`) と応答ヘッダー (`response.headers`) を含むエラーをスローします。 これらのエラーはコードで対処する必要があります。 たとえば、try/catch ブロックを使用してエラーをキャッチできます。\n\n```javascript copy\nlet filesChanged = []\n\ntry {\n  const iterator = octokit.paginate.iterator(\"GET /repos/{owner}/{repo}/pulls/{pull_number}/files\", {\n    owner: \"github\",\n    repo: \"docs\",\n    pull_number: 22809,\n    per_page: 100,\n    headers: {\n      \"x-github-api-version\": \"2026-03-10\",\n    },\n  });\n\n  for await (const {data} of iterator) {\n    filesChanged = [...filesChanged, ...data.map(fileData => fileData.filename)];\n  }\n} catch (error) {\n  if (error.response) {\n    console.error(`Error! Status: ${error.response.status}. Message: ${error.response.data.message}`)\n  }\n  console.error(error)\n}\n```\n\n### 目的のエラー コードの処理\n\n場合によっては、 GitHub は 4xx 状態コードを使用してエラー以外の応答を示します。 使用しているエンドポイントでこれを行う場合は、特定のエラーに対する処理を追加できます。 たとえば、リポジトリに星が付いていない場合、`GET /user/starred/{owner}/{repo}` エンドポイントは `404` を返します。 次の例では、`404` 応答を使用して、リポジトリに星が付いていないことを示しています。その他のすべてのエラー コードはエラーとして扱われます。\n\n```javascript copy\ntry {\n  await octokit.request(\"GET /user/starred/{owner}/{repo}\", {\n    owner: \"github\",\n    repo: \"docs\",\n    headers: {\n      \"x-github-api-version\": \"2026-03-10\",\n    },\n  });\n\n  console.log(`The repository is starred by me`);\n\n} catch (error) {\n  if (error.status === 404) {\n    console.log(`The repository is not starred by me`);\n  } else {\n    console.error(`An error occurred while checking if the repository is starred: ${error?.response?.data?.message}`);\n  }\n}\n```\n\n### レート制限エラーの処理\n\nレート制限エラーが発生した場合は、待機後に要求を再試行できます。 レート制限がある場合、 GitHub は `403 Forbidden` エラーで応答し、 `x-ratelimit-remaining` 応答ヘッダーの値が `\"0\"`されます。 応答ヘッダーには、現在のレート制限ウィンドウがリセットされる時刻を UTC エポック秒数で示す `x-ratelimit-reset` ヘッダーが含まれます。 要求は、`x-ratelimit-reset` で指定された時刻より後に再試行できます。\n\n```javascript copy\nasync function requestRetry(route, parameters) {\n  try {\n    const response = await octokit.request(route, parameters);\n    return response\n  } catch (error) {\n    if (error.response && error.status === 403 && error.response.headers['x-ratelimit-remaining'] === '0') {\n      const resetTimeEpochSeconds = error.response.headers['x-ratelimit-reset'];\n      const currentTimeEpochSeconds = Math.floor(Date.now() / 1000);\n      const secondsToWait = resetTimeEpochSeconds - currentTimeEpochSeconds;\n      console.log(`You have exceeded your rate limit. Retrying in ${secondsToWait} seconds.`);\n      setTimeout(requestRetry, secondsToWait * 1000, route, parameters);\n    } else {\n      console.error(error);\n    }\n  }\n}\n\nconst response = await requestRetry(\"GET /repos/{owner}/{repo}/issues\", {\n    owner: \"github\",\n    repo: \"docs\",\n    per_page: 2\n  })\n```\n\n## 応答を利用する\n\n`request` メソッドは、要求が成功した場合にオブジェクトに解決される Promise を返します。 オブジェクトのプロパティは `data`、(エンドポイントによって返される応答本文)、`status` (HTTP 応答コード)、`url` (要求の URL)、および `headers` (応答ヘッダーを含むオブジェクト) です。 特に指定しない限り、応答本文は JSON 形式となります。 一部のエンドポイントは応答本文を返しません。このような場合、`data` プロパティは省略されます。\n\n```javascript copy\nconst response = await octokit.request(\"GET /repos/{owner}/{repo}/issues/{issue_number}\", {\n  owner: \"github\",\n  repo: \"docs\",\n  issue_number: 11901,\n  headers: {\n    \"x-github-api-version\": \"2026-03-10\",\n  },\n});\n\nconsole.log(`The status of the response is: ${response.status}`)\nconsole.log(`The request URL was: ${response.url}`)\nconsole.log(`The x-ratelimit-remaining response header is: ${response.headers[\"x-ratelimit-remaining\"]}`)\nconsole.log(`The issue title is: ${response.data.title}`)\n```\n\n同様に、`paginate` メソッドは Promise を返します。 要求が成功した場合、Promise はエンドポイントによって返されるデータの配列に解決されます。\n`request` メソッドとは異なり、`paginate` メソッドは状態コード、URL、またはヘッダーを返しません。\n\n```javascript copy\nconst data = await octokit.paginate(\"GET /repos/{owner}/{repo}/issues\", {\n  owner: \"github\",\n  repo: \"docs\",\n  per_page: 100,\n  headers: {\n    \"x-github-api-version\": \"2026-03-10\",\n  },\n});\n\nconsole.log(`${data.length} issues were returned`)\nconsole.log(`The title of the first issue is: ${data[0].title}`)\n```\n\n## サンプル スクリプト\n\nOctokit.js を使用するスクリプトの完全な例を次に示します。 このスクリプトは `Octokit` をインポートし、`Octokit` の新しいインスタンスを作成します。\nGitHub Appではなくpersonal access tokenで認証する場合は、`App`ではなく`Octokit`をインポートしてインスタンス化します。 詳細については、「[GitHub Appを使用した認証」を](#authenticating-with-a-github-app)参照してください。\n\n`getChangedFiles` 関数は、pull request で変更されたすべてのファイルを取得します。\n`commentIfDataFilesChanged` 関数は `getChangedFiles` 関数を呼び出します。 pull request で変更されたいずれかのファイルのファイル パスに `/data/` が含まれている場合、この関数が pull request にコメントを付けます。\n\n```javascript copy\nimport { Octokit } from \"octokit\";\n\nconst octokit = new Octokit({ \n  auth: 'YOUR-TOKEN',\n});\n\nasync function getChangedFiles({owner, repo, pullNumber}) {\n  let filesChanged = []\n\n  try {\n    const iterator = octokit.paginate.iterator(\"GET /repos/{owner}/{repo}/pulls/{pull_number}/files\", {\n      owner: owner,\n      repo: repo,\n      pull_number: pullNumber,\n      per_page: 100,\n      headers: {\n        \"x-github-api-version\": \"2026-03-10\",\n      },\n    });\n\n    for await (const {data} of iterator) {\n      filesChanged = [...filesChanged, ...data.map(fileData => fileData.filename)];\n    }\n  } catch (error) {\n    if (error.response) {\n      console.error(`Error! Status: ${error.response.status}. Message: ${error.response.data.message}`)\n    }\n    console.error(error)\n  }\n\n  return filesChanged\n}\n\nasync function commentIfDataFilesChanged({owner, repo, pullNumber}) {\n  const changedFiles = await getChangedFiles({owner, repo, pullNumber});\n\n  const filePathRegex = new RegExp(/\\/data\\//, \"i\");\n  if (!changedFiles.some(fileName => filePathRegex.test(fileName))) {\n    return;\n  }\n\n  try {\n    const {data: comment} = await octokit.request(\"POST /repos/{owner}/{repo}/issues/{issue_number}/comments\", {\n      owner: owner,\n      repo: repo,\n      issue_number: pullNumber,\n      body: `It looks like you changed a data file. These files are auto-generated. \\n\\nYou must revert any changes to data files before your pull request will be reviewed.`,\n      headers: {\n        \"x-github-api-version\": \"2026-03-10\",\n      },\n    });\n\n    return comment.html_url;\n  } catch (error) {\n    if (error.response) {\n      console.error(`Error! Status: ${error.response.status}. Message: ${error.response.data.message}`)\n    }\n    console.error(error)\n  }\n}\n\nawait commentIfDataFilesChanged({owner: \"github\", repo: \"docs\", pullNumber: 191});\n```\n\n## 次の手順\n\n* Octokit.js について詳しくは、[Octokit.js のドキュメント](https://github.com/octokit/octokit.js/#readme)を参照してください。\n* 実際の例については、GitHubGitHubして、[](https://github.com/search?q=repo%3Agithub%2Fdocs%20path%3A.github%20octokit\\&type=code) Docs が Octokit.js を使用する方法を確認してください。"}