diff --git a/app/assets/javascripts/admin/controllers/admin-web-hooks-show-events.js.es6 b/app/assets/javascripts/admin/controllers/admin-web-hooks-show-events.js.es6
index 9b4cc91f5c5..d91469d33df 100644
--- a/app/assets/javascripts/admin/controllers/admin-web-hooks-show-events.js.es6
+++ b/app/assets/javascripts/admin/controllers/admin-web-hooks-show-events.js.es6
@@ -1,14 +1,65 @@
 import { ajax } from 'discourse/lib/ajax';
 import { popupAjaxError } from 'discourse/lib/ajax-error';
+import computed from 'ember-addons/ember-computed-decorators';
 
 export default Ember.Controller.extend({
+  pingDisabled: false,
+  incomingEventIds: [],
+  incomingCount: Ember.computed.alias("incomingEventIds.length"),
+
+  @computed('incomingCount')
+  hasIncoming(incomingCount) {
+    return incomingCount > 0;
+  },
+
+  subscribe() {
+    this.messageBus.subscribe(`/web_hook_events/${this.get('model.extras.web_hook_id')}`, data => {
+      if (data.event_type === 'ping') {
+        this.set('pingDisabled', false);
+      }
+      this._addIncoming(data.web_hook_event_id);
+    });
+  },
+
+  unsubscribe() {
+    this.messageBus.unsubscribe('/web_hook_events/*');
+  },
+
+  _addIncoming(eventId) {
+    const incomingEventIds = this.get("incomingEventIds");
+
+    if (incomingEventIds.indexOf(eventId) === -1) {
+      incomingEventIds.pushObject(eventId);
+    }
+  },
+
   actions: {
     loadMore() {
       this.get('model').loadMore();
     },
 
     ping() {
-      ajax(`/admin/web_hooks/${this.get('model.extras.web_hook_id')}/ping`, {type: 'POST'}).catch(popupAjaxError);
+      this.set('pingDisabled', true);
+
+      ajax(`/admin/web_hooks/${this.get('model.extras.web_hook_id')}/ping`, {
+        type: 'POST'
+      }).catch(error => {
+        this.set('pingDisabled', false);
+        popupAjaxError(error);
+      });
+    },
+
+    showInserted() {
+      const webHookId = this.get('model.extras.web_hook_id');
+
+      ajax(`/admin/web_hooks/${webHookId}/events/bulk`, {
+        type: 'GET',
+        data: { ids: this.get('incomingEventIds') }
+      }).then(data => {
+        const objects = data.map(event => this.store.createRecord('web-hook-event', event));
+        this.get("model").unshiftObjects(objects);
+        this.set("incomingEventIds", []);
+      });
     }
   }
 });
diff --git a/app/assets/javascripts/admin/routes/admin-web-hooks-show-events.js.es6 b/app/assets/javascripts/admin/routes/admin-web-hooks-show-events.js.es6
index ea4e33ac630..89841d5a7ba 100644
--- a/app/assets/javascripts/admin/routes/admin-web-hooks-show-events.js.es6
+++ b/app/assets/javascripts/admin/routes/admin-web-hooks-show-events.js.es6
@@ -5,6 +5,11 @@ export default Discourse.Route.extend({
 
   setupController(controller, model) {
     controller.set('model', model);
+    controller.subscribe();
+  },
+
+  deactivate() {
+    this.controllerFor('adminWebHooks.showEvents').unsubscribe();
   },
 
   renderTemplate() {
diff --git a/app/assets/javascripts/admin/templates/web-hooks-show-events.hbs b/app/assets/javascripts/admin/templates/web-hooks-show-events.hbs
index 7cfb1bd794c..9b4f1e80a3f 100644
--- a/app/assets/javascripts/admin/templates/web-hooks-show-events.hbs
+++ b/app/assets/javascripts/admin/templates/web-hooks-show-events.hbs
@@ -2,7 +2,7 @@
   {{#link-to 'adminWebHooks' tagName='button' classNames='btn'}}
     {{fa-icon 'list'}} {{i18n 'admin.web_hooks.events.go_list'}}
   {{/link-to}}
-  {{d-button icon="send" label="admin.web_hooks.events.ping" action="ping"}}
+  {{d-button icon="send" label="admin.web_hooks.events.ping" action="ping" disabled=pingDisabled}}
   {{#link-to 'adminWebHooks.show' model.extras.web_hook_id tagName='button' classNames='btn'}}
     {{fa-icon 'edit'}} {{i18n 'admin.web_hooks.events.go_details'}}
   {{/link-to}}
@@ -10,6 +10,12 @@
 
 <div class='web-hook-events-listing'>
 {{#if model}}
+  {{#if hasIncoming}}
+    <div class='alert alert-info clickable' {{action "showInserted"}}>
+      {{count-i18n key="admin.web_hooks.events.incoming" count=incomingCount}}
+      {{i18n 'click_to_show'}}
+    </div>
+  {{/if}}
   {{#load-more selector=".web-hook-events li" action="loadMore"}}
     <div class='web-hook-events content-list'>
       <ul>
diff --git a/app/assets/stylesheets/common/admin/admin_base.scss b/app/assets/stylesheets/common/admin/admin_base.scss
index d8a734cf7d5..5d81c310b84 100644
--- a/app/assets/stylesheets/common/admin/admin_base.scss
+++ b/app/assets/stylesheets/common/admin/admin_base.scss
@@ -1859,8 +1859,6 @@ table#user-badges {
 }
 
 .web-hook-events {
-  margin-top: 15px;
-
   li {
     padding: 2px 0;
   }
@@ -1906,6 +1904,13 @@ table#user-badges {
   }
 }
 
+.web-hook-events-listing {
+  margin-top: 15px;
+  .alert {
+    margin: 15px 0 0 0;
+  }
+}
+
 // Mobile specific styles
 // Mobile view text-inputs need some padding
 .mobile-view .admin-contents {
diff --git a/app/controllers/admin/web_hooks_controller.rb b/app/controllers/admin/web_hooks_controller.rb
index d70048c7428..3d7a134c44e 100644
--- a/app/controllers/admin/web_hooks_controller.rb
+++ b/app/controllers/admin/web_hooks_controller.rb
@@ -1,5 +1,5 @@
 class Admin::WebHooksController < Admin::AdminController
-  before_filter :fetch_web_hook, only: %i(show update destroy list_events ping)
+  before_filter :fetch_web_hook, only: %i(show update destroy list_events bulk_events ping)
 
   def index
     limit = 50
@@ -72,6 +72,12 @@ class Admin::WebHooksController < Admin::AdminController
     render json: MultiJson.dump(json), status: 200
   end
 
+  def bulk_events
+    params.require(:ids)
+    web_hook_events = @web_hook.web_hook_events.where(id: params[:ids])
+    render_serialized(web_hook_events, AdminWebHookEventSerializer)
+  end
+
   def redeliver_event
     web_hook_event = WebHookEvent.find(params[:event_id])
 
diff --git a/app/jobs/regular/emit_web_hook_event.rb b/app/jobs/regular/emit_web_hook_event.rb
index d3315b33fcf..c3bbc3c14ae 100644
--- a/app/jobs/regular/emit_web_hook_event.rb
+++ b/app/jobs/regular/emit_web_hook_event.rb
@@ -67,6 +67,10 @@ module Jobs
                                         response_headers: MultiJson.dump(response.headers),
                                         response_body: response.body,
                                         duration: ((Time.zone.now - now) * 1000).to_i)
+      MessageBus.publish("/web_hook_events/#{@web_hook.id}", {
+        web_hook_event_id: web_hook_event.id,
+        event_type: @opts[:event_type]
+      }, user_ids: User.staff.pluck(:id))
     end
 
     def build_web_hook_body
diff --git a/app/serializers/admin_web_hook_event_serializer.rb b/app/serializers/admin_web_hook_event_serializer.rb
index 0343d1739d0..14ff7248839 100644
--- a/app/serializers/admin_web_hook_event_serializer.rb
+++ b/app/serializers/admin_web_hook_event_serializer.rb
@@ -10,7 +10,6 @@ class AdminWebHookEventSerializer < ApplicationSerializer
              :duration,
              :created_at
 
-
   def request_url
     object.web_hook.payload_url
   end
diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml
index 217f1f09a73..9809cd7df0f 100644
--- a/config/locales/client.en.yml
+++ b/config/locales/client.en.yml
@@ -2478,6 +2478,9 @@ en:
         events:
           none: "There are no related events."
           redeliver: "Redeliver"
+          incoming:
+            one: "There is a new event."
+            other: "There are {{count}} new events."
           completion: "Completed in %{seconds} seconds."
           request: "Request"
           response: "Response"
diff --git a/config/routes.rb b/config/routes.rb
index 45cf5a871df..d4a33a08053 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -209,6 +209,7 @@ Discourse::Application.routes.draw do
     resources :web_hooks, constraints: AdminConstraint.new
     get 'web_hook_events/:id' => 'web_hooks#list_events', constraints: AdminConstraint.new, as: :web_hook_events
     get 'web_hooks/:id/events' => 'web_hooks#list_events', constraints: AdminConstraint.new
+    get 'web_hooks/:id/events/bulk' => 'web_hooks#bulk_events', constraints: AdminConstraint.new
     post 'web_hooks/:web_hook_id/events/:event_id/redeliver' => 'web_hooks#redeliver_event', constraints: AdminConstraint.new
     post 'web_hooks/:id/ping' => 'web_hooks#ping', constraints: AdminConstraint.new