Home

Awesome

app.js

GitHub App toolset for Node.js

@latest Build Status

<!-- toc --> <!-- tocstop -->

Usage

<table> <tbody valign=top align=left> <tr><th>

Browsers

</th><td width=100%>

@octokit/app is not meant for browser usage.

</td></tr> <tr><th>

Node

</th><td>

Install with npm install @octokit/app

const { App, createNodeMiddleware } = require("@octokit/app");
</td></tr> </tbody> </table>

[!IMPORTANT] As we use conditional exports, you will need to adapt your tsconfig.json by setting "moduleResolution": "node16", "module": "node16".

See the TypeScript docs on package.json "exports".<br> See this helpful guide on transitioning to ESM from @sindresorhus

const app = new App({
  appId: 123,
  privateKey: "-----BEGIN PRIVATE KEY-----\n...",
  oauth: {
    clientId: "0123",
    clientSecret: "0123secret",
  },
  webhooks: {
    secret: "secret",
  },
});

const { data } = await app.octokit.request("/app");
console.log("authenticated as %s", data.name);
for await (const { installation } of app.eachInstallation.iterator()) {
  for await (const { octokit, repository } of app.eachRepository.iterator({
    installationId: installation.id,
  })) {
    await octokit.request("POST /repos/{owner}/{repo}/dispatches", {
      owner: repository.owner.login,
      repo: repository.name,
      event_type: "my_event",
    });
  }
}

app.webhooks.on("issues.opened", async ({ octokit, payload }) => {
  await octokit.request(
    "POST /repos/{owner}/{repo}/issues/{issue_number}/comments",
    {
      owner: payload.repository.owner.login,
      repo: payload.repository.name,
      issue_number: payload.issue.number,
      body: "Hello World!",
    },
  );
});

app.oauth.on("token", async ({ token, octokit }) => {
  const { data } = await octokit.request("GET /user");
  console.log(`Token retrieved for ${data.login}`);
});

require("http").createServer(createNodeMiddleware(app)).listen(3000);
// can now receive requests at /api/github/*

App.defaults(options)

Create a new App with custom defaults for the constructor options

const MyApp = App.defaults({
  Octokit: MyOctokit,
});
const app = new MyApp({ clientId, clientSecret });
// app.octokit is now an instance of MyOctokit

Constructor

<table width="100%"> <thead align=left> <tr> <th width=150> name </th> <th width=70> type </th> <th> description </th> </tr> </thead> <tbody align=left valign=top> <tr> <th> <code>appId</code> </th> <th> <code>number</code> </th> <td> <strong>Required</strong>. Find the <strong>App ID</strong> on the app’s about page in settings. </td> </tr> <tr> <th> <code>privateKey</code> </th> <th> <code>string</code> </th> <td> <strong>Required</strong>. Content of the <code>*.pem</code> file you downloaded from the app’s about page. You can generate a new private key if needed. </td> </tr> <tr id="constructor-option-octokit"> <th> <code>Octokit</code> </th> <th> <code>Constructor</code> </th> <td>

You can pass in your own Octokit constructor with custom defaults and plugins. Note that authStrategy will be always be set to createAppAuth from @octokit/auth-app.

For usage with enterprise, set baseUrl to the hostname + /api/v3. Example:

const { Octokit } = require("@octokit/core");
new App({
  appId: 123,
  privateKey: "-----BEGIN PRIVATE KEY-----\n...",
  oauth: {
    clientId: 123,
    clientSecret: "secret",
  },
  webhooks: {
    secret: "secret",
  },
  Octokit: Octokit.defaults({
    baseUrl: "https://ghe.my-company.com/api/v3",
  }),
});

Defaults to @octokit/core.

</td></tr> <tr id="constructor-option-log"> <th> <code>log</code> </th> <th> <code>object</code> </th> <td> Used for internal logging. Defaults to <a href="https://developer.mozilla.org/en-US/docs/Web/API/console"><code>console</code></a>. </td> </tr> <tr> <th> <code>webhooks.secret</code> </th> <th> <code>string</code> </th> <td> <strong>Required.</strong> Secret as configured in the GitHub App's settings. </td> </tr> <tr> <th> <code>webhooks.transform</code> </th> <th> <code>function</code> </th> <td> Only relevant for `app.webhooks.on`. Transform emitted event before calling handlers. Can be asynchronous. </td> </tr> <tr> <th> <code>oauth.clientId</code> </th> <th> <code>number</code> </th> <td> Find the OAuth <strong>Client ID</strong> on the app’s about page in settings. </td> </tr> <tr> <th> <code>oauth.clientSecret</code> </th> <th> <code>number</code> </th> <td> Find the OAuth <strong>Client Secret</strong> on the app’s about page in settings. </td> </tr> <tr> <th> <code>oauth.allowSignup</code> </th> <th> <code>boolean</code> </th> <td> Sets the default value for <code>app.oauth.getAuthorizationUrl(options)</code>. </td> </tr> </tbody> </table>

API

app.octokit

Octokit instance. Uses the Octokit constructor option if passed.

app.log

See https://github.com/octokit/core.js#logging. Customize using the log constructor option.

app.getInstallationOctokit

const octokit = await app.getInstallationOctokit(123);

app.eachInstallation

for await (const { octokit, installation } of app.eachInstallation.iterator()) { /* ... */ }
await app.eachInstallation(({ octokit, installation }) => /* ... */)

app.eachRepository

for await (const { octokit, repository } of app.eachRepository.iterator()) { /* ... */ }
await app.eachRepository(({ octokit, repository }) => /* ... */)

Optionally pass installation ID to iterate through all repositories in one installation

for await (const { octokit, repository } of app.eachRepository.iterator({ installationId })) { /* ... */ }
await app.eachRepository({ installationId }, ({ octokit, repository }) => /* ... */)

app.getInstallationUrl

const installationUrl = await app.getInstallationUrl();
return res.redirect(installationUrl);

Optionally pass the ID of a GitHub organization or user to request installation on that specific target.

If the user will be sent to a redirect URL after installation (such as if you request user authorization during installation), you can also supply a state string that will be included in the query of the post-install redirect.

const installationUrl = await app.getInstallationUrl({ state, target_id });
return res.redirect(installationUrl);

app.webhooks

An @octokit/webhooks instance

app.oauth

An @octokit/oauth-app instance

Middlewares

A middleware is a method or set of methods to handle requests for common environments.

By default, all middlewares expose the following routes

RouteRoute Description
POST /api/github/webhooksEndpoint to receive GitHub Webhook Event requests
GET /api/github/oauth/loginRedirects to GitHub's authorization endpoint. Accepts optional ?state query parameter.
GET /api/github/oauth/callbackThe client's redirect endpoint. This is where the token event gets triggered
POST /api/github/oauth/tokenExchange an authorization code for an OAuth Access token. If successful, the token event gets triggered.
GET /api/github/oauth/tokenCheck if token is valid. Must authenticate using token in Authorization header. Uses GitHub's POST /applications/{client_id}/token endpoint
PATCH /api/github/oauth/tokenResets a token (invalidates current one, returns new token). Must authenticate using token in Authorization header. Uses GitHub's PATCH /applications/{client_id}/token endpoint.
DELETE /api/github/oauth/tokenInvalidates current token, basically the equivalent of a logout. Must authenticate using token in Authorization header.
DELETE /api/github/oauth/grantRevokes the user's grant, basically the equivalent of an uninstall. must authenticate using token in Authorization header.

createNodeMiddleware(app, options)

Middleware for Node's built in http server or express.

const { App, createNodeMiddleware } = require("@octokit/app");

const app = new App({
  appId: 123,
  privateKey: "-----BEGIN PRIVATE KEY-----\n...",
  oauth: {
    clientId: "0123",
    clientSecret: "0123secret",
  },
  webhooks: {
    secret: "secret",
  },
});

const middleware = createNodeMiddleware(app);
require("http")
  .createServer(async (req, res) => {
    // `middleware` returns `false` when `req` is unhandled (beyond `/api/github`)
    if (await middleware(req, res)) return;
    res.writeHead(404);
    res.end();
  })
  .listen(3000);
// can now receive user authorization callbacks at /api/github/*

The middleware returned from createNodeMiddleware can also serve as an Express.js middleware directly.

<table width="100%"> <thead align=left> <tr> <th width=150> name </th> <th width=70> type </th> <th> description </th> </tr> </thead> <tbody align=left valign=top> <tr> <th> <code>app</code> </th> <th> <code>App instance</code> </th> <td> <strong>Required</strong>. </td> </tr> <tr> <th> <code>options.pathPrefix</code> </th> <th> <code>string</code> </th> <td>

All exposed paths will be prefixed with the provided prefix. Defaults to "/api/github"

</td> </tr> <tr> <td> <code>log</code> <em> object </em> </td> <td>

Used for internal logging. Defaults to console with debug and info doing nothing.

  </td>
</tr>
</tbody> </table>

Contributing

See CONTRIBUTING.md

License

MIT