Giter Club home page Giter Club logo

webhooks.js's Introduction

@octokit/webhooks

GitHub webhook events toolset for Node.js

@latest Test

@octokit/webhooks helps to handle webhook events received from GitHub.

GitHub webhooks can be registered in multiple ways

  1. In repository or organization settings on github.com.
  2. Using the REST API for repositories or organizations
  3. By creating a GitHub App.

Note that while setting a secret is optional on GitHub, it is required to be set in order to use @octokit/webhooks. Content Type must be set to application/json, application/x-www-form-urlencoded is not supported.

Usage

// install with: npm install @octokit/webhooks
import { Webhooks, createNodeMiddleware } from "@octokit/webhooks";
import { createServer } from "node:http";
const webhooks = new Webhooks({
  secret: "mysecret",
});

webhooks.onAny(({ id, name, payload }) => {
  console.log(name, "event received");
});

createServer(createNodeMiddleware(webhooks)).listen(3000);
// can now receive webhook events at /api/github/webhooks

Local development

You can receive webhooks on your local machine or even browser using EventSource and smee.io.

Go to smee.io and Start a new channel. Then copy the "Webhook Proxy URL" and

  1. enter it in the GitHub App’s "Webhook URL" input
  2. pass it to the EventSource constructor, see below
const webhookProxyUrl = "https://smee.io/IrqK0nopGAOc847"; // replace with your own Webhook Proxy URL
const source = new EventSource(webhookProxyUrl);
source.onmessage = (event) => {
  const webhookEvent = JSON.parse(event.data);
  webhooks
    .verifyAndReceive({
      id: webhookEvent["x-request-id"],
      name: webhookEvent["x-github-event"],
      signature: webhookEvent["x-hub-signature"],
      payload: JSON.stringify(webhookEvent.body),
    })
    .catch(console.error);
};

EventSource is a native browser API and can be polyfilled for browsers that don’t support it. In node, you can use the eventsource package: install with npm install eventsource, then import EventSource from "eventsource";)

API

  1. Constructor
  2. webhooks.sign()
  3. webhooks.verify()
  4. webhooks.verifyAndReceive()
  5. webhooks.receive()
  6. webhooks.on()
  7. webhooks.onAny()
  8. webhooks.onError()
  9. webhooks.removeListener()
  10. createNodeMiddleware()
  11. Webhook events
  12. emitterEventNames

Constructor

new Webhooks({ secret /*, transform */ });
secret (String) Required. Secret as configured in GitHub Settings.
transform (Function) Only relevant for webhooks.on. Transform emitted event before calling handlers. Can be asynchronous.
log object

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

Returns the webhooks API.

webhooks.sign()

webhooks.sign(eventPayload);
eventPayload (String) Required. Webhook request payload as received from GitHub

Returns a signature string. Throws error if eventPayload is not passed.

The sign method can be imported as static method from @octokit/webhooks-methods.

webhooks.verify()

webhooks.verify(eventPayload, signature);
eventPayload (String) Required. Webhook event request payload as received from GitHub.
signature (String) Required. Signature string as calculated by webhooks.sign().

Returns true or false. Throws error if eventPayload or signature not passed.

The verify method can be imported as static method from @octokit/webhooks-methods.

webhooks.verifyAndReceive()

webhooks.verifyAndReceive({ id, name, payload, signature });
id String Unique webhook event request id
name String Required. Name of the event. (Event names are set as X-GitHub-Event header in the webhook event request.)
payload String Required. Webhook event request payload as received from GitHub.
signature (String) Required. Signature string as calculated by webhooks.sign().

Returns a promise.

Verifies event using webhooks.verify(), then handles the event using webhooks.receive().

Additionally, if verification fails, rejects the returned promise and emits an error event.

Example

import { Webhooks } from "@octokit/webhooks";
const webhooks = new Webhooks({
  secret: "mysecret",
});
eventHandler.on("error", handleSignatureVerificationError);

// put this inside your webhooks route handler
eventHandler
  .verifyAndReceive({
    id: request.headers["x-github-delivery"],
    name: request.headers["x-github-event"],
    payload: request.body,
    signature: request.headers["x-hub-signature-256"],
  })
  .catch(handleErrorsFromHooks);

webhooks.receive()

webhooks.receive({ id, name, payload });
id String Unique webhook event request id
name String Required. Name of the event. (Event names are set as X-GitHub-Event header in the webhook event request.)
payload Object Required. Webhook event request payload as received from GitHub.

Returns a promise. Runs all handlers set with webhooks.on() in parallel and waits for them to finish. If one of the handlers rejects or throws an error, then webhooks.receive() rejects. The returned error has an .errors property which holds an array of all errors caught from the handlers. If no errors occur, webhooks.receive() resolves without passing any value.

The .receive() method belongs to the event-handler module which can be used standalone.

webhooks.on()

webhooks.on(eventName, handler);
webhooks.on(eventNames, handler);
eventName String Required. Name of the event. One of GitHub's supported event names, or (if the event has an action property) the name of an event followed by its action in the form of <event>.<action>.
eventNames Array Required. Array of event names.
handler Function Required. Method to be run each time the event with the passed name is received. the handler function can be an async function, throw an error or return a Promise. The handler is called with an event object: {id, name, payload}.

The .on() method belongs to the event-handler module which can be used standalone.

webhooks.onAny()

webhooks.onAny(handler);
handler Function Required. Method to be run each time any event is received. the handler function can be an async function, throw an error or return a Promise. The handler is called with an event object: {id, name, payload}.

The .onAny() method belongs to the event-handler module which can be used standalone.

webhooks.onError()

webhooks.onError(handler);

If a webhook event handler throws an error or returns a promise that rejects, an error event is triggered. You can use this handler for logging or reporting events. The passed error object has a .event property which has all information on the event.

Asynchronous error event handler are not blocking the .receive() method from completing.

handler Function Required. Method to be run each time a webhook event handler throws an error or returns a promise that rejects. The handler function can be an async function, return a Promise. The handler is called with an error object that has a .event property which has all the information on the event: {id, name, payload}.

The .onError() method belongs to the event-handler module which can be used standalone.

webhooks.removeListener()

webhooks.removeListener(eventName, handler);
webhooks.removeListener(eventNames, handler);
eventName String Required. Name of the event. One of GitHub's supported event names, or (if the event has an action property) the name of an event followed by its action in the form of <event>.<action>, or '*' for the onAny() method or 'error' for the onError() method.
eventNames Array Required. Array of event names.
handler Function Required. Method which was previously passed to webhooks.on(). If the same handler was registered multiple times for the same event, only the most recent handler gets removed.

The .removeListener() method belongs to the event-handler module which can be used standalone.

createNodeMiddleware()

import { createServer } from "node:http";
import { Webhooks, createNodeMiddleware } from "@octokit/webhooks";

const webhooks = new Webhooks({
  secret: "mysecret",
});

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

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

webhooks Webhooks instance Required.
path string Custom path to match requests against. Defaults to /api/github/webhooks.
log object

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

Webhook events

See the full list of event types with example payloads.

If there are actions for a webhook, events are emitted for both, the webhook name as well as a combination of the webhook name and the action, e.g. installation and installation.created.

Event Actions
branch_protection_configuration disabled
enabled
branch_protection_rule created
deleted
edited
check_run completed
created
requested_action
rerequested
check_suite completed
requested
rerequested
code_scanning_alert appeared_in_branch
closed_by_user
created
fixed
reopened
reopened_by_user
commit_comment created
create
custom_property created
deleted
updated
custom_property_values updated
delete
dependabot_alert auto_dismissed
auto_reopened
created
dismissed
fixed
reintroduced
reopened
deploy_key created
deleted
deployment created
deployment_protection_rule requested
deployment_review approved
rejected
requested
deployment_status created
discussion answered
category_changed
closed
created
deleted
edited
labeled
locked
pinned
reopened
transferred
unanswered
unlabeled
unlocked
unpinned
discussion_comment created
deleted
edited
fork
github_app_authorization revoked
gollum
installation created
deleted
new_permissions_accepted
suspend
unsuspend
installation_repositories added
removed
installation_target renamed
issue_comment created
deleted
edited
issues assigned
closed
deleted
demilestoned
edited
labeled
locked
milestoned
opened
pinned
reopened
transferred
unassigned
unlabeled
unlocked
unpinned
label created
deleted
edited
marketplace_purchase cancelled
changed
pending_change
pending_change_cancelled
purchased
member added
edited
removed
membership added
removed
merge_group checks_requested
destroyed
meta deleted
milestone closed
created
deleted
edited
opened
org_block blocked
unblocked
organization deleted
member_added
member_invited
member_removed
renamed
package published
updated
page_build
personal_access_token_request approved
cancelled
created
denied
ping
project closed
created
deleted
edited
reopened
project_card converted
created
deleted
edited
moved
project_column created
deleted
edited
moved
projects_v2 closed
created
deleted
edited
reopened
projects_v2_item archived
converted
created
deleted
edited
reordered
restored
public
pull_request assigned
auto_merge_disabled
auto_merge_enabled
closed
converted_to_draft
demilestoned
dequeued
edited
enqueued
labeled
locked
milestoned
opened
ready_for_review
reopened
review_request_removed
review_requested
synchronize
unassigned
unlabeled
unlocked
pull_request_review dismissed
edited
submitted
pull_request_review_comment created
deleted
edited
pull_request_review_thread resolved
unresolved
push
registry_package published
updated
release created
deleted
edited
prereleased
published
released
unpublished
repository archived
created
deleted
edited
privatized
publicized
renamed
transferred
unarchived
repository_advisory published
reported
repository_dispatch sample
repository_import
repository_ruleset created
deleted
edited
repository_vulnerability_alert create
dismiss
reopen
resolve
secret_scanning_alert created
reopened
resolved
revoked
validated
secret_scanning_alert_location created
security_advisory published
updated
withdrawn
security_and_analysis
sponsorship cancelled
created
edited
pending_cancellation
pending_tier_change
tier_changed
star created
deleted
status
team added_to_repository
created
deleted
edited
removed_from_repository
team_add
watch started
workflow_dispatch
workflow_job completed
in_progress
queued
waiting
workflow_run completed
in_progress
requested

emitterEventNames

A read only tuple containing all the possible combinations of the webhook events + actions listed above. This might be useful in GUI and input validation.

import { emitterEventNames } from "@octokit/webhooks";
emitterEventNames; // ["check_run", "check_run.completed", ...]

TypeScript

The types for the webhook payloads are sourced from @octokit/openapi-webhooks-types, which can be used by themselves.

In addition to these types, @octokit/webhooks exports 2 types specific to itself:

Note that changes to the exported types are not considered breaking changes, as the changes will not impact production code, but only fail locally or during CI at build time.

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

⚠️ Caution ⚠️: Webhooks Types are expected to be used with the strictNullChecks option enabled in your tsconfig. If you don't have this option enabled, there's the possibility that you get never as the inferred type in some use cases. See octokit/webhooks#395 for details.

EmitterWebhookEventName

A union of all possible events and event/action combinations supported by the event emitter, e.g. "check_run" | "check_run.completed" | ... many more ... | "workflow_run.requested".

EmitterWebhookEvent

The object that is emitted by @octokit/webhooks as an event; made up of an id, name, and payload properties. An optional generic parameter can be passed to narrow the type of the name and payload properties based on event names or event/action combinations, e.g. EmitterWebhookEvent<"check_run" | "code_scanning_alert.fixed">.

License

MIT

webhooks.js's People

Contributors

aidant avatar ankeetmaini avatar codebytere avatar copperwall avatar dependabot[bot] avatar g-rath avatar gimenete avatar github-actions[bot] avatar gr2m avatar greenkeeper[bot] avatar jablko avatar jakemwood avatar joao-paulo-parity avatar jovel avatar jstastny avatar kfcampbell avatar lumaxis avatar mikey923 avatar monsonjeremy avatar nbransby avatar nickfloyd avatar nogs avatar octokitbot avatar oscard0m avatar prettier-toc-me[bot] avatar renovate[bot] avatar spencerkaiser avatar srujandeshpande avatar uzlopak avatar wolfy1339 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

webhooks.js's Issues

Allow to inject parameters into webhook handlers

For the upcoming octokit we need to be able to inject a pre-authenticated octokit client to the webhooks handler, see the Webhooks section

const webhooks = client.webhooks({secret})
webhooks.on('issue.opened', ({id, name, payload, client}) => {
  return client.rest.issues.createComment({body: 'Hello, World!'})
})
require('http').createServer(webhooks.middleware).listen(3000)

The client parameter in the code snippet above needs to be injected, it is not part of @octokit/webhooks API. We need to be able to run code after a webhook is received, but before it is passed to the webhook handlers.

One approach would be to implement middleware similar to what Express does: https://expressjs.com/en/guide/using-middleware.html. There is a related issue on Probot: probot/probot#598

An alternative would be to leverage the hook API that we already use in @octokit/rest and that will be part of octokit: https://github.com/octokit/rest.js#hooks.

verifyAndReceive fails depending on json details

Summary

verifyAndReceive uses a parsed representation of the passed json data. This can lead to false negative signature verifications. One Example is the signature verification failure for ANSI/ISO-6429 codes a.k.a. escape sequences. If Any GitHub event body contains an escape sequence, the verification will always fail, even though everything is valid.

Details

When the ESC sequence is json-encoded it might be encoded as \u001b OR \u001B.
The node json parser will always encode this sequence with a lowercase b, which means that the verification will fail if the signature was generated with a capital B (which is already the case).
Since this (and other encoding details) are ambiguous in the json standard, the only safe option is to verify the signature with the raw body we receive and not with the parsed representation, since JSON.stringify(JSON.parse(x)) does not necessarily yield x, thus causing a false negative.
This however is only one example, that already happens. In general, the only way that will guarantee that we properly verify the signature header is, using the data in the format it was encoded in the first place. This means, before parsing it.

Suggestion

In order to solve the problem, middleware/middleware might need to be adjusted, together with get-payload and verify-and-receive.
I was already working on that when a realised the following compatibility issues:

Compatibility concerns

  1. verifyAndReceived is part of the public API, meaning people are using it directly and outside of the middleware context. (I saw it in some PR discussions). This means this function has to stay and still work with parsed data instead of json.
  2. Since this PR octokit is supporting the usage in combination with body-parser, which will also store parsed information in request.body

It seems as if we need to keep the verification based on parsed data, if we want to support the mix of body-parser and webhook.js. We could also store the raw body in the request object.

A compromise could be:
testing if req.body is defined and if that is the case, we could use the current implementation.
Also keep the current implementation of verifyAndReceive exposed and (maybe?) deprecate it.
In order to fix our bug, we could just add a second verify and receive implementation that does the verification with the raw data.
This however would duplicate a lot of code and I am not sure what you think about this.

I hope we can figure out a way to fix this bug. This is just my view on things, maybe somebody has a better suggestion on how to address this issue.

Related issues

  • This issue might be related to: #61
  • There are also several slack discussions raising this topic (Non ANSI code support)

/cc @gr2m

Asserting webhook names is not future-proof

throw new Error(`${webhookNameOrNames} is not a valid webhook name`)

Limiting the events that can be received to this list has two issues:

  1. This library can't be used by beta testers for webhooks that are not yet unreleased
  2. I think there are some undocumented webhooks for GitHub Enterprise. I can't find the list right now, but will try to locate it

It'd be great if the assertions could be turned off, or turned into just warnings.

Support generics in generated types

Hey guys 🙂

First off, thanks for the awesome project! After #168 got merged I started using generated types for workflow_dispatch event and it works great. However having to type cast inputs of the event through any pains me a lot:

type WebhookPayloadWorkflowDispatchInputs = {};
type WebhookPayloadWorkflowDispatch = {
  inputs: WebhookPayloadWorkflowDispatchInputs;
  ref: string;
  repository: PayloadRepository;
  organization: WebhookPayloadWorkflowDispatchOrganization;
  sender: WebhookPayloadWorkflowDispatchSender;
  workflow: string;
};
type FooBarInput = { foo: string; bar: string };

const onWorkflowDispatch = (event: Webhooks.WebhookPayloadWorkflowDispatch) => {
  const { foo, bar } = (event.inputs as any) as FooBarInput;
  ...
}

However, I do believe that a better developer experience can be achieved by introducing generics in generated types:

type WebhookPayloadWorkflowDispatch<T> = {
  inputs: T;
  ref: string;
  repository: PayloadRepository;
  organization: WebhookPayloadWorkflowDispatchOrganization;
  sender: WebhookPayloadWorkflowDispatchSender;
  workflow: string;
};
type FooBarInput = { foo: string; bar: string };

const onWorkflowDispatch = (event: Webhooks.WebhookPayloadWorkflowDispatch<FooBarInput>) => {
  const { foo, bar } = event.inputs;
  ...
}

It is something that should be raised here or in gimenete/type-writer? I'd be happy to move this issue there if that's the case. Anyway, I would be happy to assist with a PR if/when we figure out some kind of a solution for this.

throw a helpful error if received request has content type set to `application/x-www-form-url-encoded`

I ran into this issue and though it was never resolved, it appears tha the underlying problem is that @octokit/wehooks is assuming that the incoming request body is application/json. However, github can also deliver payloads in application/x-www-form-url-encoded which is, in fact, the default delivery format when creating a webhook via the github UI

image

In the event that the payload is encoded as application/x-www-form-urlencoded, the middleware will try to parse it as JSON.

I could see two possible solutions:

  1. asserting that the content-type header is aapplication/json, and rejecting with a 400 and a status text that clearly indicates that x-form-url-encoded is not acceptable, and that the webhook configuration should be updated.
  2. checking the content-type and decoding the payload appropriately for both application/json and application/x-form-www-url-encoded.

Would be happy to help implement either.

[question/proposal] use of enums for event names?

[❓question] Would have sense to use enums for event names?

webhooks.js/index.d.ts

Lines 4402 to 4417 in 5ca6c8a

event:
| "pull_request"
| "pull_request.assigned"
| "pull_request.closed"
| "pull_request.edited"
| "pull_request.labeled"
| "pull_request.locked"
| "pull_request.opened"
| "pull_request.ready_for_review"
| "pull_request.reopened"
| "pull_request.review_request_removed"
| "pull_request.review_requested"
| "pull_request.unassigned"
| "pull_request.unlabeled"
| "pull_request.unlocked"
| "pull_request.synchronize",

A use case where it would be valuable is to make sure the events to be listened webhooks.on([<eventName>]) are the right ones on compile time.

If you think is a valid proposal I would be more than happy to propose a pull-request for it! :)

Readme Example Fails to Compile with TypeScript

Hello! I attempted to build a new TypeScript project that consumes this module. I created a package.json and installed the following dependencies:

{
  "dependencies": {
    "@octokit/webhooks": "5.3.3"
  },
  "devDependencies": {
    "@types/node": "^11.12.0",
    "typescript": "^3.3.4000"
  }
}

I took the example from the readme and fixed the imports to work with TypeScript but it fails to compile:

// TypeScript default import syntax
import * as WebhooksApi from '@octokit/webhooks';
import * as http from 'http';

const webhooks = new WebhooksApi({
  secret: 'mysecret'
});

webhooks.on('*', ({id, name, payload}) => {
  console.log(name, 'event received');
});

http.createServer(webhooks.middleware).listen(3000);
//                ~~~~~~~~~~~~~~~~~~~
// TS2559: Type '(request: ClientRequest, response: ServerResponse, next: (err?: any) => void) => (request: IncomingMessage, response: ServerResponse) => void' has no properties in common with type 'ServerOptions'.

I would expect that this code example would successfully compile. What is going on here? It looks like middleware is not a http.RequestListener, but a function that returns a http.RequestListener. Is this merely an issue with the definition of middleware in index.d.ts?

Thanks for your help!

Impossibility to send correctly signed payload from other languages

When trying to send a request with correct payload from PHP I am stuck with the issue that a correctly signed payload doesn't pass signature verification due to its conversion from string to object in middleware/get-payload.js. Original payload is coming as a string and the string is correctly signed with SHA1. But after parsing the string it becomes an object and after that the signature to be compared is calculated on the object being converted back to the string with formatting. I cannot emulate the same string structure.

References to `receiver` in README

There are several references to receiver in the docs and dead links linking to /receiver. I tried to find the relevant directory/package, but didn't find anything.

The automated release is failing 🚨

🚨 The automated release from the master branch failed. 🚨

I recommend you give this issue a high priority, so other packages depending on you could benefit from your bug fixes and new features.

You can find below the list of errors reported by semantic-release. Each one of them has to be resolved in order to automatically publish your package. I’m sure you can resolve this 💪.

Errors are usually caused by a misconfiguration or an authentication problem. With each error reported below you will find explanation and guidance to help you to resolve it.

Once all the errors are resolved, semantic-release will release your package the next time you push a commit to the master branch. You can also manually restart the failed CI job that runs semantic-release.

If you are not sure how to resolve this, here is some links that can help you:

If those don’t help, or if this issue is reporting something you think isn’t right, you can always ask the humans behind semantic-release.


No npm token specified.

An npm token must be created and set in the NPM_TOKEN environment variable on your CI environment.

Please make sure to create an npm token and to set it in the NPM_TOKEN environment variable on your CI environment. The token must allow to publish to the registry https://registry.npmjs.org/.


Good luck with your project ✨

Your semantic-release bot 📦🚀

[TypeScript] do not restrict return/resolve type of `.on()` callback

I don't see a reason why we should restrict what the .on(event, callback) callback function returns. People use early returns or want to return promises in non-async callback functions.

This code currently emits TypeScript errors

webhooks.on("issues", () => {
  return 1;
});
webhooks.on("issues", () => {
  return Promise.resolve(1);
});
webhooks.on("issues", async () => {
  return "foo";
});

I don't think it should. We should allow for any return type, both synchronous and asynchronous

Error handler is not called in case of missing headers

Hi there 👋
I am opening this regarding some findings from the issue probot/probot#568

While debugging to understand the error, I noticed that if the header X-Hub-Signature is missing (or any header actually) a 400 error response is sent, but the error is never propagated to the error handler (in that case, probot):

const missingHeaders = getMissingHeaders(request).join(', ')
if (missingHeaders) {
debug(`ignored: ${request.method} ${request.url} due to missing headers: ${missingHeaders}`)
response.statusCode = 400
response.end(`Required headers missing: ${missingHeaders}`)
return
}

Sorry if I got it wrong, but shouldn't it be calling the error handler like the case with an invalid signature?

if (!matchesSignature) {
const error = new Error('signature does not match event payload and secret')
error.event = event
error.status = 400
return state.eventHandler.receive(error)
}

Type error when using strict type checking

Hello! I've come across an interesting bug in the type definitions when recently updating

$ tsc
node_modules/@octokit/webhooks/index.d.ts:5004:17 - error TS7010: 'createWebhooksApi', which lacks return-type annotation, implicitly has an 'any' return type.

5004 export function createWebhooksApi(options?: Options);
                     ~~~~~~~~~~~~~~~~~


Found 1 error.

I can work around this using the skipLibCheck option for tsc, but skipping all 3rd party type defs is clearly not ideal 😄

Any chance you'd consider updating the types here?

Webhook mocks/fixtures

moving from gr2m/octokit-webhooks.js-legacy#8 @rtsao, @JasonEtco


Per probot/probot#316 (comment), for testing probot apps, it would be ideal to have a node-github-like API to programmatically generate webhook fixtures, for example something like:

let robot = /* ... */

let github = new MockGitHub();
let repo = github.mocks.repo({
  org: 'test-org',
  name: 'test-repo'
});

robot.auth = () => Promise.resolve(github);

let webhook = github.issues.edited(
  repo.issue({
    body: 'new issue body'
  })
);

await robot.recieve(webhook);

/* ... assertions ... */

Security Advisory event payload is missing the name of the repo for which the advisory was issued

Hi,
I am not sure whether this is the right place to post this issue (or whether this is intentional), fell free to guide me there.
I am creating a github app for tracking security vulnerabilities in the repos of my organisation. I was checking the security advisory event, but the event payload is missing the repository field for which the advisory was issued. I wanted to create automated issues on repos when the advisory is published, but the missing field makes it really difficult.
Another way would be to fetch security advisories of all the repos in the organisation, but it looks very counter-productive (Not to mention we have around 2K repos in the organisation).

The automated release is failing 🚨

🚨 The automated release from the master branch failed. 🚨

I recommend you give this issue a high priority, so other packages depending on you could benefit from your bug fixes and new features.

You can find below the list of errors reported by semantic-release. Each one of them has to be resolved in order to automatically publish your package. I’m sure you can resolve this 💪.

Errors are usually caused by a misconfiguration or an authentication problem. With each error reported below you will find explanation and guidance to help you to resolve it.

Once all the errors are resolved, semantic-release will release your package the next time you push a commit to the master branch. You can also manually restart the failed CI job that runs semantic-release.

If you are not sure how to resolve this, here is some links that can help you:

If those don’t help, or if this issue is reporting something you think isn’t right, you can always ask the humans behind semantic-release.


Invalid npm token.

The npm token configured in the NPM_TOKEN environment variable must be a valid token allowing to publish to the registry https://registry.npmjs.org/.

If you are using Two-Factor Authentication, make configure the auth-only level is supported. semantic-release cannot publish with the default auth-and-writes level.

Please make sure to set the NPM_TOKEN environment variable in your CI with the exact value of the npm token.


Good luck with your project ✨

Your semantic-release bot 📦🚀

An in-range update of semantic-release is breaking the build 🚨

Version 15.5.1 of semantic-release was just published.

Branch Build failing 🚨
Dependency semantic-release
Current Version 15.5.0
Type devDependency

This version is covered by your current version range and after updating it in your project the build failed.

semantic-release is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.

Status Details
  • continuous-integration/travis-ci/push The Travis CI build could not complete due to an error Details

Release Notes v15.5.1

15.5.1 (2018-06-06)

Bug Fixes

  • plugin-load: clarify load message (6a36832), closes #811
Commits

The new version differs by 6 commits.

  • 6a36832 fix(plugin-load): clarify load message
  • 4d47b20 docs: clarify config file format
  • ddcf29a chore(package): update nyc to version 12.0.1
  • 4c157f3 docs(plugins): add semantic-release-vsce
  • c6636ab docs(plugins): remove warning
  • 44fd7fe chore(package): update delay to version 3.0.0

See the full diff

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

TypeError [ERR_INVALID_ARG_TYPE]: The "chunk" argument must be one of type string or Buffer. Received type object

I have this code

const SmeeClient = require('smee-client')

process.env["NODE_TLS_REJECT_UNAUTHORIZED"] = 0;

const smee = new SmeeClient({
  source: 'https://smee.io/ou0EqBOIPJ1QuwDQ',
  target: 'https://localhost:453/webhook/documentsigning',
  logger: console
})

const events = smee.start()

When I have a request from docusign to 'https://smee.io/ou0EqBOIPJ1QuwDQ' this throws and app stop. Error message is attached:

_http_outgoing.js:690
      throw new ERR_INVALID_ARG_TYPE('chunk', ['string', 'Buffer'], chunk);
      ^

TypeError [ERR_INVALID_ARG_TYPE]: The "chunk" argument must be one of type string or Buffer. Received type object
    at ClientRequest.end (_http_outgoing.js:690:13)
    at Request._end (C:\Users\User\Desktop\proxy\node_modules\superagent\lib\node\index.js:1021:9)
    at Request.end (C:\Users\User\Desktop\proxy\node_modules\superagent\lib\node\index.js:777:15)
    at Client.onmessage (C:\Users\User\Desktop\proxy\node_modules\smee-client\index.js:35:9)
    at EventSource.emit (events.js:189:13)
    at _emit (C:\Users\User\Desktop\proxy\node_modules\eventsource\lib\eventsource.js:242:17)
    at parseEventStreamLine (C:\Users\User\Desktop\proxy\node_modules\eventsource\lib\eventsource.js:257:9)
    at IncomingMessage.<anonymous> (C:\Users\User\Desktop\proxy\node_modules\eventsource\lib\eventsource.js:217:11)
    at IncomingMessage.emit (events.js:189:13)
    at addChunk (_stream_readable.js:284:12)

Enable programmatic access to webhook event list

👋 It'd be really helpful to expose the list of available webhook events as a JSON-consumable object or array. Type definitions are great, but in a use-case where, for example, I want to expose that list via a <select> dropdown, I'd need to loop through the list. So something auto generated like the TypeScript definitions, but require-able.

Something like:

const events = require('@octokit/webhooks/events')
console.log(events)

// Actions as array items
// -> { issues: ['opened', 'closed'], pull_request: ['synchronize'] }

// Just a big ol' array
// -> ['issues', 'issues.opened', 'issues.closed', 'pull_request', 'pull_request.synchronize']

I can carve out some time to open this as a PR in a couple weeks if that'd help!

Version 10 of node.js has been released

Version 10 of Node.js (code name Dubnium) has been released! 🎊

To see what happens to your code in Node.js 10, Greenkeeper has created a branch with the following changes:

  • Added the new Node.js version to your .travis.yml

If you’re interested in upgrading this repo to Node.js 10, you can open a PR with these changes. Please note that this issue is just intended as a friendly reminder and the PR as a possible starting point for getting your code running on Node.js 10.

More information on this issue

Greenkeeper has checked the engines key in any package.json file, the .nvmrc file, and the .travis.yml file, if present.

  • engines was only updated if it defined a single version, not a range.
  • .nvmrc was updated to Node.js 10
  • .travis.yml was only changed if there was a root-level node_js that didn’t already include Node.js 10, such as node or lts/*. In this case, the new version was appended to the list. We didn’t touch job or matrix configurations because these tend to be quite specific and complex, and it’s difficult to infer what the intentions were.

For many simpler .travis.yml configurations, this PR should suffice as-is, but depending on what you’re doing it may require additional work or may not be applicable at all. We’re also aware that you may have good reasons to not update to Node.js 10, which is why this was sent as an issue and not a pull request. Feel free to delete it without comment, I’m a humble robot and won’t feel rejected 🤖


FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

WebHookPayloadPullRequest.installation is missing from typings

The TypeScript typings for the installation field on WebHookPayloadPullRequest is missing:

type WebhookPayloadPullRequest = {
action: string;
number: number;
pull_request: WebhookPayloadPullRequestPullRequest;
repository: PayloadRepository;
sender: WebhookPayloadPullRequestSender;
assignee?: WebhookPayloadPullRequestAssignee;
label?: WebhookPayloadPullRequestLabel;
};

It's there at runtime, and the documentation suggests it should always be there for pull request events.

Webhooks integration with HapiJS 17

Hello,

Can you please shed some light on how I am supposed to integrate @octokit/webhoooks with HapiJS server plugins? The @octokit/webhook middleware function currently accepts 3 arguments (http request obj, http response obj, and nodejs next function).

However the handler function for HapiJS 17 has a http request object, h response toolkit object, and does not have a nodejs next function.
https://hapi.dev/api/?v=18.4.0#-routeoptionshandler

I am having a hard time trying to integrate with hapijs, has there been an example of this before?

Thanks

Galdino Rosas

Typescript: "organization" key missing in Webhook payload definitions

Using typescript, the webhook event payload type definitions do not match the actual payloads sent by Github.

Example

The handler for the check_suite.completed event receives an argument of type Webhook.WebhookEvent<Webhook.WebhookPayloadCheckSuite>

The Webhook.WebhookPayloadCheckSuite type is defined as:

type WebhookPayloadCheckSuite = {
    action: string;
    check_suite: WebhookPayloadCheckSuiteCheckSuite;
    repository: PayloadRepository;
    sender: WebhookPayloadCheckSuiteSender;
};

The actual received payload contains two extra fields which are missing from the type definition, these fields are installation and organization:

{
  "action": "completed",
  "check_suite": { ... },
  "repository": { ... },
  "sender": { ... },
  "organization": { ... },
  "installation": {
    "id": 1234,
    "node_id": "dummy_node_id"
  }
}

The type definitions should be updated to match the responses provided by Github.

webhook hangs when used in combination to bodyparser.json

Great project!

I'm using body-parser to transform requests to json form. Seems like this will consume the body stream before webhooks gets a chance to look at it.

Webhooks will then hang the request until the express timeout triggers and cancels the request. No error messages are thrown.

Perhaps a quick note in the README that this package must come before any body consumers such as body parser? Maybe an error thrown by checking if req.body already exists?

I can put together a PR as well.

To run validate:ts on Pull Requests

Problem

A Pull Request on this repository is marked as Ready to Merge even if the index.d.ts has introduced a regression.

  • Example PR introducing regression: #134

  • Bug introduced: #136

Proposal

To make a required check to run npm run validate:ts on Pull Requests for this repository

Add support for smee.io

smee.io has been created by the Probot team to simplify delivery of webhooks to your local development environment.

I’m not sure how much I’d build it into @octokit/webhooks or how much could be just done by documentation. It’s fairly simple:

const source = new EventSource('https://smee.io/gMOmZA1hb7gzyo')
source.onmessage = (event) => {
  const webhookEvent = JSON.parse(event.data)
  webhooks.verifyAndReceive({
    id: webhookEvent['x-request-id'],
    name: webhookEvent['x-github-event'],
    signature: webhookEvent['x-hub-signature'],
    payload: webhookEvent.body
  }).catch(console.error)
}

What I find most intriguing is that this makes @octokit/webhooks work for browsers :) There is a polyfil for Node as well as browsers without EventSource support: https://github.com/EventSource/eventsource

Going all in on making it part of @octokit/webhooks could looks something like this

webhooks.subscribe('https://smee.io/gMOmZA1hb7gzyo')

Or maybe a better approach that would avoid having a dependency on the eventsource package and the problem of polyfiling in older browsers:

const source = new EventSource('https://smee.io/gMOmZA1hb7gzyo')
source.onmessage = webhooks.verifyAndReceive

And then add checks within verifyAndReceive to see if the passed object is coming from smee or not.

I’ll give the last approach a try

An in-range update of semantic-release is breaking the build 🚨

Version 15.6.0 of semantic-release was just published.

Branch Build failing 🚨
Dependency [semantic-release](https://github.com/semantic-release/semantic-release)
Current Version 15.5.5
Type devDependency

This version is covered by your current version range and after updating it in your project the build failed.

semantic-release is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.

Status Details
  • continuous-integration/travis-ci/push The Travis CI build could not complete due to an error Details

Release Notes v15.6.0

15.6.0 (2018-06-19)

Features

  • allow to disable the publish plugin hook (4454d57)
Commits

The new version differs by 1 commits.

  • 4454d57 feat: allow to disable the publish plugin hook

See the full diff

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

Missing `pull_request.draft`

It seems that the new property located at pull_request.draft is not in the TypeScript definitions.

I have looked in the docs and it seems to be missing there too.

Reliable payload signature verification

We had issues verifying the signature of some payloads here #71 due to the way it is being calculated (JSON.parse + JSON.stringify) and I made a quick and dirty suggestion #71 (comment)

Nevertheless, the long term solution should be to always calculate the signature from the raw, original, payload.

I know that there are some circumstances where that's not possible (e.g. seems like Firebase doesn't expose the raw original body) but the library should always use the raw payload whenever possible and warn the developer if it's not possible.

We haven't seen any new mismatch between the way webhooks.js calculates the signature, but it could happen since the implementation assumes things that shouldn't rely on.

"issues.labeled" event lacks "payload.label" property type

This issue depends on octokit/webhooks#43. It is related to #30 .

In the generated webhook schema there is only name, actions, and examples for each webhook. So this library generates the TypeScript types using @gimenete/type-writer from the examples in the schema.

This means that critical payload values that exist in the webhook but are not in the examples are not accessible in TypeScript without some terrible escape hatches.

For example, in an IssuesEvent, a developer trying to access the label payload property would not get prompted that it exists:

2019-09-25_13-24-32

And entering it anyway results in a compiler error, even though the property exists in the webhook:

2019-09-25_13-25-00

The only workaround I've found is to override the types to add the missing properties when they are needed, or escape hatch with any:

webhooks.on('issues.labeled', ({payload}: {payload: any}) => {
  const label = payload.label
})

Since using any removes any type checking, it kinda defeats the purpose of having a schema. So it would be great if the schema could be complete enough to include all the payload parameters in the documentation, and this library could leverage those parameters to build the types.

Thanks!

Type definitions for webhook payloads

Similar to https://github.com/octokit/routes, it would be great to have a published schema for webhook payloads.

probot/probot#626 extracts the type definition we use for Probot. Once we've made a little more progress on that I'll submit a PR here to add basic types, but that will only include hand-crafted types for each payload.

Long-term, we hope to publish official webhook payload schemas as part of Octokit. In the near term though, we may need to do something more manual to generate fixtures based documentation or sample payloads.

cc @gimenete @tcbyrd @kytrinyx

Return response body on matched handler

Thanks a lot for providing this library. I was wondering if there was anyway to return a custom response when a handler is matched? Currently it only returns "ok" however I'd like to return a custom response body if possible. Thanks!

`installation_repositories` event types wrong

The types for the event installation_repositories are wrong and invalid, thus they don't work.

This is how they should look like

type WebhookPayloadInstallationRepositories = {
    action: string;
    installation: WebhookPayloadInstallationRepositoriesInstallation;
    repository_selection: string;
    repositories_added: Array<any>;
    repositories_removed: Array<
      WebhookPayloadInstallationRepositoriesRepositoriesRemovedItem
    >;
    sender: WebhookPayloadInstallationRepositoriesSender;
  };

🤔 differentiating webhook events from github.com and GHE

follow up for #1 (comment)

Use case

I want to build a GitHub app which works for both, github.com and GitHub Enterprise (GHE) installations. For GHE the available APIs (and probably the event payloads) differ per version, so it would be nice to know as the receiver of webhooks what I can do with them.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.