# Script em API REST e JavaScript

Escreva um script usando o SDK do Octokit.js para interagir com a API REST.

## Sobre o Octokit.js

Se você quiser escrever um script usando JavaScript para interagir com a API REST da GitHub, a GitHub recomenda que você use o SDK do Octokit.js. O Octokit.js é mantido pela GitHub. O SDK implementa as melhores práticas e facilita a interação com a API REST por meio do JavaScript. O Octokit.js funciona com todos os navegadores modernos, Node.js e Deno. Para obter mais informações sobre o Octokit.js, confira o arquivo [LEIAME do Octokit.js](https://github.com/octokit/octokit.js/#readme).

## Pré-requisitos

Este guia pressupõe que você esteja familiarizado com o JavaScript e a API REST da GitHub. Para obter informações sobre a API REST, confira [Introdução à API REST](/pt/rest/guides/getting-started-with-the-rest-api).

Você precisa instalar e importar `octokit` para usar a biblioteca do Octokit.js. Este guia usa instruções de importação de acordo com o ES6. Para obter mais informações sobre diferentes métodos de instalação e importação, confira a seção de uso no README do Octokit.js.

## Instanciação e autenticação

> \[!WARNING]
> Trate suas credenciais de autenticação como uma senha.
>
> Para manter suas credenciais seguras, você pode armazená-las como um segredo e executar seu script por meio de GitHub Actions. Para saber mais, confira [Usar segredos em ações do GitHub](/pt/actions/security-guides/encrypted-secrets).

> Você também pode armazenar suas credenciais como um segredo do Codespaces e executar seu script no Codespaces. Para saber mais, confira [Gerenciando seus segredos específicos da conta no GitHub Codespaces](/pt/codespaces/managing-your-codespaces/managing-encrypted-secrets-for-your-codespaces).

> Se essas opções não forem possíveis, considere usar outro serviço CLI para armazenar suas credenciais com segurança.

### Autenticar com um personal access token

Se quiser usar a API REST do GitHub para uso pessoal, crie um personal access token. Para obter mais informações sobre como criar um personal access token, confira [Gerenciar seus tokens de acesso pessoal](/pt/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token).

Primeiro, importe `Octokit` de `octokit`. Em seguida, passe seu personal access token ao criar uma instância de `Octokit`. No exemplo a seguir, substitua `YOUR-TOKEN` por uma referência ao seu personal access token.

```javascript copy
import { Octokit } from "octokit";

const octokit = new Octokit({ 
  auth: 'YOUR-TOKEN',
});
```

### Autenticação com um GitHub App

Se você quiser usar a API em nome de uma organização ou de outro usuário, a GitHub recomenda que você use um GitHub App. Se um ponto de extremidade estiver disponível para GitHub Apps, a documentação de referência da API REST para esse ponto de extremidade indicará que tipo de token do GitHub App é necessário. Para saber mais, confira [Registrando um aplicativo GitHub](/pt/apps/creating-github-apps/setting-up-a-github-app/creating-a-github-app) e [Sobre a autenticação com um aplicativo GitHub](/pt/apps/creating-github-apps/authenticating-with-a-github-app/about-authentication-with-a-github-app).

Em vez de importar `Octokit` de `octokit`, importe `App`. No exemplo a seguir, substitua `APP_ID` por uma referência à ID do seu aplicativo. Substitua `PRIVATE_KEY` por uma referência à chave privada do seu aplicativo. Substitua `INSTALLATION_ID` pela ID de instalação do seu aplicativo em nome do qual deseja se autenticar. Você pode encontrar a ID do seu aplicativo e gerar uma chave privada na página de configurações do aplicativo. Para saber mais, confira [Gerenciando chaves privadas para aplicativos GitHub](/pt/apps/creating-github-apps/authenticating-with-a-github-app/managing-private-keys-for-github-apps). Você pode obter uma ID de instalação com os pontos de extremidade `GET /users/{username}/installation`, `GET /repos/{owner}/{repo}/installation` ou `GET /orgs/{org}/installation`. Para obter mais informações, confira [Pontos de extremidade da API REST para o GitHub Apps](/pt/rest/apps/apps).

```javascript copy
import { App } from "octokit";

const app = new App({
  appId: APP_ID,
  privateKey: PRIVATE_KEY,
});

const octokit = await app.getInstallationOctokit(INSTALLATION_ID);
```

### Autenticação em GitHub Actions

Se você quiser usar a API em um fluxo de trabalho de GitHub Actions, GitHub recomenda que você faça a autenticação com o `GITHUB_TOKEN` interno, em vez de criar um token. Você pode conceder permissões à `GITHUB_TOKEN` com a chave `permissions`. Para obter mais informações sobre `GITHUB_TOKEN`, confira [GITHUB\_TOKEN](/pt/actions/concepts/security/github_token).

Se o fluxo de trabalho precisar acessar recursos fora do repositório dele, então você não poderá usar `GITHUB_TOKEN`. Nesse caso, armazene suas credenciais como um segredo e substitua `GITHUB_TOKEN` nos exemplos abaixo pelo nome do segredo. Para saber mais sobre segredos, confira [Usar segredos em ações do GitHub](/pt/actions/security-guides/encrypted-secrets).

Se usar a palavra-chave `run` para executar o script do JavaScript em seus fluxos de trabalho de GitHub Actions, você poderá armazenar o valor de `GITHUB_TOKEN` como uma variável de ambiente. Seu script pode acessar a variável de ambiente como `process.env.VARIABLE_NAME`.

Por exemplo, essa etapa do fluxo de trabalho armazena `GITHUB_TOKEN` em uma variável de ambiente chamada `TOKEN`:

```yaml
- name: Run script
  env:
    TOKEN: ${{ secrets.GITHUB_TOKEN }}
  run: |
    node .github/actions-scripts/use-the-api.mjs
```

O script que o fluxo de trabalho executa usa `process.env.TOKEN` para se autenticar:

```javascript copy
import { Octokit } from "octokit";

const octokit = new Octokit({ 
  auth: process.env.TOKEN,
});
```

### Instanciação sem autenticação

Você pode usar a API REST sem autenticação, embora isso resulte em uma limitação de taxa mais baixa e não permita o uso de alguns endpoints. Para criar uma instância de `Octokit` sem autenticação, não passe o argumento `auth`.

```javascript copy
import { Octokit } from "octokit";

const octokit = new Octokit({ );
```

## Como fazer solicitações

O Octokit dá suporte a várias maneiras de fazer solicitações. Você pode usar o método `request` para fazer solicitações se souber o verbo HTTP e o caminho para o ponto de extremidade. Você pode usar o método `rest` se quiser aproveitar o preenchimento automático em seu IDE e digitar. Para pontos de extremidade paginados, você pode usar o método `paginate` para solicitar várias páginas de dados.

### Como usar o método `request` para fazer solicitações

Para usar o método `request` a fim de fazer solicitações, passe o método HTTP e o caminho como o primeiro argumento. Passe quaisquer parâmetros de corpo, consulta ou caminho em um objeto como o segundo argumento. Por exemplo, para fazer uma solicitação `GET` para `/repos/{owner}/{repo}/issues` e passar os parâmetros `owner`, `repo` e `per_page`:

```javascript copy
await octokit.request("GET /repos/{owner}/{repo}/issues", {
  owner: "github",
  repo: "docs",
  per_page: 2
});
```

O método `request` passa automaticamente o cabeçalho `Accept: application/vnd.github+json`. Para passar cabeçalhos adicionais ou um cabeçalho `Accept` diferente, adicione uma propriedade `headers` ao objeto que é passado como o segundo argumento. O valor da propriedade `headers` é um objeto onde os nomes dos cabeçalhos são as chaves e os valores correspondentes são os valores. Por exemplo, para enviar um cabeçalho `content-type` com o valor de `text/plain` e um cabeçalho `x-github-api-version` com o valor de `2026-03-10`:

```javascript copy
await octokit.request("POST /markdown/raw", {
  text: "Hello **world**",
  headers: {
    "content-type": "text/plain",
    "x-github-api-version": "2026-03-10",
  },
});
```

### Como usar métodos endpoint `rest` para fazer solicitações

Cada ponto de extremidade da API REST tem um método de ponto de extremidade `rest` associado no Octokit. Esses métodos geralmente são preenchidos automaticamente em seu IDE para conveniência. Você pode passar qualquer parâmetro como um objeto para o método.

```javascript copy
await octokit.rest.issues.listForRepo({
  owner: "github",
  repo: "docs",
  per_page: 2
});
```

Além disso, se estiver usando uma linguagem tipada, como TypeScript, você poderá importar tipos para usar com esses métodos. Para obter mais informações, confira a [seção de TypeScript no README do plugin-rest-endpoint-methods.js](https://github.com/octokit/plugin-rest-endpoint-methods.js/#typescript).

### Como fazer solicitações paginadas

Se o endpoint for paginado e você quiser recuperar mais de uma página de resultados, poderá usar o método `paginate`.
`paginate` buscará a próxima página de resultados até chegar à última página e retornará todos os resultados como uma única matriz. Alguns pontos de extremidade retornam resultados paginados como matriz em um objeto, em vez de retornar os resultados paginados como uma matriz.
`paginate` sempre retorna uma matriz de itens, mesmo que o resultado bruto tenha sido um objeto .

Por exemplo, o exemplo a seguir obtém todos os problemas do repositório `github/docs`. Embora solicite 100 solicitações por vez, a função não retornará até que a última página de dados seja atingida.

```javascript copy
const issueData = await octokit.paginate("GET /repos/{owner}/{repo}/issues", {
  owner: "github",
  repo: "docs",
  per_page: 100,
  headers: {
    "x-github-api-version": "2026-03-10",
  },
});
```

O método `paginate` aceita uma função de mapa opcional, que pode ser usada para coletar apenas os dados desejados da resposta. Isso reduz o uso de memória pelo seu script. A função de mapa pode usar um segundo argumento, `done`, que pode ser chamado para encerrar a paginação antes que a última página seja alcançada. Isso permite que você busque um subconjunto de páginas. Por exemplo, o exemplo a seguir continua buscando resultados até que seja retornada uma questão que inclua "teste" no título. Para as páginas de dados que foram retornadas, apenas o título e o autor da questão são armazenados.

```javascript copy
const issueData = await octokit.paginate("GET /repos/{owner}/{repo}/issues", {
  owner: "github",
  repo: "docs",
  per_page: 100,
  headers: {
    "x-github-api-version": "2026-03-10",
  },
},
    (response, done) => response.data.map((issue) => {
    if (issue.title.includes("test")) {
      done()
    }
    return ({title: issue.title, author: issue.user.login})
  })
);
```

Em vez de buscar todos os resultados de uma só vez, você pode usar `octokit.paginate.iterator()` para percorrer uma só página de cada vez. Por exemplo, o caso a seguir busca uma página de resultados por vez e processa cada objeto da página atual antes de buscar a próxima. Uma vez encontrado um problema com "teste" no título, o script interrompe a iteração e retorna o título e o autor do problema de cada objeto que foi processado. O iterador é o método mais eficiente em termos de memória para buscar dados paginados.

```javascript copy
const iterator = octokit.paginate.iterator("GET /repos/{owner}/{repo}/issues", {
  owner: "github",
  repo: "docs",
  per_page: 100,
  headers: {
    "x-github-api-version": "2026-03-10",
  },
});

let issueData = []
let breakLoop = false
for await (const {data} of iterator) {
  if (breakLoop) break
  for (const issue of data) {
    if (issue.title.includes("test")) {
      breakLoop = true
      break
    } else {
      issueData = [...issueData, {title: issue.title, author: issue.user.login}];
    }
  }
}
```

Você também pode usar o método `paginate` com os métodos de endpoint `rest`. Passe o método de ponto de extremidade `rest` como o primeiro argumento. Passe todos os demais parâmetros como o segundo argumento.

```javascript copy
const iterator = octokit.paginate.iterator(octokit.rest.issues.listForRepo, {
  owner: "github",
  repo: "docs",
  per_page: 100,
  headers: {
    "x-github-api-version": "2026-03-10",
  },
});
```

Para saber mais sobre a paginação, confira [Como usar paginação na API REST](/pt/rest/guides/using-pagination-in-the-rest-api).

## Captura de erros

### Capturando todos os erros

Às vezes, a API REST da GitHub retorna um erro. Por exemplo, um erro será exibido se o token de acesso tiver expirado ou se um parâmetro obrigatório for omitido. O Octokit.js faz automaticamente novas tentativas de executar a solicitação quando obtém um erro diferente de `400 Bad Request`, `401 Unauthorized`, `403 Forbidden`, `404 Not Found` ou `422 Unprocessable Entity`. Se ocorrer um erro de API mesmo após novas tentativas, o Octokit.js gera um erro que inclui o código de status HTTP da resposta (`response.status`) e os cabeçalhos da resposta (`response.headers`). Você deve tratar esses erros em seu código. Por exemplo, você pode usar um bloco try/catch para capturar erros:

```javascript copy
let filesChanged = []

try {
  const iterator = octokit.paginate.iterator("GET /repos/{owner}/{repo}/pulls/{pull_number}/files", {
    owner: "github",
    repo: "docs",
    pull_number: 22809,
    per_page: 100,
    headers: {
      "x-github-api-version": "2026-03-10",
    },
  });

  for await (const {data} of iterator) {
    filesChanged = [...filesChanged, ...data.map(fileData => fileData.filename)];
  }
} catch (error) {
  if (error.response) {
    console.error(`Error! Status: ${error.response.status}. Message: ${error.response.data.message}`)
  }
  console.error(error)
}
```

### Tratamento de códigos de erro previstos

Às vezes, a GitHub usa um código de status 4xx para indicar uma resposta sem erro. Se o endpoint que você está usando fizer isso, você poderá adicionar tratamento adicional para erros específicos. Por exemplo, o endpoint `GET /user/starred/{owner}/{repo}` retornará `404` se o repositório não estiver marcado com estrela. O exemplo a seguir usa a resposta `404` para indicar que o repositório não foi estrelado; todos os demais códigos de erros são tratados como erros.

```javascript copy
try {
  await octokit.request("GET /user/starred/{owner}/{repo}", {
    owner: "github",
    repo: "docs",
    headers: {
      "x-github-api-version": "2026-03-10",
    },
  });

  console.log(`The repository is starred by me`);

} catch (error) {
  if (error.status === 404) {
    console.log(`The repository is not starred by me`);
  } else {
    console.error(`An error occurred while checking if the repository is starred: ${error?.response?.data?.message}`);
  }
}
```

### Tratamento de erros de limite de taxa

Se você receber um erro de limite de taxa, talvez seja necessário repetir a solicitação após aguardar um tempo. Quando você tem taxa limitada, a GitHub responde com um erro `403 Forbidden` e o valor do cabeçalho de resposta `x-ratelimit-remaining` será `"0"`. Os cabeçalhos de resposta incluirão um cabeçalho `x-ratelimit-reset`, que informa a hora em que a janela de limite de taxa atual é redefinida, em segundos UTC. Você pode repetir a solicitação após aguardar o tempo especificado por `x-ratelimit-reset`.

```javascript copy
async function requestRetry(route, parameters) {
  try {
    const response = await octokit.request(route, parameters);
    return response
  } catch (error) {
    if (error.response && error.status === 403 && error.response.headers['x-ratelimit-remaining'] === '0') {
      const resetTimeEpochSeconds = error.response.headers['x-ratelimit-reset'];
      const currentTimeEpochSeconds = Math.floor(Date.now() / 1000);
      const secondsToWait = resetTimeEpochSeconds - currentTimeEpochSeconds;
      console.log(`You have exceeded your rate limit. Retrying in ${secondsToWait} seconds.`);
      setTimeout(requestRetry, secondsToWait * 1000, route, parameters);
    } else {
      console.error(error);
    }
  }
}

const response = await requestRetry("GET /repos/{owner}/{repo}/issues", {
    owner: "github",
    repo: "docs",
    per_page: 2
  })
```

## Como usar a resposta

O método `request` retorna uma promessa que será resolvida para um objeto se a solicitação for bem-sucedida. As propriedades do objeto são `data` (o corpo da resposta retornado pelo ponto de extremidade), `status` (o código da resposta HTTP), `url` (a URL da solicitação) e `headers` (um objeto que contém os cabeçalhos da resposta). A menos que especificado de outra forma, o corpo da resposta está no formato JSON. Alguns endpoints não retornam um corpo de resposta; nesses casos, a propriedade `data` é omitida.

```javascript copy
const response = await octokit.request("GET /repos/{owner}/{repo}/issues/{issue_number}", {
  owner: "github",
  repo: "docs",
  issue_number: 11901,
  headers: {
    "x-github-api-version": "2026-03-10",
  },
});

console.log(`The status of the response is: ${response.status}`)
console.log(`The request URL was: ${response.url}`)
console.log(`The x-ratelimit-remaining response header is: ${response.headers["x-ratelimit-remaining"]}`)
console.log(`The issue title is: ${response.data.title}`)
```

Da mesma forma, o método `paginate` retorna uma promessa. Se a solicitação tiver sido bem-sucedida, a promessa será resolvida para uma matriz de dados retornada pelo ponto de extremidade. Ao contrário do método `request`, o método `paginate` não retorna o código de status, a URL ou os cabeçalhos.

```javascript copy
const data = await octokit.paginate("GET /repos/{owner}/{repo}/issues", {
  owner: "github",
  repo: "docs",
  per_page: 100,
  headers: {
    "x-github-api-version": "2026-03-10",
  },
});

console.log(`${data.length} issues were returned`)
console.log(`The title of the first issue is: ${data[0].title}`)
```

## Script de exemplo

Aqui está um script de exemplo completo que usa o Octokit.js. O script importa `Octokit` e cria uma instância de `Octokit`. Se você quisesse se autenticar com um GitHub App em vez de um personal access token, você importaria e instanciaria `App` em vez de `Octokit`. Para obter mais informações, confira [Como se autenticar com um GitHub App](#authenticating-with-a-github-app).

A função `getChangedFiles` obtém todos os arquivos alterados para uma solicitação de pull. A função `commentIfDataFilesChanged` chama a função `getChangedFiles`. Se qualquer um dos arquivos que a solicitação de pull alterou incluir `/data/` no caminho, a função comentará sobre a solicitação de pull.

```javascript copy
import { Octokit } from "octokit";

const octokit = new Octokit({ 
  auth: 'YOUR-TOKEN',
});

async function getChangedFiles({owner, repo, pullNumber}) {
  let filesChanged = []

  try {
    const iterator = octokit.paginate.iterator("GET /repos/{owner}/{repo}/pulls/{pull_number}/files", {
      owner: owner,
      repo: repo,
      pull_number: pullNumber,
      per_page: 100,
      headers: {
        "x-github-api-version": "2026-03-10",
      },
    });

    for await (const {data} of iterator) {
      filesChanged = [...filesChanged, ...data.map(fileData => fileData.filename)];
    }
  } catch (error) {
    if (error.response) {
      console.error(`Error! Status: ${error.response.status}. Message: ${error.response.data.message}`)
    }
    console.error(error)
  }

  return filesChanged
}

async function commentIfDataFilesChanged({owner, repo, pullNumber}) {
  const changedFiles = await getChangedFiles({owner, repo, pullNumber});

  const filePathRegex = new RegExp(/\/data\//, "i");
  if (!changedFiles.some(fileName => filePathRegex.test(fileName))) {
    return;
  }

  try {
    const {data: comment} = await octokit.request("POST /repos/{owner}/{repo}/issues/{issue_number}/comments", {
      owner: owner,
      repo: repo,
      issue_number: pullNumber,
      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.`,
      headers: {
        "x-github-api-version": "2026-03-10",
      },
    });

    return comment.html_url;
  } catch (error) {
    if (error.response) {
      console.error(`Error! Status: ${error.response.status}. Message: ${error.response.data.message}`)
    }
    console.error(error)
  }
}

await commentIfDataFilesChanged({owner: "github", repo: "docs", pullNumber: 191});
```

## Próximas etapas

* Para saber mais sobre o Octokit.js, confira a [documentação do Octokit.js](https://github.com/octokit/octokit.js/#readme).
* Para obter alguns exemplos da vida real, veja como o GitHub Docs usa o Octokit.js [pesquisando o repositório do GitHub Docs](https://github.com/search?q=repo%3Agithub%2Fdocs%20path%3A.github%20octokit\&type=code).