Introduction
In this article we're going to look at Azure Communication Services with integrated angular applications. When you need to interact with your clients, friends, or colleagues, you need applications that enable you to chat from Azure Communication Services. Azure Communication Services provides some collection of APIs in Azure that you can use to chat, send and receive SMS messages, make video and audio calls, and place and receive telephone calls. Here we are going to see chat only.
Create Azure Communication Service
If you want to follow along, you'll need the following:
To create an Azure Communication Services resource, after signing in to the Azure portal. In the upper-left corner of the page, select -> + Create a resource.
Enter text "Communication" into the search bar at the top of the portal.
Once I get the search result select the Communication Services, select the result, and click Create. You can now configure your Communication Services resource.
After you have selected the subscription and the resource group you can create a new one or select an existing resource group.
Add Instance Details for Resource Name and Data location. Once entered all the details please click Review + Create and Created. Here I have referred to the resource name TestSatAzureTips.
To manage your Communication Services resources, go to the Azure portal, and search for and select Azure Communication Services. On the Communication Services page, select the name of your resource.
To manage your Communication Services resources, go to the Azure portal, and search for and select Azure Communication Services. On the Communication Services page, select the name of your resource.
After navigating to your Communication Services resource, select Keys from the navigation menu and copy the Connection string or Endpoint values for usage by the Communication Services SDKs.
If we need to see the keys, please click the show values icons. You can also access key information using Azure CLI, like your resource group or the keys for a specific resource.
Before installing nodejs and angular CLI with basic project setup and then follow the below codes. Azure Communication Chat client library for angular. Please follow and install the libraries in an angular application.
npm install @azure/communication-common --save
npm install @azure/communication-identity --save
npm install @azure/communication-signaling --save
npm install @azure/communication-chat --save
After installing the packages. here I have created two new components azure-chat.component.ts, azure-chat. component.html and chat-thread.component.ts, chat-thread.component.html and copy the codes below.
azure-chat.component.ts
import {
Component,
OnInit
} from '@angular/core';
import {
ChatClient,
ChatThreadClient
} from '@azure/communication-chat';
import {
HttpClient
} from '@angular/common/http';
import {
AzureCommunicationTokenCredential
} from '@azure/communication-common';
import {
CommunicationIdentityClient
} from '@azure/communication-identity';
@Component({
selector: 'app-azure-chat',
templateUrl: './azure-chat.component.html',
// styleUrls: ['./azure-chat.component.css']
})
export class AzureChatComponent implements OnInit {
endpointUrl = 'https://xxxxx.communication.azure.com';
communicationUserId: string = '';
userAccessToken: string = '';
chatClient: ChatClient | any = null;
Name: string = '';
display_name: string = '';
threadLink: string = '';
chatThreadClient: ChatThreadClient | any = null;
other_user_CommunicationId: string = '';
other_display_name: string = '';
constructor(public http: HttpClient) {}
async ngOnInit() {
// Your unique Azure Communication service endpoint
const ConnectionString = 'xxxxxxxx';
const client = new CommunicationIdentityClient(ConnectionString);
const user = await client.createUser();
const token = await client.getToken(user, ["chat"]);
this.userAccessToken = token.token;
this.communicationUserId = user.communicationUserId;
this.chatClient = new ChatClient(this.endpointUrl, new AzureCommunicationTokenCredential(this.userAccessToken));
}
async createChatThread() {
let createChatThreadRequest = {
topic: this.Name
};
let createChatThreadOptions = {
participants: [{
id: {
communicationUserId: this.communicationUserId
},
displayName: this.display_name
}]
};
let createChatThreadResult = await this.chatClient.createChatThread(createChatThreadRequest, createChatThreadOptions);
let threadId = createChatThreadResult.chatThread.id;
console.log(`Thread created:${threadId}`);
this.threadLink = 'http://localhost:4200/chat/' + threadId;
this.chatThreadClient = this.chatClient.getChatThreadClient(threadId);
}
async AddUserParticipantToTheChatThread() {
let addParticipantsRequest = {
participants: [{
id: {
communicationUserId: this.other_user_CommunicationId
},
displayName: this.other_display_name
}]
};
let addUser = await this.chatThreadClient.addParticipants(addParticipantsRequest);
console.log(addUser);
}
async listAllChatThreads() {
let threads = this.chatClient.listChatThreads();
for await (const thread of threads) {
console.log(thread);
}
}
}
azure-chat. Component.html
<label for="">Add Thread</label>
<br>
<br>
<input type="text" placeholder="Group Name" [(ngModel)]="Name" name="group Name">
<input type="text" placeholder="Your Display Name" [(ngModel)]="display_name" name="display name">
<button (click)="createChatThread()">Submit</button>
<br>
<br>
<a *ngIf="threadLink" href="{{threadLink}}">{{threadLink}}</a>
<br>
<br>
<br>
<br>
<br>
<div *ngIf="threadLink">
<label for="">Add user to thread</label>
<br>
<br>
<input type="text" placeholder="User id" [(ngModel)]="other_user_CommunicationId" name="otherCommunicationUserId">
<input type="text" placeholder="Display Name" [(ngModel)]="other_display_name" name="otherDisplayName">
<button (click)="AddUserParticipantToTheChatThread()">Submit</button>
</div>
chat-thread.component.ts
import {
Component,
OnInit,
ChangeDetectorRef
} from '@angular/core';
import {
ChatClient,
ChatThreadClient
} from '@azure/communication-chat';
import {
HttpClient
} from '@angular/common/http';
import {
AzureCommunicationTokenCredential
} from '@azure/communication-common';
import {
ActivatedRoute
} from '@angular/router';
import {
CommunicationIdentityClient
} from '@azure/communication-identity';
@Component({
selector: 'app-chat-thread',
templateUrl: './chat-thread.component.html',
})
export class ChatThreadComponent implements OnInit {
endpointUrl = 'https://xxxxx.communication.azure.com';
communicationUserId: any;
userAccessToken: string = '';
chatClient: ChatClient | any = null;
topicName: string = '';
displayName: string = '';
currentThreadId: any;
chatThreadClient: ChatThreadClient | any = null;
messages: message[] = [];
sendMsg: message = {
message: '',
sender: ''
};
constructor(public http: HttpClient, private changeDetection: ChangeDetectorRef, private route: ActivatedRoute) {}
async ngOnInit(): Promise < void > {
const ConnectionString = 'xxxxxxxx';
const client = new CommunicationIdentityClient(ConnectionString);
this.currentThreadId = this.route.snapshot.paramMap.get('threadid');
this.communicationUserId = this.route.snapshot.paramMap.get('userid');
let data = await client.getToken(this.communicationUserId, ["chat"]);
this.userAccessToken = data.token;
this.chatClient = new ChatClient(this.endpointUrl, new AzureCommunicationTokenCredential(this.userAccessToken));
this.chatThreadClient = this.chatClient.getChatThreadClient(this.currentThreadId);
this.setupHandlers();
}
async setupHandlers() {
this.getListMessages();
await this.chatClient.startRealtimeNotifications();
this.chatClient.on("chatMessageReceived", ((state: any) => {
this.getListMessages();
}).bind(this));
this.chatClient.on("chatMessageEdited", ((state: any) => {
this.getListMessages();
}).bind(this));
this.chatClient.on("chatMessageDeleted", ((state: any) => {
this.getListMessages();
}).bind(this));
this.chatClient.on("typingIndicatorReceived", ((state: any) => {
this.getListMessages();
}).bind(this));
this.chatClient.on("readReceiptReceived", ((state: any) => {
this.getListMessages();
}).bind(this));
this.chatClient.on("chatThreadCreated", ((state: any) => {
this.getListMessages();
}).bind(this));
this.chatClient.on("chatThreadDeleted", ((state: any) => {
this.getListMessages();
}).bind(this));
this.chatClient.on("chatThreadPropertiesUpdated", ((state: any) => {
this.getListMessages();
}).bind(this));
this.chatClient.on("participantsAdded", ((state: any) => {
this.getListMessages();
}).bind(this));
this.chatClient.on("participantsRemoved", ((state: any) => {
this.getListMessages();
}).bind(this));
}
async getListMessages() {
this.messages = [];
const messages = this.chatThreadClient.listMessages();
for await (const message of messages) {
if (message.type == "text") {
let msg: message = {
sender: message.senderDisplayName,
message: message.content.message
};
this.messages.push(msg);
}
}
this.changeDetection.detectChanges();
}
async sendMessage() {
let sendMessageRequest = {
content: this.sendMsg.message
};
let sendMessageOptions = {
senderDisplayName: this.sendMsg.sender,
type: 'text'
};
const sendChatMessageResult = await this.chatThreadClient.sendMessage(sendMessageRequest, sendMessageOptions);
const messageId = sendChatMessageResult.id;
this.sendMsg = {
message: '',
sender: ''
};
}
async ListUsersInChatThread() {
const participants = this.chatThreadClient.listParticipants();
for await (const participant of participants) {
console.log(participant);
}
}
async RemoveUserFromChatThread(userId: any) {
await this.chatThreadClient.removeParticipant({
communicationUserId: userId
});
await this.ListUsersInChatThread();
}
}
interface message {
sender: string,
message: string
}
chat-thread.component.html
<div *ngFor="let message of messages;" class="row">
<label for="">{{message.sender}}</label> : <label for="">{{message.message}}</label>
</div>
<br>
<br>
<br>
<br>
<div class="col-md-12">
<label for="">Send New Message</label>
<br>
<br>
<input type="text" placeholder="Sender" [(ngModel)]="sendMsg.sender" name="sender">
<input type="text" placeholder="Message" [(ngModel)]="sendMsg.message" name="message">
<button (click)="sendMessage()">Submit</button>
</div>
app-routing.module.ts
import {
ChatThreadComponent
} from './chat-thread/chat-thread.component';
import {
AzureChatComponent
} from './azure-chat/azure-chat.component';
import {
NgModule
} from '@angular/core';
import {
RouterModule,
Routes
} from '@angular/router';
const routes: Routes = [{
path: '',
component: AzureChatComponent
}, {
path: 'chat/:threadid/:userid',
component: ChatThreadComponent
}];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule {}
App.module.ts
import {
NgModule
} from '@angular/core';
import {
BrowserModule
} from '@angular/platform-browser';
import {
AppRoutingModule
} from './app-routing.module';
import {
AppComponent
} from './app.component';
import {
HttpClientModule
} from '@angular/common/http';
import {
FormsModule
} from '@angular/forms';
import {
AzureChatComponent
} from './azure-chat/azure-chat.component';
import {
ChatThreadComponent
} from './chat-thread/chat-thread.component';
@NgModule({
declarations: [
AppComponent,
AzureChatComponent,
ChatThreadComponent
],
imports: [
FormsModule,
HttpClientModule,
BrowserModule,
AppRoutingModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule {}
Once copied all the codes please run the application follow the below steps for Create a chat thread, Create a thread with 2 users, send a message to the thread, and Receive messages from a thread.
Here I have created a Test Group Chat name with Admin for display name. Once entered text please click to submit the button and the thread was created.
Example -1
Example -2
Next, add otherCommunicationUserId to with display name and add more users using addParticipants functions. For example, created user communicationUserId, I have marked like xxxxx with the user name. Once created the users we can able to create the chat link. Like the format is = (Thread + "/ " + CommunicationUserId).
Once open the chat link in the browser follow the images below to send and receive messages from one to another.
Test user 1 sent the message
Test user 2 received the message and sent the message.
Admin Received both Test user 1 & Test user 2 and sent the message.
Finally, Azure Communication Service integrated successfully with the angular application. We are to send and receive messages with our own chat window. I hope this article is most helpful for us.