You can register a callback with Stack Exchange Chat, which gets called prior to the change happening in the DOM (i.e. if you want to find a new message in the DOM, you need to use a `setTimeout()` to act after the DOM change). Callbacks can be registered with `CHAT.addEventHandlerHook(callback)`, which takes a function as its single argument. Prior *most* of the chat system processing of the event, the registered callbacks are executed in the order they were added. If any callback alters the `event` object in argument 0, then that change will be propagated to any subsequent callbacks and used when the chat system updates the DOM after all registered callbacks have been executed. If any callback returns a truthy value, then no further callbacks are executed and the chat system doesn't do any of its normal processing of the event (i.e. the DOM will not be updated). Effectively, returning a truthy value from a callback cancels the event. The chat system itself uses `CHAT.addEventHandlerHook(callback)` to add its own callback for *partial* processing of *some* event types. This means that the processing for the following event types will be split between prior to other callbacks and after other callbacks: `MessageDeleted`, `MessageEdited`, `MessageFlagged`, `MessagePosted`, `MessageReply`, `UserEntered`, `UserLeft`, `UserMentioned`, and `UserNameOrAvatarChanged`. The callback function is passed arguments that look like: <!-- language: lang-json --> arguments: { 0: { event_type: 1, time_stamp: 1552493100, content: 'Test message with a tag <a href="//stackoverflow.com/questions/tagged/some-tag"><span class="ob-post-tag" style="background-color: #E0EAF1; color: #3E6D8E; border-color: #3E6D8E; border-style: solid;">some-tag</span></a>.', id: 92913194, user_id: 3773011, user_name: "Makyen", room_id: 68414, room_name: "SOCVR Testing Facility", message_id: 45625173 }, 1: false, 2: 92913190 } The first argument is a chat "event" Object. The type of event is indicated by the numeric value of `event_type`. There are 34 types which are possible for `event_type`. <!-- language: lang-js --> const chatEventTypes = { 1: 'MessagePosted', 2: 'MessageEdited', 3: 'UserEntered', 4: 'UserLeft', 5: 'RoomNameChanged', 6: 'MessageStarred', 7: 'DebugMessage', 8: 'UserMentioned', 9: 'MessageFlagged', 10: 'MessageDeleted', 11: 'FileAdded', 12: 'ModeratorFlag', 13: 'UserSettingsChanged', 14: 'GlobalNotification', 15: 'AccessLevelChanged', 16: 'UserNotification', 17: 'Invitation', 18: 'MessageReply', 19: 'MessageMovedOut', 20: 'MessageMovedIn', 21: 'TimeBreak', 22: 'FeedTicker', 29: 'UserSuspended', 30: 'UserMerged', 34: 'UserNameOrAvatarChanged', }; The callback will receive events for all the rooms the user is in, so you will want to filter them by matching the `room_id` to the current room. The list of event types was copied from the SE's minimized chat JavaScript. [1]: https://chat.stackoverflow.com/transcript/message/54614089