Skip to content

GitHub Event Subscriptions

Samad Yar Khan edited this page Jul 6, 2022 · 5 revisions

GitHub WebHooks / Event Subscriptions

  • Rocket.Chat Apps enable us to add an API End Point to our application using ApiEndPoint Abstract Class which can be used to receive HTTP requests.
  • In the GitHub App we have used this ApiEndPoint abstract class to enable an API end point which can be used to receive a POST(HTTP) request.
  • We allow users to subscribe to different repository events using the GitHub WebHooks and the payload is received on the above mentioned API end point using a POST(HTTP) request.
  • As soon as a payload is received, we will match the payload's repository event to the subscribed rooms using the persisted data and send a repository event notification in the respected rooms.

User Flow

Subscribing events using Slash Command

The user can subscribe to all repository events by typing the command : /github Owner/Repository subscribe. If a hook already exists, then we add additional events to hook if needed and subscribe to the events.

lol`

Unsubscribe to all Repository Events using slash command

The user can unsubscribe to all repository events by typing the command : /github Owner/Repository unsubscribe. The room will unsubscribe to the events and those events which are not required by any room will be deleted from the hook and the hook is updated. In below example, non of the events are required by any other room , hence whole hook is deleted.

Untitled-2022-07-06-1957

Subscribing and Unsubscribing using modal

The user can use the slash command /github subscribe to see a list of subscribed repository events and see options to add or delete subscriptions.

To subscribe to events of a repository, we click on the Add Subscription button and enter details on the next modal and click subscribe.

Untitled-2022-07-06-2031

The user can similarly unsubscribe from events in the following fashion, by clicking on the Delete Subscriptions Button.

Untitled-2022-07-06-2031

Registering an API End Point

  • We make a new class which extends ApiEndPoint class and register this endpoint in the Rocket.Chat Applications Extended Configuration.
  • As soon as we received a payload, the post method will be called, so it should contain all the logic which decides what happens with a received payload.
  • GitHub app uses a githubWebHooks class to add the API end point.
  • Code Snippet registering this API Endpoint in the extendConfiguration can be seen over here.

Event Subscription and Persistence

  • We can subscribe to GitHub WebHook Events by using the GitHub WebHooks REST APIs.
  • All the functions which are needed to create, update or delete a WebHook can be found in the githubSDK.
  • Whenever we create a subscription using the createSubscription method provided by the SDK, we must persist the data which can link the hook to the room in the Rocket.Chat apps persistent storage.
  • Hence, whenever a hook is created, we create a Subscription object and use the createSubscription method to save the WebHooks data inside the Applications persistent storage in the form of objects which extend ISubscription interface. This is internally done by the Subscription class by making use of using the RocketChatAssociationRecords.

Edge Cases with WebHook

  • A user can only create a unique WebHook for a specific callback URI. Hence, if we want to subscribe to the same repository events in multiple channels, we cannot just create another hook with the exact events and the exact Endpoint URI. This will lead to an error.
  • Similarly if channel1 wants to subscribe to events A,B,C of a repository and channel2 wants to subscribe to events B,C,D , there will be an overlap of events due to the same call back URI, leading to a server error.
  • Solution :
    • We make a single WebHook and Persist the data in the applications storage.
    • Whenever we want to subscribe to an event, we will first check all the current repository subscriptions of the server using getSubscriptionsByRepo.
    • If a no subscriptions exits, we will just create a new subscription using createSubscription.
    • If a subscription exists, we will store the webHookId and store all the unique subscriptions made to the repository by different rooms.
    • If our events already exists in the previously subscribed events, we will just store Subscriptions in the Persistent Storage using createSubscription method and use the webHookId of the existing hook. This will map the already repository subscription event to our room and when a payload is received, our room will also be in the list of subscribed room and receive notifications. This enables us to use the same WebHook to send notifications to multiple rooms instead of creating a new hook each time.
    • The code for the above mentioned solution can be found here.
    • Similar Logic can be used for deleting subscriptions as well. The code for unsubscribing can be found over here.
    • Subscribing to different events from a single hook in different rooms and updating hook (EDGE CASE DEMO)
    • Unsubscribing from events in a room and deleting non required hook events (EDGE CASE DEMO)