```json
//[doc-seo]
{
"Description": "Discover how to implement real-time messaging in your application with the ABP Chat Module. Installation made easy via ABP Suite or CLI."
}
```
# Chat Module (Pro)
> You must have an [ABP Team or a higher license](https://abp.io/pricing) to use this module.
This module implements real time messaging between users for an application.
See [the module description page](https://abp.io/modules/Volo.Chat) for an overview of the module features.
To download the source-code of the Chat module, you can use ABP Suite or you can use the ABP CLI with the following command:
```bash
abp get-source Volo.Chat
```
## How to Install
Chat module is not installed in [the startup templates](../solution-templates). So, it needs to be installed manually. There are two ways of installing a module into your application.
### Installation
#### 1. Using ABP Suite
ABP Suite allows adding a module to a solution using ``Add to your solution`` option in modules list.

#### 2. Manual Installation
If you modified your solution structure, adding module using ABP Suite might not work for you. In such cases, chat module can be added to a solution manually.
In order to do that, add packages listed below to matching project on your solution. For example, ```Volo.Chat.Application``` package to your **{ProjectName}.Application.csproj** like below;
```xml
```
After adding the package reference, open the module class of the project (eg: `{ProjectName}ApplicationModule`) and add the below code to the `DependsOn` attribute.
```csharp
[DependsOn(
//...
typeof(ChatApplicationModule)
)]
```
> If you are using Blazor Web App, you need to add the `Volo.Chat.Blazor.WebAssembly` package to the **{ProjectName}.Blazor.Client.csproj** project and add the `Volo.Chat.Blazor.Server` package to the **{ProjectName}.Blazor.csproj** project.
The `Volo.Chat.SignalR` package must be added according to your project structure:
* **Mvc**
* **Tiered**: {ProjectName}.HttpApi.Host project.
* **Blazor Server**
* **Unified Backend**: {ProjectName}.Blazor.
* **Separated Auth Server**: {ProjectName}.HttpApi.Host project.
* **Blazor WebAssembly**: {ProjectName}.HttpApi.Host project.
* **Blazor Web App**
* **Unified Backend**: {ProjectName}.Blazor.
* **Separated Auth Server**: {ProjectName}.HttpApi.Host project.
* **Angular**: {ProjectName}.HttpApi.Host project.
If database provider of your project is **EntityFrameworkCore**, use `modelBuilder.ConfigureChat()` to configure database tables in your project's DbContext.
## Configuration
### SignalR Access Token Configuration for Angular and Blazor WebAssembly Projects
See [Microsoft SignalR Authentication and Authorization](https://docs.microsoft.com/en-us/aspnet/core/signalr/authn-and-authz) and [Microsoft SignalR Security](https://docs.microsoft.com/en-us/aspnet/core/signalr/security#access-token-logging) documentations.
> In standard web APIs, bearer tokens are sent in an HTTP header. However, SignalR is unable to set these headers in browsers when using some transports. When using WebSockets and Server-Sent Events, the token is transmitted as a query string parameter. To support this on the server, additional configuration is required.
>
Here is a sample configuration for this:
```csharp
app.Use(async (httpContext, next) =>
{
var accessToken = httpContext.Request.Query["access_token"];
var path = httpContext.Request.Path;
if (!string.IsNullOrEmpty(accessToken) &&
(path.StartsWithSegments("/signalr-hubs/chat")))
{
httpContext.Request.Headers["Authorization"] = "Bearer " + accessToken;
}
await next();
});
```
### Adding Distributed Event Bus for distributed architecture projects
When Web & API tiers are separated, it is impossible to directly send a server-to-client message from the HTTP API. This is also true for a microservice architected application. **Chat Module** uses the distributed event bus to deliver the message from API application to the web application, then to the client.
If your project has such an architecture (example: MVC + tiered option), then you need a Distributed Event Bus. See [related ABP documentation](../framework/infrastructure/event-bus/distributed) to understand Distributed Event Bus system in ABP. Also see [RabbitMQ Integration documentation](../framework/infrastructure/event-bus/distributed/rabbitmq.md) if your choice is to use RabbitMQ.
## Packages
This module follows the [module development best practices guide](../framework/architecture/best-practices) and consists of several NuGet and NPM packages. See the guide if you want to understand the packages and relations between them.
You can visit [Chat module package list page](https://abp.io/packages?moduleName=Volo.Chat) to see list of packages related with this module.
## User interface
### Chat feature and permissions
The `Chat.Enable` feature is disabled by default. Enable it for a tenant or edition before granting chat permissions.

The module defines the following permissions:
* `Chat.Messaging`: Allows a user to open the chat page and exchange messages. A message can only be sent if the target user also has this permission.
* `Chat.Searching`: A child permission of `Chat.Messaging`. It allows a user to start a conversation with a user who is not already in the conversation history. Without this permission, the user can continue existing conversations.
* `Chat.SettingManagement`: Allows a user to manage the chat settings.
### Chat page
This is the page that users send messages to each other.

Message text is required. By default, it must contain between 1 and 4,096 characters. The conversation API returns the newest messages first; the built-in user interfaces reverse that result to display messages in chronological order.
### Deleting messages and conversations
The following settings control deletion behavior:
| Setting | Default | Description |
| --- | --- | --- |
| `Volo.Chat.Messaging.DeletingMessages` | `Enabled` | `Enabled` allows deletion at any time, `Disabled` prevents deletion, and `EnabledWithDeletionPeriod` allows deletion only during the configured period after the message is created. |
| `Volo.Chat.Messaging.MessageDeletionPeriod` | `0` | Deletion period in seconds when message deletion is set to `EnabledWithDeletionPeriod`. |
| `Volo.Chat.Messaging.DeletingConversations` | `Enabled` | Enables conversation deletion. It is effective only when message deletion is set to `Enabled`. |
Deleting a message removes the shared message and both users' message records. Deleting a conversation removes both users' conversation records and all messages between them. These operations are shared deletions, not a "hide for me" operation. Deletion notifications are sent through the real-time channel.
### Chat icon on navigation bar
An icon that shows unread message count of the user and leads to chat page when clicked is added to navigation menu.

## Internals
### Domain layer
#### Entities and aggregate roots
* `Message` (aggregate root): Represents a chat message. Implements `IMultiTenant`.
* `Text`: Message content.
* `IsAllRead`: Message read information.
* `ReadTime`: Message read time information.
* `ChatUser` (aggregate root): Represents a chat user. Implements `IUser` and `IUpdateUserData` interfaces.
* `UserMessage`: is created for each side (sender and receiver) of a message. Implements `IMultiTenant` and `IAggregateRoot` interfaces.
* `ChatMessageId`: Id of related `Message`.
* `UserId`: Id of related `ChatUser.`
* `TargetUserId`: Id of other related `ChatUser`.
* `Side`: States that if it is a send message or received message.
* `IsRead`: Read information.
* `ReadTime`: Read time information.
* `Conversation`: is created for each side of a conversation between users. Implements `IMultiTenant` and `IAggregateRoot` interfaces.
* `UserId`: Id of related `ChatUser.`
* `TargetUserId`: Id of other related `ChatUser`.
* `LastMessageSide`: States the side of the latest message (send or received).
* `LastMessage`: Content of the last message in the conversation.
* `LastMessageDate`: Date of the last message in the conversation.
* `UnreadMessageCount`: Count of unread messages in the conversation.
#### Repositories
This module follows the [Repository Best Practices & Conventions](../framework/architecture/best-practices) guide.
Following custom repositories are defined for this module:
* `IConversationRepository`
* `IUserMessageRepository`
* `IChatUserRepository`
* `IMessageRepository`
#### Domain Services
* `MessagingManager`
### Application layer
#### Application services
* `ConversationAppService` (implements `IConversationAppService`): Used to send messages, get conversation between users and mark a conversation as read.
* `SettingsAppService` (implements `ISettingsAppService`): Used to save chat settings.
* `ContactAppService` (implements `IContactAppService`): Used to get list of contacts and total unread message count of a user.
* `DistributedEventBusRealTimeChatMessageSender` (implements `IRealTimeChatMessageSender`): Used to publish chat messages to distributed event bus.
* `SignalRRealTimeChatMessageSender` (implements `IRealTimeChatMessageSender`): Used to send messages to target `SignalR` client.
### Database providers
#### Common
##### Table / collection prefix & schema
All tables/collections use the `Chat` prefix by default. Set static properties on the `ChatDbProperties` class if you need to change the table prefix or set a schema name (if supported by your database provider).
##### Connection string
This module uses `Chat` for the connection string name. If you don't define a connection string with this name, it fallbacks to the `Default` connection string.
See the [connection strings](../framework/fundamentals/connection-strings.md) documentation for details.
#### Entity Framework Core
##### Tables
* **ChatUsers**
* **ChatMessages**
* **ChatUserMessages**
* **ChatConversations**
#### MongoDB
##### Collections
* **ChatUsers**
* **ChatMessages**
* **ChatUserMessages**
* **ChatConversations**
### Angular UI
#### Installation
In order to configure the application to use the chat module, you first need to import `provideChatConfig` from `@volo/abp.ng.chat/config` to the root application configuration. Then, you will need to append it to the `providers` array.
```ts
// app.config.ts
import { provideChatConfig } from '@volo/abp.ng.chat/config';
export const appConfig: ApplicationConfig = {
providers: [
// ...
provideChatConfig(),
],
};
```
The chat module should be imported and lazy-loaded in your routing array. It exports a `createRoutes` function from `@volo/abp.ng.chat`.
```ts
// app.routes.ts
const APP_ROUTES: Routes = [
// ...
{
path: 'chat',
loadChildren: () =>
import('@volo/abp.ng.chat').then(c => c.createRoutes()),
},
];
```
#### Component replacement
The Angular chat route uses the `Chat.ChatComponent` replacement key and `ChatComponent` as its default component. See the [Angular component replacement documentation](../framework/ui/angular/component-replacement.md) if you need to replace the page.
#### Services / Models
Chat module services and models are generated via `generate-proxy` command of the [ABP CLI](../cli). If you need the module's proxies, you can run the following command in the Angular project directory:
```bash
abp generate-proxy --module chat
```
#### Remote Endpoint URL
The Chat module remote endpoint URLs can be configured in the environment files.
```ts
export const environment = {
// other configurations
apis: {
default: {
url: 'default url here',
},
Chat: {
url: 'Chat remote url here',
signalRUrl: 'Chat signalR remote url here',
},
// other api configurations
},
};
```
The Chat module remote URL configurations shown above are optional.
> If you don't set the `signalRUrl`, `Chat.url` will be used as fallback. If you don't set the `Chat` property, the `default.url` will be used as fallback.
### Blazor and MAUI UIs
#### Remote Endpoint URL
The SignalR base URL can be configured with the option type that matches the UI package:
| UI package | Option type | Fallback when `SignalrUrl` is not set |
| --- | --- | --- |
| Blazor Server | `ChatBlazorServerOptions` | The current application URL. |
| Blazor WebAssembly | `ChatBlazorWebAssemblyOptions` | `AbpRemoteServiceOptions.RemoteServices.Default.BaseUrl`. |
| Blazor MAUI | `ChatBlazorMauiBlazorOptions` | `AbpRemoteServiceOptions.RemoteServices.Default.BaseUrl`. |
| MudBlazor Server | `ChatBlazorMudBlazorServerOptions` | The current application URL. |
| MudBlazor WebAssembly | `ChatBlazorMudBlazorWebAssemblyOptions` | `AbpRemoteServiceOptions.RemoteServices.Default.BaseUrl`. |
| MudBlazor MAUI | `ChatBlazorMudBlazorMauiBlazorOptions` | `AbpRemoteServiceOptions.RemoteServices.Default.BaseUrl`. |
The module appends the `/signalr-hubs/chat` path to the resolved base URL.
For example, the Chat module remote endpoint URL can be configured for Blazor WebAssembly via the `ChatBlazorWebAssemblyOptions`:
```csharp
Configure(options =>
{
options.SignalrUrl = builder.Configuration["RemoteServices:Chat:BaseUrl"];
});
```
```json
"RemoteServices": {
"Default": {
"BaseUrl": "Default url here"
},
"Chat": {
"BaseUrl": "Chat remote url here"
}
},
```
> If you don't set the `BaseUrl`, the `Default.BaseUrl` will be used as fallback.
## Distributed Events
The module defines the following Event Transfer Object types for real-time operations:
| Event Transfer Object | Operation | SignalR client method |
| --- | --- | --- |
| `ChatMessageEto` | A message is sent. | `ReceiveMessage` |
| `ChatDeletedMessageEto` | A message is deleted. | `DeleteMessage` |
| `ChatDeletedConversationEto` | A conversation is deleted. | `DeleteConversation` |
The default application-layer implementation of `IRealTimeChatMessageSender` publishes these events to the distributed event bus. The `Volo.Chat.SignalR` package replaces that implementation in the SignalR host, handles the distributed events and sends them to the target user through the corresponding SignalR client method. See the [standard distributed events](../framework/infrastructure/event-bus/distributed) for more information about distributed events.