# Events
Chat SDK has two main event systems.
## EventHandler
You can access the event handler using:
```
ChatSDK.events()
```
There are then three main methods:
```
ChatSDK.events().sourceOnMain().subscribe(event -> {
});
```
Listen to events on the main thread.
```
ChatSDK.events().source().subscribe(event -> {
});
```
Listen to events on a background thread.
```
ChatSDK.events().errorSourceOnMain().subscribe(throwable -> {
});
```
Listen for global errors.
### List of available events
You can look at the [`EventType`](https://github.com/chat-sdk/chat-sdk-android/blob/master/chat-sdk-core/src/main/java/sdk/chat/core/events/EventType.java) enum. Here is a summary of the events that exist at the present time:
```
public enum EventType {
ThreadAdded,
ThreadRemoved,
ThreadDetailsUpdated,
ThreadMetaUpdated,
MessageAdded,
MessageUpdated,
MessageRemoved,
MessageSendStatusUpdated,
ThreadUsersUpdated,
ThreadUserRoleUpdated,
UserMetaUpdated,
UserPresenceUpdated,
ContactAdded,
ContactDeleted,
ContactsUpdated,
TypingStateUpdated,
Logout,
ThreadRead,
MessageReadReceiptUpdated,
NearbyUserAdded,
NearbyUserMoved,
NearbyUserRemoved,
NearbyUsersUpdated,
Error
}
```
### Filtering
If you want to listen for a particular event type you can use the following:
```
Predicate<NetworkEvent> filter = NetworkEvent.filterType(EventType.ContactAdded, EventType.ContactDeleted);
ChatSDK.events().sourceOnMain().filter(filter).subscribe(event -> {
});
```
### Accessing Event Object
Different event types have different associated objects. For example, a message added event will also provide the message:
```
ChatSDK.events().sourceOnMain().filter(NetworkEvent.filterType(EventType.MessageAdded)).subscribe(event -> {
Message message = event.getMessage();
if (message != null) {
}
});
```
### Removing the listener
If you want to remove an event listener you can use:
```
// Add listener
Disposable d = ChatSDK.events().sourceOnMain().subscribe(event -> {
});
// Remove listener
d.dispose()
```
## Hooks
The second way to access events is using the hook system. The difference is that events are read-only whereas with hooks, you can change the functionality of the core library. For example, using a hook, you could intercept the message sent event, make an API call to remove offensive language, modify the message object and then resume message sending.
### Sync vs Async
Before demonstrating the API, there is an important thing to understand. Hooks come in two forms, synchronous and asynchronous.
- **Synchronous:** This means that processing will be resumed as soon as your block of code finishes. This should be used if you are not calling an external API
- **Asynchronous:** This means that processing will be suspended until your completable completes. This is good if you need to call an external server API
### Sync
Add a synchronous hook:
```
Hook hook = Hook.sync(data -> {
});
ChatSDK.hook().addHook(hook, HookEvent.DidAuthenticate);
```
### Async
```
Hook hook = Hook.async(data -> {
return Completable.create(emitter -> {
YourLongRunningAPI.call(() -> {
emitter.onComplete();
});
});
});
ChatSDK.hook().addHook(hook, HookEvent.DidAuthenticate);
```
This time we are using a completable. That means that execution in the main app will be paused until you call `emitter.onComplete()`. So in this case, the app will pause until `YourLongRunningAPI.call()` has finished.
> Be aware, if you don't call `onComplete()` the app will never continue execution.
### Available Hooks
You can see a list of the available hooks in the [`HookEvent`](https://github.com/chat-sdk/chat-sdk-android/blob/master/chat-sdk-core/src/main/java/sdk/chat/core/hook/HookEvent.java) class.
```
public static String DidAuthenticate = "DidAuthenticate";
public static String UserOn = "UserOn";
public static String MessageReceived = "MessageReceived";
public static String MessageWillSend = "MessageWillSend";
public static String MessageSent = "MessageSent";
public static String IsNew_Boolean = "IsNew_Boolean";
public static String DidLogout = "DidLogout";
public static String WillLogout = "WillLogout";
public static String UserDidConnect = "UserDidConnect";
public static String UserWillDisconnect = "UserWillDisconnect";
public static String ContactWillBeAdded = "ContactWillBeAdded";
public static String ContactWasAdded = "ContactWasAdded";
public static String ContactWillBeDeleted = "ContactWillBeDeleted";
public static String ContactWasDeleted = "ContactWasDeleted";
```
### Access data from the hook
Hooks can also provide data. You can access using the following:
```
public static String User = "User";
public static String Thread = "Thread";
public static String Message = "Message";
public static String Object = "Object";
```
So:
```
Hook hook = Hook.sync(data -> {
Object messageObject = data.get(HookEvent.Message);
if (messageObject instanceof Message) {
Message message = (Message) messageObject;
}
});
ChatSDK.hook().addHook(hook, HookEvent.MessageReceived);
```
### Remove a hook
You can also remove a hook:
```
ChatSDK.hook().removeHook(hook, HookEvent.MessageReceived);
```