What happened?
GItHub Octokit throws 401 error with GitHub App. Here is the code looks like
import dotenv from 'dotenv'
import fs from 'fs'
import http from 'http'
import { Octokit, App } from 'octokit'
import { createNodeMiddleware } from '@octokit/webhooks'
import { createAppAuth } from "@octokit/auth-app";
// Load environment variables from .env file
dotenv.config()
// Set configured values
const { APP_ID, ENTERPRISE_HOSTNAME, GITHUB_TOKEN, PRIVATE_KEY_PATH, WEBHOOK_SECRET, CLIENT_ID, CLIENT_SECRET } = process.env
const PRIVATE_KEY = fs.readFileSync(PRIVATE_KEY_PATH, 'utf8')
// Create an authenticated Octokit client authenticated as a GitHub App
const app = new App({
appId: APP_ID,
privateKey: PRIVATE_KEY,
webhooks: {
secret: WEBHOOK_SECRET
},
...(ENTERPRISE_HOSTNAME && {
Octokit: Octokit.defaults({
auth: GITHUB_TOKEN,
baseUrl: `https://${ENTERPRISE_HOSTNAME}/api/v3`
})
})
})
app.webhooks.on('pull_request.opened', async ({ octokit, payload }) => {
try {
await octokit.rest.pulls.createReviewComment({
owner: payload.repository.owner.login,
repo: payload.repository.name,
issue_number: payload.pull_request.number,
body: "Add new code review comment"
})
} catch (error) {
if (error.response) {
console.error(`Error! Status 3: ${error.response.status}. Message: ${error.response.data.message}`)
} else {
console.error(error)
}
}
try {
const response = await octokit.rest.pulls.listFiles({
owner: payload.repository.owner.login,
repo: payload.repository.name,
issue_number: payload.pull_request.number
})
console.log('Response: ', JSON.stringify(response))
} catch (error) {
if (error.response) {
console.error(`Error! Status 4: ${error.response.status}. Message: ${error.response.data.message}`)
} else {
console.error(error)
}
}
try {
await octokit.rest.pulls.requestReviewers({
owner: payload.repository.owner.login,
repo: payload.repository.name,
issue_number: payload.pull_request.number,
reviewers: ["user1"]
})
} catch (error) {
if (error.response) {
console.error(`Error! Status 5: ${error.response.status}. Message: ${error.response.data.message}`)
} else {
console.error(error)
}
}
})
app.webhooks.onError((error) => {
if (error.name === 'AggregateError') {
console.log(`Error processing request: ${error.event}`)
} else {
console.log(error)
}
})
// Launch a web server to listen for GitHub webhooks
const port = process.env.PORT || 3004
const path = '/api/webhook'
const localWebhookUrl = `http://localhost:${port}${path}`
// See https://github.com/octokit/webhooks.js/#createnodemiddleware for all options
const middleware = createNodeMiddleware(app.webhooks, { path })
http.createServer(middleware).listen(port, () => {
console.log(`Server is listening for events at: ${localWebhookUrl}`)
console.log('Press Ctrl + C to quit.')
})
Note –
All the values for APP_ID, ENTERPRISE_HOSTNAME, GITHUB_TOKEN, PRIVATE_KEY_PATH, WEBHOOK_SECRET seems to be correct and verified.
Versions
Node v18, Octokit v4.0.2
Relevant log output
Error! Status 3: 401. Message: Must authenticate to access this API.
Error! Status 4: 401. Message: Must authenticate to access this API.
Error! Status 5: 401. Message: Must authenticate to access this API.
Without try catch:
AggregateError:
HttpError: Unauthorized. "POST /repos/{owner}/{repo}/pulls/{pull_number}/comments" failed most likely due to lack of authentication. Reason: "installation" key missing in webhook event payload
at file:///Users/user1/Documents/project/mytestapp/node_modules/octokit/node_modules/@octokit/request/dist-bundle/index.js:106:21
at async requestWithGraphqlErrorHandling (file:///Users/user1/Documents/project/mytestapp/node_modules/octokit/node_modules/@octokit/plugin-retry/dist-bundle/index.js:36:20)
at async Job.doExecute (/Users/user1/Documents/project/mytestapp/node_modules/bottleneck/light.js:405:18)
at file:///Users/user1/Documents/project/mytestapp/node_modules/@octokit/webhooks/dist-bundle/index.js:416:19
at async middleware (file:///Users/user1/Documents/project/mytestapp/node_modules/@octokit/webhooks/dist-bundle/index.js:604:5) {
event: {
id: '6fdae3a0-3d0d-11ef-833a-9857aeba7dcd',
name: 'pull_request',
payload: {
action: 'opened',
number: 62,
pull_request: [Object],
repository: [Object],
enterprise: [Object],
sender: [Object]
}
},
errors: [
RequestError [HttpError]: Unauthorized. "POST /repos/{owner}/{repo}/pulls/{pull_number}/comments" failed most likely due to lack of authentication. Reason: "installation" key missing in webhook event payload
at file:///Users/user1/Documents/project/mytestapp/node_modules/octokit/node_modules/@octokit/request/dist-bundle/index.js:106:21
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
at async requestWithGraphqlErrorHandling (file:///Users/user1/Documents/project/mytestapp/node_modules/octokit/node_modules/@octokit/plugin-retry/dist-bundle/index.js:36:20)
at async Job.doExecute (/Users/user1/Documents/project/mytestapp/node_modules/bottleneck/light.js:405:18) {
status: 401,
request: [Object],
response: [Object],
event: [Object]
}
]
}