||<>|| = Webhooks = Some objects in Launchpad support [[https://en.wikipedia.org/wiki/Webhook|webhooks]]. When these objects change, Launchpad will send an HTTP POST request to the delivery URL configured for each webhook with some information about the event that prompted the notification. You can use this to integrate with all kinds of external services, and if you control an HTTP server reachable from the Internet it's easy to write your own webhook endpoint. == Objects and events == You can create webhooks on any of these target objects: || '''Object''' || '''Events''' || || [[https://launchpad.net/+apidoc/devel.html#branch|Bazaar branch]] || `bzr:push:0.1`, `merge-proposal:0.1` || || [[https://launchpad.net/+apidoc/devel.html#git_repository|Git repository]] || `git:push:0.1`, `merge-proposal:0.1` || || [[https://launchpad.net/+apidoc/devel.html#snap|Snap package]] || `snap:build:0.1` || Events have a type (used in the API) and a name (shown in the web UI). The types are versioned: if we ever change an event payload in an incompatible way, we'll bump the version so that you can adapt your code gracefully. We may add more key/value pairs to dictionaries without bumping the version. || '''Event type''' || '''Event name''' || '''When''' || || [[#bzr-push-0.1|bzr:push:0.1]] || Bazaar push || Any time a Bazaar branch is pushed || || [[#git-push-0.1|git:push:0.1]] || Git push || Any time a Git repository is pushed; this includes creating or deleting branches || || [[#merge-proposal-0.1|merge-proposal:0.1]] || Merge proposal || Any time a merge proposal that has this branch or repository as the target is created, modified, or deleted || || [[#ping|ping]] || Ping || A test event was requested manually || || [[#snap-build-0.1|snap:build:0.1]] || Snap build || Any time the status of a snap package build changes || == Creating webhooks == You can create new webhooks by visiting a supported object in the Launchpad web UI and following the "Manage webhooks" link, or by using the `newWebhook` method on one of those objects via the [[API|Launchpad API]]. == Authentication == When you create a webhook, you will be asked for a secret. You don't have to provide one, but if you do, Launchpad will add an `X-Hub-Signature` HTTP header to each webhook delivery containing an HMAC-SHA1 signature of the body with that secret, as in the [[https://pubsubhubbub.github.io/PubSubHubbub/pubsubhubbub-core-0.4.html#rfc.section.8|PubSubHubbub specification]]. You can't currently change the secret for an existing webhook using the Launchpad web UI, but you can use the [[https://launchpad.net/+apidoc/devel.html#webhook-setSecret|setSecret]] API method to change it. Launchpad will never divulge an existing webhook secret by any means; this is a write-only property. == Testing == You can use the [[https://launchpad.net/+apidoc/devel.html#webhook-ping|ping]] API method to send a test event: {{{ obj = launchpad.load('/path/to/object') webhook = obj.webhooks[0] webhook.ping() }}} Recent deliveries of a webhook are shown on its page in the Launchpad web UI. They are also available in the `webhook.deliveries` API collection, and you can look at [[https://launchpad.net/+apidoc/devel.html#webhook_delivery|various attributes of the delivery]] there. == Delivery ordering == Webhooks will generally be delivered in roughly the order in which the events happened, but (as with any distributed service) you cannot rely on this. If ordering is important to your application, then you should sort events by the numeric `X-Launchpad-Delivery` header. == Network considerations == You should ensure that your firewall allows HTTP/HTTPS access (as appropriate) from all the IP addresses associated with `webhooks-proxy.launchpad.net`. If you are testing from the [[https://qastaging.launchpad.net/|qastaging sandbox]], you should also allow `webhooks-proxy.qastaging.paddev.net`. The proxy used for delivering webhooks does not generally allow access to Canonical's own IP space. If you are a Canonical employee and want to set up a webhook-based integration with another service hosted by Canonical, please [[https://answers.launchpad.net/launchpad/+addquestion|contact the Launchpad team]] with details. == Event payloads == All webhook deliveries will have the following HTTP headers: || '''Header name''' || '''Content''' || || `User-Agent` || Begins with `launchpad.net-Webhooks/` || || `Content-Type` || `application/json` || || `X-Launchpad-Event-Type` || Event type || || `X-Launchpad-Delivery` || Unique identifier for this delivery || || `X-Hub-Signature` || HMAC-SHA1 signature of the body with the secret, if configured; otherwise absent || The body of the request will be JSON. Payloads will usually contain the path part of the target object's URL, referred to as the "url-path" type below. You can use these to find the object in the Launchpad web UI (prefix "https://launchpad.net") or in the Launchpad API (for example, you can pass the path directly to [[API/launchpadlib#Persistent_references_to_Launchpad_objects|launchpad.load]] without any prefix). We recommend that you use the API if you need more information about the object than the webhook payload provides, or if you need to send notifications back to Launchpad (for example, after a CI job completes). <> === Bazaar push === Triggered any time a Bazaar branch is pushed. The payload is: || '''Key''' || '''Type''' || '''Value''' || || `bzr_branch` || url-path || The branch || || `bzr_branch_path` || string || A path to the branch; prefix with "lp:" to get a URL that can be used with the `bzr` client || || `old` || dict || Branch attributes before this push || || `new` || dict || Branch attributes after this push || `old` and `new` are dictionaries of attributes as follows: || '''Key''' || '''Type''' || '''Value''' || || `revision_id` || string || The tip revision ID || <> === Git push === Triggered any time a Git repository is pushed; this includes creating or deleting branches. The payload is: || '''Key''' || '''Type''' || '''Value''' || || `git_repository` || url-path || The repository || || `git_repository_path` || string || A path to the repository; prefix with "git+ssh://git.launchpad.net/" or "https://git.launchpad.net/" to get a URL that can be used with the `git` client || || `ref_changes` || dict || Maps ref names to `old` and `new` keys describing the previous and current state of each changed ref, each of which may be either `None` if the ref is/was absent or a ref description as below || Ref descriptions are dictionaries of attributes as follows: || '''Key''' || '''Type''' || '''Value''' || || `commit_sha1` || string || The SHA-1 of the commit that the ref points to || <> === Merge proposal === Triggered any time a merge proposal that has the target branch or repository as the target is created, modified, or deleted. The payload is: || '''Key''' || '''Type''' || '''Value''' || || `merge_proposal` || url-path || The merge proposal || || `action` || string || "created", "modified", or "deleted" || || `old` || dict || Absent if `action` is "created"; otherwise, a dictionary of merge proposal attributes before this event || || `new` || dict || Absent if `action` is "deleted"; otherwise, a dictionary of merge proposal attributes after this event || Merge proposal attributes are as follows: || '''Key''' || '''Type''' || '''Value''' || || registrant || url-path || The person who registered the merge proposal || || source_branch || url-path || The Bazaar branch that has code to land || || source_git_repository || url-path || The Git repository that has code to land || || source_git_path || string || Ref path of the Git branch that has code to land || || target_branch || url-path || The Bazaar branch that the source branch will be merged into || || target_git_repository || url-path || The Git repository that the source branch will be merged into || || target_git_path || string || Ref path of the Git branch that the source branch will be merged into || || prerequisite_branch || url-path || The Bazaar branch that the source branch branched from || || prerequisite_git_repository || url-path || The Git repository containing the branch that the source branch branched from || || prerequisite_git_path || string || The path of the Git branch that the source branch branched from || || queue_status || string || The current state of the proposal: one of "Work in progress", "Needs review", "Approved", "Rejected", "Merged", or "Superseded" || || commit_message || string || The commit message that should be used when merging the source branch || || whiteboard || string || Notes about the merge || || description || string || A detailed description of the changes that are being addressed by the branch being proposed to be merged || || preview_diff || url-path || The current diff of the source branch against the target branch || <> === Ping === A test event was [[#Testing|requested manually]]. The payload is: || '''Key''' || '''Type''' || '''Value''' || || `ping` || boolean || `true` || <> === Snap build === Triggered any time the status of a snap package build changes. The payload is: || '''Key''' || '''Type''' || '''Value''' || || `snap_build` || url-path || The snap build || || `action` || string || "status-changed" || || `snap` || url-path || The snap package || || `status` || string || The current status of the build job: one of "Needs building", "Successfully built", "Failed to build", "Dependency wait", "Chroot problem", "Build for superseded Source", "Currently building", "Failed to upload", "Uploading build", "Cancelling build", or "Cancelled build" || || `store_upload_status` || string || The current status of uploading this build to the store: one of "Unscheduled", "Pending", "Failed to upload", "Failed to release to channels", or "Uploaded" ||