GitHub App toolset for Node.js
Browsers |
|
---|---|
Node |
Install with const { App, createNodeMiddleware } = require("@octokit/app"); |
[!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".
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/*
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
name | type | description |
---|---|---|
appId
|
number
|
Required. Find the App ID on the app’s about page in settings. |
privateKey
|
string
|
Required. Content of the *.pem file you downloaded from the app’s about page. You can generate a new private key if needed.
|
Octokit
|
Constructor
|
You can pass in your own Octokit constructor with custom defaults and plugins. Note that For usage with enterprise, set 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 |
log
|
object
|
Used for internal logging. Defaults to console .
|
webhooks.secret
|
string
|
Required. Secret as configured in the GitHub App's settings. |
webhooks.transform
|
function
|
Only relevant for `app.webhooks.on`. Transform emitted event before calling handlers. Can be asynchronous. |
oauth.clientId
|
number
|
Find the OAuth Client ID on the app’s about page in settings. |
oauth.clientSecret
|
number
|
Find the OAuth Client Secret on the app’s about page in settings. |
oauth.allowSignup
|
boolean
|
Sets the default value for app.oauth.getAuthorizationUrl(options) .
|
Octokit instance. Uses the Octokit
constructor option if passed.
See https://github.com/octokit/core.js#logging. Customize using the log
constructor option.
const octokit = await app.getInstallationOctokit(123);
for await (const { octokit, installation } of app.eachInstallation.iterator()) { /* ... */ }
await app.eachInstallation(({ octokit, installation }) => /* ... */)
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 }) => /* ... */)
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);
An @octokit/oauth-app
instance
A middleware is a method or set of methods to handle requests for common environments.
By default, all middlewares expose the following routes
Route | Route Description |
---|---|
POST /api/github/webhooks |
Endpoint to receive GitHub Webhook Event requests |
GET /api/github/oauth/login |
Redirects to GitHub's authorization endpoint. Accepts optional ?state query parameter. |
GET /api/github/oauth/callback |
The client's redirect endpoint. This is where the token event gets triggered |
POST /api/github/oauth/token |
Exchange an authorization code for an OAuth Access token. If successful, the token event gets triggered. |
GET /api/github/oauth/token |
Check if token is valid. Must authenticate using token in Authorization header. Uses GitHub's POST /applications/{client_id}/token endpoint |
PATCH /api/github/oauth/token |
Resets 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/token |
Invalidates current token, basically the equivalent of a logout. Must authenticate using token in Authorization header. |
DELETE /api/github/oauth/grant |
Revokes the user's grant, basically the equivalent of an uninstall. must authenticate using token in Authorization header. |
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.
name | type | description |
---|---|---|
app
|
App instance
|
Required. |
options.pathPrefix
|
string
|
All exposed paths will be prefixed with the provided prefix. Defaults to |
log
object
|
Used for internal logging. Defaults to
|
See CONTRIBUTING.md