Review Board can notify third-party services when various events occur. This is useful for tying your various tools together (for example, posting a message to a group chat room when a review request is published). WebHooks are managed in your Team Administration UI under "WebHooks."
WebHooks send an HTTP POST request to a remote endpoint. The body of the request contains information that the remote server can use to perform some action.
Configuring a WebHook
When creating or updating a WebHook, you'll see a form with a number of options:
Let's break this down.
General Information
Enabled: This check-box will control whether or not the WebHook is active.
URL (required): The URL of the remote service to send HTTP POST requests to. This must be accessible over the Internet to the RBCommons servers.
Events (required): Specifies which events will trigger this WebHook. You can choose one or more events. Unless overridden below, the payloads sent to the remote server will depend on the event that triggered the WebHook.
Apply to (required): Allows you to limit this WebHook to review requests only on a single repository, all repositories, or only review requests not tied to a repository (those using file attachments only).
Payload
Encoding (required): The format that the payload will be in. This defaults to JSON, but can send the data using XML or HTML Form Data.
HMAC secret: If present, the payload will be signed using HMAC with the given secret as the key. This allows your remote endpoint to confirm that the request isn’t being spoofed by some nefarious third party.
Events and Payloads
There are 5 types of events supported today:
- Review request closed
- Review request published
- Review request reopened
- Review published
- Reply published
The first three will send a payload for a review request to the WebHook. "Review published" will send a payload for a review, and "Reply published" will send a payload for a reply to a review.
Samples of those payloads are provided below.
Payloads contain the same sort of data you would get through the API, making it easy to consume by callers that already work with the RBCommons API. It's a natural progression from handling a WebHook to sending follow-up API requests.
Review Request Payloads
{ "event" : "review_request_published", "is_new" : true, "review_request" : { "public" : true, "status" : "pending", "approved" : false, "issue_resolved_count" : 0, "ship_it_count" : 0, "extra_data" : {}, "last_updated" : "2016-06-10T23:58:08Z", "issue_open_count" : 0, "text_type" : null, "commit_id" : "58e4ea3d2c792c5f3f4671ed48a84e0bb88ec987", "time_added" : "2016-06-10T23:58:08Z", "depends_on" : [], "target_people" : [ { "method" : "GET", "title" : "chipx86", "href" : "https://rbcommons.com/s/<myteam>/api/users/chipx86/" } ], "approval_failure" : "The review request has not been marked \"Ship It!\"", "absolute_url" : "https://rbcommons.com/s/<myteam>/r/1303/", "url" : "/s/<myteam>/r/1303/", "links" : { "repository" : { "href" : "https://rbcommons.com/s/<myteam>/api/repositories/512/", "method" : "GET", "title" : "rbtools" }, "diffs" : { "href" : "https://rbcommons.com/s/<myteam>/api/review-requests/1303/diffs/", "method" : "GET" }, "draft" : { "href" : "https://rbcommons.com/s/<myteam>/api/review-requests/1303/draft/", "method" : "GET" }, "file_attachments" : { "href" : "https://rbcommons.com/s/<myteam>/api/review-requests/1303/file-attachments/", "method" : "GET" }, "changes" : { "method" : "GET", "href" : "https://rbcommons.com/s/<myteam>/api/review-requests/1303/changes/" }, "update" : { "href" : "https://rbcommons.com/s/<myteam>/api/review-requests/1303/", "method" : "PUT" }, "last_update" : { "method" : "GET", "href" : "https://rbcommons.com/s/<myteam>/api/review-requests/1303/last-update/" }, "self" : { "method" : "GET", "href" : "https://rbcommons.com/s/<myteam>/api/review-requests/1303/" }, "diff_context" : { "method" : "GET", "href" : "https://rbcommons.com/s/<myteam>/api/review-requests/1303/diff-context/" }, "screenshots" : { "method" : "GET", "href" : "https://rbcommons.com/s/<myteam>/api/review-requests/1303/screenshots/" }, "delete" : { "href" : "https://rbcommons.com/s/<myteam>/api/review-requests/1303/", "method" : "DELETE" }, "reviews" : { "method" : "GET", "href" : "https://rbcommons.com/s/<myteam>/api/review-requests/1303/reviews/" }, "submitter" : { "href" : "https://rbcommons.com/s/<myteam>/api/users/chipx86/", "method" : "GET", "title" : "chipx86" } }, "changenum" : null, "summary" : "Include mirror_path in search for repositories.", "close_description" : null, "target_groups" : [], "description_text_type" : "markdown", "blocks" : [], "description" : "If a reviewboard repository has a mirror path, clients using that path are not\nable to post review requests. The search for repositories returns only the\nprimary path. This change includes a repository mirror path if a valid one is\nfound.", "id" : 1303, "bugs_closed" : [ "4401" ], "branch" : "release-0.7.x", "issue_dropped_count" : 0, "testing_done_text_type" : "markdown", "close_description_text_type" : "plain", "testing_done" : "Manual testing.\nRan all unit tests before and after changes. In both cases I received:\n\n```\nRan 169 tests in 182.476s\n\nFAILED (SKIP=50, errors=2, failures=1)\n```" } }
Review Payloads
{ "event" : "review_published", "file_attachment_comments" : [], "screenshot_comments" : [], "diff_comments" : [ { "public" : true, "links" : { "user" : { "method" : "GET", "href" : "https://rbcommons.com/s/<myteam>/api/users/chipx86/", "title" : "chipx86" }, "self" : { "method" : "GET", "href" : "https://rbcommons.com" }, "filediff" : { "title" : "rbtools/commands/post.py (af1a7c31c1a595652414af20d9a55ebfc58d4983) -> rbtools/commands/post.py (548c4559532110e4722ca81d3e78f11024d06899)", "href" : "https://rbcommons.com/s/<myteam>/api/review-requests/1303/diffs/1/files/3212121/", "method" : "GET" } }, "issue_opened" : true, "issue_status" : "open", "num_lines" : 2, "interfilediff" : null, "text" : "Can you fix the styling to meet our standards guide?", "first_line" : 343, "timestamp" : "2016-06-11T00:06:35Z", "text_type" : "markdown", "id" : 403467, "extra_data" : {} } ], "review" : { "body_top" : "Just a couple of nits.", "body_bottom" : "", "links" : { "diff_comments" : { "href" : "https://rbcommons.com/s/<myteam>/api/review-requests/1303/reviews/309424/diff-comments/", "method" : "GET" }, "delete" : { "method" : "DELETE", "href" : "https://rbcommons.com/s/<myteam>/api/review-requests/1303/reviews/309424/" }, "update" : { "method" : "PUT", "href" : "https://rbcommons.com/s/<myteam>/api/review-requests/1303/reviews/309424/" }, "screenshot_comments" : { "href" : "https://rbcommons.com/s/<myteam>/api/review-requests/1303/reviews/309424/screenshot-comments/", "method" : "GET" }, "user" : { "title" : "chipx86", "href" : "https://rbcommons.com/s/<myteam>/api/users/chipx86/", "method" : "GET" }, "self" : { "href" : "https://rbcommons.com/s/<myteam>/api/review-requests/1303/reviews/309424/", "method" : "GET" }, "file_attachment_comments" : { "method" : "GET", "href" : "https://rbcommons.com/s/<myteam>/api/review-requests/1303/reviews/309424/file-attachment-comments/" }, "replies" : { "href" : "https://rbcommons.com/s/<myteam>/api/review-requests/1303/reviews/309424/replies/", "method" : "GET" } }, "public" : true, "body_bottom_text_type" : "plain", "extra_data" : {}, "id" : 309424, "ship_it" : false, "body_top_text_type" : "markdown", "text_type" : null, "timestamp" : "2016-06-11T00:06:36Z" } }
Review Reply Payloads
{ "event" : "reply_published", "screenshot_comments" : [], "file_attachment_comments" : [], "diff_comments" : [ { "text" : "Can do!", "public" : true, "text_type" : "markdown", "num_lines" : 2, "id" : 403468, "timestamp" : "2016-06-11T00:11:08Z", "links" : { "reply_to" : { "method" : "GET", "href" : "https://rbcommons.com/s/<myteam>/api/review-requests/1303/reviews/309424/diff-comments/403467/", "title" : "Can you fix the styling to meet our standards guide?" }, "update" : { "href" : "https://rbcommons.com/s/<myteam>/api/review-requests/1303/reviews/309424/replies/309425/diff-comments/403468/", "method" : "PUT" }, "filediff" : { "title" : "rbtools/commands/post.py (af1a7c31c1a595652414af20d9a55ebfc58d4983) -> rbtools/commands/post.py (548c4559532110e4722ca81d3e78f11024d06899)", "method" : "GET", "href" : "https://rbcommons.com/s/<myteam>/api/review-requests/1303/diffs/1/files/3212121/" }, "delete" : { "href" : "https://rbcommons.com/s/<myteam>/api/review-requests/1303/reviews/309424/replies/309425/diff-comments/403468/", "method" : "DELETE" }, "self" : { "method" : "GET", "href" : "https://rbcommons.com/s/<myteam>/api/review-requests/1303/reviews/309424/replies/309425/diff-comments/403468/" }, "user" : { "title" : "chipx86", "method" : "GET", "href" : "https://rbcommons.com/s/<myteam>/api/users/chipx86/" } }, "issue_opened" : false, "extra_data" : {}, "interfilediff" : null, "first_line" : 343, "issue_status" : "" } ], "reply" : { "extra_data" : {}, "body_top" : "", "body_bottom_text_type" : "plain", "timestamp" : "2016-06-11T00:11:09Z", "links" : { "screenshot_comments" : { "href" : "https://rbcommons.com/s/<myteam>/api/review-requests/1303/reviews/309424/replies/309425/screenshot-comments/", "method" : "GET" }, "user" : { "method" : "GET", "href" : "https://rbcommons.com/s/<myteam>/api/users/chipx86/", "title" : "chipx86" }, "file_attachment_comments" : { "method" : "GET", "href" : "https://rbcommons.com/s/<myteam>/api/review-requests/1303/reviews/309424/replies/309425/file-attachment-comments/" }, "update" : { "method" : "PUT", "href" : "https://rbcommons.com/s/<myteam>/api/review-requests/1303/reviews/309424/replies/309425/" }, "delete" : { "href" : "https://rbcommons.com/s/<myteam>/api/review-requests/1303/reviews/309424/replies/309425/", "method" : "DELETE" }, "self" : { "method" : "GET", "href" : "https://rbcommons.com/s/<myteam>/api/review-requests/1303/reviews/309424/replies/309425/" }, "diff_comments" : { "method" : "GET", "href" : "https://rbcommons.com/s/<myteam>/api/review-requests/1303/reviews/309424/replies/309425/diff-comments/" } }, "id" : 309425, "body_top_text_type" : "plain", "body_bottom" : "", "text_type" : null, "public" : true } }