In this article, we will learn the azure communication chat using Angular and generate tokens in the back-end ASP.Net Core.
First of all, we have to create a communication service resource from here and keep it private.
After generating the resource connection string, we have to create 2 APIs in the backend for token generation.
Install the following NuGet packages:
Add connection string in appsettings.json :
"ResourceConnectionString": "endpoint=https://test.westus.communication.azure.com/;accesskey=SAMPLE KEY 1234"
Add new API Controller :
using System; using System.Threading.Tasks; using Azure; using Azure.Communication; using Azure.Communication.Identity; using Azure.Core; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Configuration; namespace Calling { public class UserTokenController : Controller { private readonly CommunicationIdentityClient _client; public UserTokenController(IConfiguration configuration) { _client = new CommunicationIdentityClient(configuration["ResourceConnectionString"]); } /// <summary> /// Create User and Generate token /// </summary> /// <returns></returns> [Route("/token")] [HttpGet] public async Task<IActionResult> GetAsync() { try { Response<CommunicationUserIdentifierAndToken> response = await _client.CreateUserAndTokenAsync(scopes: new[] { CommunicationTokenScope.Chat }); var responseValue = response.Value; var jsonFormattedUser = new { communicationUserId = responseValue.User.Id }; var clientResponse = new { user = jsonFormattedUser, token = responseValue.AccessToken.Token, expiresOn = responseValue.AccessToken.ExpiresOn }; return this.Ok(clientResponse); } catch (RequestFailedException ex) { Console.WriteLine($"Error occured while Generating Token: {ex}"); return this.Ok(this.Json(ex)); } } /// <summary> /// Generate token for the User /// </summary> /// <returns></returns> [Route("/refreshToken/{identity}")] [HttpGet] public async Task<IActionResult> GetAsync(string identity) { try { CommunicationUserIdentifier identifier = new CommunicationUserIdentifier(identity); Response<AccessToken> response = await _client.GetTokenAsync(identifier, scopes: new[] { CommunicationTokenScope.Chat }); var responseValue = response.Value; var clientResponse = new { token = responseValue.Token, expiresOn = responseValue.ExpiresOn }; return this.Ok(clientResponse); } catch (RequestFailedException ex) { Console.WriteLine($"Error occured while Generating Token: {ex}"); return this.Ok(this.Json(ex)); } } } }
Install the following packages in angular:
npm install @azure/communication-common --save npm install @azure/communication-identity --save npm install @azure/communication-signaling --save npm install @azure/communication-chat --save
create new component 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'; @Component({ selector: 'app-azure-chat', templateUrl: './azure-chat.component.html', styleUrls: ['./azure-chat.component.css'] }) export class AzureChatComponent implements OnInit { endpointUrl = 'https://test.westus.communication.azure.com'; communicationUserId: string = ''; userAccessToken: string = ''; chatClient: ChatClient | any = null; topicName: string = ''; displayName: string = ''; threadLink: string = ''; chatThreadClient: ChatThreadClient | any = null; otherCommunicationUserId: string = ''; otherDisplayName: string = ''; constructor(public http: HttpClient) { } ngOnInit(): void { // https://localhost:44316/token -----> For create an User and Generate Token // https://localhost:44316/refreshToken/{identity} -----> For Generate Token this.http.get('https://localhost:44316/token').subscribe((data: any) => { this.userAccessToken = data.token; this.communicationUserId = data.user.communicationUserId; this.chatClient = new ChatClient(this.endpointUrl, new AzureCommunicationTokenCredential(this.userAccessToken)); }); } async createChatThread() { let createChatThreadRequest = { topic: this.topicName }; let createChatThreadOptions = { participants: [ { id: { communicationUserId: this.communicationUserId }, displayName: this.displayName } ] }; 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.otherCommunicationUserId }, displayName: this.otherDisplayName } ] }; 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="Topic Name" [(ngModel)]="topicName" name="topicName"> <input type="text" placeholder="Your Display Name" [(ngModel)]="displayName" name="displayName"> <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)]="otherCommunicationUserId" name="otherCommunicationUserId"> <input type="text" placeholder="Display Name" [(ngModel)]="otherDisplayName" name="otherDisplayName"> <button (click)="AddUserParticipantToTheChatThread()">Submit</button> </div>
create new component 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'; @Component({ selector: 'app-chat-thread', templateUrl: './chat-thread.component.html', styleUrls: ['./chat-thread.component.css'] }) export class ChatThreadComponent implements OnInit { endpointUrl = 'https://test.westus.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) { } ngOnInit(): void { this.currentThreadId = this.route.snapshot.paramMap.get('threadid'); this.communicationUserId = this.route.snapshot.paramMap.get('userid'); this.http.get('https://localhost:44316/refreshToken/' + this.communicationUserId).subscribe((data: any) => { this.userAccessToken = data.token; //this.communicationUserId = data.user.communicationUserId; 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/chat-thread/chat-thread.component'; import { AzureChatComponent } from './chat/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 { HttpClientModule } from '@angular/common/http'; import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { FormsModule } from '@angular/forms'; import { AppRoutingModule } from './app-routing.module'; import { AppComponent } from './app.component'; import { AzureChatComponent } from './chat/azure-chat/azure-chat.component'; import { ChatThreadComponent } from './chat/chat-thread/chat-thread.component'; @NgModule({ declarations: [ AppComponent, AzureChatComponent, ChatThreadComponent ], imports: [ FormsModule, HttpClientModule, BrowserModule, AppRoutingModule ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }
Now you have to run Angular and API both projects and Assume the following ports:
Outputs :
You can gift me a coffee from this link if I saved your valuable time 🙂
In this article, we have to show Create and Used PIPE in angular
In this article, we have to show Create and Used PIPE in angular
In this article, we have to show Create and Used PIPE in angular