Rövid útmutató: Csatlakozás a csevegőalkalmazáshoz Egy Teams-értekezlethez
Ismerkedjen meg a Azure Communication Services a csevegési megoldás Microsoft Teamshez való csatlakoztatásával.
Ebben a rövid útmutatóban megtudhatja, hogyan cseveghet Teams-értekezleteken a JavaScripthez készült Azure Communication Services Chat SDK használatával.
Példakód
Keresse meg a gitHubon a rövid útmutató véglegesített kódját.
Előfeltételek
- Teams-környezet.
- Egy működő csevegőalkalmazás.
Csatlakozás az értekezlet csevegéséhez
A Communication Services-felhasználók névtelen felhasználóként csatlakozhatnak a Teams-értekezletekhez a Hívó SDK használatával. Az értekezlethez való csatlakozás résztvevőként is hozzáadja őket az értekezlet csevegéséhez, ahol üzeneteket küldhetnek és fogadhatnak az értekezlet többi felhasználójával. A felhasználó nem fog tudni hozzáférni az értekezlethez való csatlakozás előtt elküldött csevegőüzenetekhez, és nem tud üzeneteket küldeni vagy fogadni az értekezlet befejezése után. Az értekezlethez való csatlakozáshoz és a csevegés megkezdéséhez kövesse a következő lépéseket.
Új Node.js-alkalmazás létrehozása
Nyissa meg a terminált vagy a parancsablakot, hozzon létre egy új könyvtárat az alkalmazáshoz, és navigáljon hozzá.
mkdir chat-interop-quickstart && cd chat-interop-quickstart
Futtassa a parancsot npm init -y
egy package.json fájl létrehozásához az alapértelmezett beállításokkal.
npm init -y
A csevegőcsomagok telepítése
npm install
Az paranccsal telepítheti a JavaScripthez szükséges Communication Services SDK-kat.
npm install @azure/communication-common --save
npm install @azure/communication-identity --save
npm install @azure/communication-signaling --save
npm install @azure/communication-chat --save
npm install @azure/communication-calling --save
A --save
beállítás függőségként sorolja fel a tárat a package.json fájlban.
Az alkalmazás-keretrendszer beállítása
Ez a rövid útmutató a Webpack használatával köti össze az alkalmazásegységeket. Futtassa a következő parancsot a Webpack, a webpack-cli és a webpack-dev-server npm csomagok telepítéséhez, és sorolja fel őket fejlesztési függőségként a package.json fájlban:
npm install webpack@4.42.0 webpack-cli@3.3.11 webpack-dev-server@3.10.3 --save-dev
Hozzon létre egy index.html fájlt a projekt gyökérkönyvtárában. Ezzel a fájllal olyan alapszintű elrendezést konfigurálunk, amely lehetővé teszi, hogy a felhasználó bekapcsolódjon egy értekezletbe, és csevegni kezdjen.
A Teams felhasználói felület vezérlőinek hozzáadása
Cserélje le a index.html kódját a következő kódrészletre. A lap tetején található szövegmezők segítségével adhatja meg a Teams-értekezlet környezetét és az értekezlet szálazonosítóját. A "Teams-értekezletbe való bekapcsolódás" gomb a megadott értekezlethez való csatlakozáshoz használható. A lap alján megjelenik egy csevegési előugró ablak. Segítségével üzeneteket küldhet az értekezlet szálán, és valós időben jeleníti meg a szálon küldött üzeneteket, miközben a Communication Services felhasználója tagja.
<!DOCTYPE html>
<html>
<head>
<title>Communication Client - Calling and Chat Sample</title>
<style>
body {box-sizing: border-box;}
/* The popup chat - hidden by default */
.chat-popup {
display: none;
position: fixed;
bottom: 0;
left: 15px;
border: 3px solid #f1f1f1;
z-index: 9;
}
.message-box {
display: none;
position: fixed;
bottom: 0;
left: 15px;
border: 3px solid #FFFACD;
z-index: 9;
}
.form-container {
max-width: 300px;
padding: 10px;
background-color: white;
}
.form-container textarea {
width: 90%;
padding: 15px;
margin: 5px 0 22px 0;
border: none;
background: #e1e1e1;
resize: none;
min-height: 50px;
}
.form-container .btn {
background-color: #4CAF40;
color: white;
padding: 14px 18px;
margin-bottom:10px;
opacity: 0.6;
border: none;
cursor: pointer;
width: 100%;
}
.container {
border: 1px solid #dedede;
background-color: #F1F1F1;
border-radius: 3px;
padding: 8px;
margin: 8px 0;
}
.darker {
border-color: #ccc;
background-color: #ffdab9;
margin-left: 25px;
margin-right: 3px;
}
.lighter {
margin-right: 20px;
margin-left: 3px;
}
.container::after {
content: "";
clear: both;
display: table;
}
</style>
</head>
<body>
<h4>Azure Communication Services</h4>
<h1>Calling and Chat Quickstart</h1>
<input id="teams-link-input" type="text" placeholder="Teams meeting link"
style="margin-bottom:1em; width: 300px;" />
<input id="thread-id-input" type="text" placeholder="Chat thread id"
style="margin-bottom:1em; width: 300px;" />
<p>Call state <span style="font-weight: bold" id="call-state">-</span></p>
<div>
<button id="join-meeting-button" type="button">
Join Teams Meeting
</button>
<button id="hang-up-button" type="button" disabled="true">
Hang Up
</button>
</div>
<div class="chat-popup" id="chat-box">
<div id="messages-container"></div>
<form class="form-container">
<textarea placeholder="Type message.." name="msg" id="message-box" required></textarea>
<button type="button" class="btn" id="send-message">Send</button>
</form>
</div>
<script src="./bundle.js"></script>
</body>
</html>
A Teams felhasználói felület vezérlőinek engedélyezése
Cserélje le a client.js fájl tartalmát a következő kódrészletre.
A kódrészleten belül cserélje le a
SECRET_CONNECTION_STRING
a kommunikációs szolgáltatás kapcsolati sztringENDPOINT_URL
a kommunikációs szolgáltatás végpontjának URL-címével
import { CallClient, CallAgent } from "@azure/communication-calling";
import { AzureCommunicationTokenCredential } from "@azure/communication-common";
import { CommunicationIdentityClient } from "@azure/communication-identity";
import { ChatClient } from "@azure/communication-chat";
let call;
let callAgent;
let chatClient;
let chatThreadClient;
const meetingLinkInput = document.getElementById('teams-link-input');
const threadIdInput = document.getElementById('thread-id-input');
const callButton = document.getElementById("join-meeting-button");
const hangUpButton = document.getElementById("hang-up-button");
const callStateElement = document.getElementById('call-state');
const messagesContainer = document.getElementById("messages-container");
const chatBox = document.getElementById("chat-box");
const sendMessageButton = document.getElementById("send-message");
const messagebox = document.getElementById("message-box");
var userId = '';
var lastMessage = '';
var previousMessage = '';
async function init() {
const connectionString = "<SECRET_CONNECTION_STRING>";
const endpointUrl = "<ENDPOINT_URL>";
const identityClient = new CommunicationIdentityClient(connectionString);
let identityResponse = await identityClient.createUser();
userId = identityResponse.communicationUserId;
console.log(`\nCreated an identity with ID: ${identityResponse.communicationUserId}`);
let tokenResponse = await identityClient.getToken(identityResponse, [
"voip",
"chat",
]);
const { token, expiresOn } = tokenResponse;
console.log(`\nIssued an access token that expires at: ${expiresOn}`);
console.log(token);
const callClient = new CallClient();
const tokenCredential = new AzureCommunicationTokenCredential(token);
callAgent = await callClient.createCallAgent(tokenCredential);
callButton.disabled = false;
chatClient = new ChatClient(
endpointUrl,
new AzureCommunicationTokenCredential(token)
);
console.log('Azure Communication Chat client created!');
}
init();
callButton.addEventListener("click", async () => {
// join with meeting link
call = callAgent.join({meetingLink: meetingLinkInput.value}, {});
call.on('stateChanged', () => {
callStateElement.innerText = call.state;
})
// toggle button and chat box states
chatBox.style.display = "block";
hangUpButton.disabled = false;
callButton.disabled = true;
messagesContainer.innerHTML = "";
console.log(call);
// open notifications channel
await chatClient.startRealtimeNotifications();
// subscribe to new message notifications
chatClient.on("chatMessageReceived", (e) => {
console.log("Notification chatMessageReceived!");
// check whether the notification is intended for the current thread
if (threadIdInput.value != e.threadId) {
return;
}
if (e.sender.communicationUserId != userId) {
renderReceivedMessage(e.message);
}
else {
renderSentMessage(e.message);
}
});
chatThreadClient = await chatClient.getChatThreadClient(threadIdInput.value);
});
async function renderReceivedMessage(message) {
previousMessage = lastMessage;
lastMessage = '<div class="container lighter">' + message + '</div>';
messagesContainer.innerHTML = previousMessage + lastMessage;
}
async function renderSentMessage(message) {
previousMessage = lastMessage;
lastMessage = '<div class="container darker">' + message + '</div>';
messagesContainer.innerHTML = previousMessage + lastMessage;
}
hangUpButton.addEventListener("click", async () =>
{
// end the current call
await call.hangUp();
// toggle button states
hangUpButton.disabled = true;
callButton.disabled = false;
callStateElement.innerText = '-';
// toggle chat states
chatBox.style.display = "none";
messages = "";
});
sendMessageButton.addEventListener("click", async () =>
{
let message = messagebox.value;
let sendMessageRequest = { content: message };
let sendMessageOptions = { senderDisplayName : 'Jack' };
let sendChatMessageResult = await chatThreadClient.sendMessage(sendMessageRequest, sendMessageOptions);
let messageId = sendChatMessageResult.id;
messagebox.value = '';
console.log(`Message sent!, message id:${messageId}`);
});
A csevegőszál résztvevőinek megjelenített neveit nem a Teams-ügyfél állítja be. A rendszer null értékként adja vissza a neveket az API-ban a résztvevők listázásakor, az participantsAdded
eseményben és az participantsRemoved
eseményben. A csevegés résztvevőinek megjelenített nevei lekérhetők az remoteParticipants
call
objektum mezőjéből. Ha értesítést kap egy névsor-módosításról, ezzel a kóddal lekérheti a hozzáadott vagy eltávolított felhasználó nevét:
var displayName = call.remoteParticipants.find(p => p.identifier.communicationUserId == '<REMOTE_USER_ID>').displayName;
Teams-értekezlet csevegési szálának lekérése Egy Communication Services-felhasználó számára
A Teams-értekezlet részletei a Graph API-kkal kérhetők le, amelyek a Graph dokumentációjában találhatók. A Communication Services Calling SDK elfogad egy teljes Teams-értekezlethivatkozást vagy egy értekezlet-azonosítót. Az erőforrás részeként onlineMeeting
lesznek visszaadva, amely a joinWebUrl
tulajdonság alatt érhető el
A Graph API-kkal a következőt is beszerezheti threadID
: . A válasz tartalmaz egy chatInfo
objektumot a threadID
következővel: .
A szükséges értekezletadatokat és a szálazonosítót a Teams-értekezlet-összehívás Bekapcsolódás értekezlet url-címéből is lekérheti.
A Teams-értekezletek hivatkozása a következőképpen néz ki: https://teams.microsoft.com/l/meetup-join/meeting_chat_thread_id/1606337455313?context=some_context_here
. meeting_chat_thread_id
Itt threadId
található a hivatkozás. Használat előtt győződjön meg arról, hogy a meeting_chat_thread_id
nincs beágyazva. A formátumnak a következőnek kell lennie: 19:meeting_ZWRhZDY4ZGUtYmRlNS00OWZaLTlkZTgtZWRiYjIxOWI2NTQ4@thread.v2
A kód futtatása
A Webpack-felhasználók a webpack-dev-server
használatával hozhatják létre és futtathatják az alkalmazást. Futtassa a következő parancsot az alkalmazásgazda helyi webkiszolgálón való kötegeléséhez:
npx webpack-dev-server --entry ./client.js --output bundle.js --debug --devtool inline-source-map
Nyissa meg a böngészőt, és keresse meg a következőt: http://localhost:8080/
. Az alkalmazásnak az alábbi képernyőképen látható módon kell megjelennie:
Szúrja be a Teams-értekezlet hivatkozását és szálazonosítóját a szövegmezőkbe. A Teams-értekezlethez való csatlakozáshoz nyomja le a Join Teams Meeting (Bekapcsolódás a Teams-értekezletbe ) gombot. Miután a Communication Services-felhasználót beengedték az értekezletbe, cseveghet a Communication Services-alkalmazásból. A csevegés megkezdéséhez lépjen a lap alján található mezőbe. Az egyszerűség kedvéért az alkalmazás csak az utolsó két üzenetet jeleníti meg a csevegésben.
Megjegyzés
Bizonyos funkciók jelenleg nem támogatottak a Teamsszel való együttműködési forgatókönyvekben. További információ a támogatott funkciókról: Teams-értekezletek képességei a Teams külső felhasználói számára
Ebben a rövid útmutatóban megtudhatja, hogyan cseveghet Teams-értekezleteken az iOS-hez készült Azure Communication Services Chat SDK használatával.
Előfeltételek
- Teams-környezet.
- Egy működő hívó alkalmazás.
Csatlakozás az értekezlet csevegéséhez
A Communication Services-felhasználók névtelen felhasználóként csatlakozhatnak a Teams-értekezletekhez a Hívó SDK használatával. Az értekezlethez való csatlakozás résztvevőként is hozzáadja őket az értekezlet csevegéséhez, ahol üzeneteket küldhetnek és fogadhatnak az értekezlet többi felhasználójával. A felhasználó nem fog tudni hozzáférni az értekezlethez való csatlakozás előtt elküldött csevegőüzenetekhez, és nem tud üzeneteket küldeni vagy fogadni az értekezlet befejezése után. Az értekezlethez való csatlakozáshoz és a csevegés megkezdéséhez kövesse a következő lépéseket.
Csevegés hozzáadása a Teams-hívó alkalmazáshoz
Törölje a Podfile.lock
podfájl tartalmát, és cserélje le a következőre:
platform :ios, '13.0'
use_frameworks!
target 'AzureCommunicationCallingSample' do
pod 'AzureCommunicationCalling', '~> 1.0.0-beta.12'
pod 'AzureCommunicationChat', '~> 1.0.0-beta.11'
end
A csevegőcsomagok telepítése
Futtassa a parancsot pod install
az AzureCommunicationChat-csomag telepítéséhez.
A telepítés után nyissa meg a .xcworkspace
fájlt.
Az alkalmazás-keretrendszer beállítása
Importálja az AzureCommunicationChat-csomagot ContentView.swift
a következő kódrészlet hozzáadásával:
import AzureCommunicationChat
A Teams felhasználói felület vezérlőinek hozzáadása
Adja ContentView.swift
hozzá a következő kódrészletet a meglévő állapotváltozók alá.
// Chat
@State var chatClient: ChatClient?
@State var chatThreadClient: ChatThreadClient?
@State var chatMessage: String = ""
@State var meetingMessages: [MeetingMessage] = []
let displayName: String = "<YOUR_DISPLAY_NAME_HERE>"
Cserélje le <YOUR_DISPLAY_NAME_HERE>
a elemet a csevegésben használni kívánt megjelenítendő névre.
Ezután módosítjuk az űrlapot Section
, hogy megjelenítsük a csevegési üzeneteinket, és felhasználói felületi vezérlőket adjunk hozzá a csevegéshez.
Adja hozzá a következő kódrészletet a meglévő űrlaphoz. Közvetlenül a Szöveg nézet Text(recordingStatus)
után az állapot rögzítéséhez.
VStack(alignment: .leading) {
ForEach(meetingMessages, id: \.id) { message in
let currentUser: Bool = (message.displayName == self.displayName)
let foregroundColor = currentUser ? Color.white : Color.black
let background = currentUser ? Color.blue : Color(.systemGray6)
let alignment = currentUser ? HorizontalAlignment.trailing : HorizontalAlignment.leading
VStack {
Text(message.displayName).font(Font.system(size: 10))
Text(message.content)
}
.alignmentGuide(.leading) { d in d[alignment] }
.padding(10)
.foregroundColor(foregroundColor)
.background(background)
.cornerRadius(10)
}
}.frame(minWidth: 0, maxWidth: .infinity)
TextField("Enter your message...", text: $chatMessage)
Button(action: sendMessage) {
Text("Send Message")
}.disabled(chatThreadClient == nil)
Ezután módosítsa a címet a következőre: Chat Teams Quickstart
. Módosítsa az alábbi sort ezzel a címmel.
.navigationBarTitle("Chat Teams Quickstart")
A Teams felhasználói felület vezérlőinek engedélyezése
A ChatClient inicializálása
A példányosítás és a ChatClient
valós idejű értesítések engedélyezése. Valós idejű értesítéseket használunk a csevegési üzenetek fogadásához.
NavigationView
.onAppear
A fájlban adja hozzá az alábbi kódrészletet a meglévő kód után, amely inicializálja a fájltCallAgent
.
// Initialize the ChatClient
do {
let endpoint = "COMMUNICATION_SERVICES_RESOURCE_ENDPOINT_HERE>"
let credential = try CommunicationTokenCredential(token: "<USER_ACCESS_TOKEN_HERE>")
self.chatClient = try ChatClient(
endpoint: endpoint,
credential: credential,
withOptions: AzureCommunicationChatClientOptions()
)
self.message = "ChatClient successfully created"
// Start real-time notifications
self.chatClient?.startRealTimeNotifications() { result in
switch result {
case .success:
print("Real-time notifications started")
// Receive chat messages
self.chatClient?.register(event: ChatEventId.chatMessageReceived, handler: receiveMessage)
case .failure:
print("Failed to start real-time notifications")
self.message = "Failed to enable chat notifications"
}
}
} catch {
print("Unable to create ChatClient")
self.message = "Please enter a valid endpoint and Chat token in source code"
return
}
Cserélje le a elemet <COMMUNICATION_SERVICES_RESOURCE_ENDPOINT_HERE>
a Communication Services-erőforrás végpontjára.
Cserélje le a elemet <USER_ACCESS_TOKEN_HERE>
egy csevegési hatókörrel rendelkező hozzáférési jogkivonatra.
További információ a felhasználói hozzáférési jogkivonatokról: Felhasználói hozzáférési jogkivonat
A ChatThreadClient inicializálása
A meglévő joinTeamsMeeting()
függvényen belül inicializáljuk azt ChatThreadClient
, miután a felhasználó csatlakozott az értekezlethez.
A hívás self.callAgent?.join()
befejezési kezelőjének belsejében adja hozzá a kódot a megjegyzés // Initialize the ChatThreadClient
alá. A teljes kód alább látható.
self.callAgent?.join(with: teamsMeetingLinkLocator, joinCallOptions: joinCallOptions) { (call, error) in
if (error == nil) {
self.call = call
self.callObserver = CallObserver(self)
self.call!.delegate = self.callObserver
self.message = "Teams meeting joined successfully"
// Initialize the ChatThreadClient
do {
guard let threadId = getThreadId(from: self.meetingLink) else {
self.message = "Failed to join meeting chat"
return
}
self.chatThreadClient = try chatClient?.createClient(forThread: threadId)
self.message = "Joined meeting chat successfully"
} catch {
print("Failed to create ChatThreadClient")
self.message = "Failed to join meeting chat"
return
}
} else {
print("Failed to join Teams meeting")
}
}
Adja hozzá a következő segédfüggvényt a ContentView
() függvényhez, amellyel lekérheti a csevegési szál azonosítóját a csapat értekezlet-hivatkozásáról.
func getThreadId(from meetingLink: String) -> String? {
if let range = self.meetingLink.range(of: "meetup-join/") {
let thread = self.meetingLink[range.upperBound...]
if let endRange = thread.range(of: "/")?.lowerBound {
return String(thread.prefix(upTo: endRange))
}
}
return nil
}
Üzenetek küldésének engedélyezése
Adja hozzá a sendMessage()
függvényt a következőhöz: ContentView
. Ez a függvény a ChatThreadClient
használatával küld üzeneteket a felhasználótól.
func sendMessage() {
let message = SendChatMessageRequest(
content: self.chatMessage,
senderDisplayName: self.displayName
)
self.chatThreadClient?.send(message: message) { result, _ in
switch result {
case .success:
print("Chat message sent")
case .failure:
print("Failed to send chat message")
}
self.chatMessage = ""
}
}
Üzenetek fogadásának engedélyezése
Az üzenetek fogadásához implementáljuk a kezelőt az eseményekhez ChatMessageReceived
. Amikor a rendszer új üzeneteket küld a szálnak, a kezelő hozzáadja az üzeneteket a meetingMessages
változóhoz, hogy azok megjelenjenek a felhasználói felületen.
Először adja hozzá a következő strukturát a következőhöz ContentView.swift
: . A felhasználói felület a struktúrában szereplő adatokat használja a csevegőüzenetek megjelenítéséhez.
struct MeetingMessage {
let id: String
let content: String
let displayName: String
}
Ezután adja hozzá a függvényt a receiveMessage()
következőhöz: ContentView
. Ez az a kezelő, amelyet minden alkalommal meghívnak, amikor egy ChatMessageReceived
esemény bekövetkezik.
func receiveMessage(response: Any, eventId: ChatEventId) {
let chatEvent: ChatMessageReceivedEvent = response as! ChatMessageReceivedEvent
let displayName: String = chatEvent.senderDisplayName ?? "Unknown User"
let content: String = chatEvent.message.replacingOccurrences(of: "<[^>]+>", with: "", options: String.CompareOptions.regularExpression)
self.meetingMessages.append(
MeetingMessage(
id: chatEvent.id,
content: content,
displayName: displayName
)
)
}
Kilépés a csevegésből
Amikor a felhasználó elhagyja a csapat értekezletét, töröljük a csevegést a felhasználói felületről. A teljes kód alább látható.
func leaveMeeting() {
if let call = call {
call.hangUp(options: nil, completionHandler: { (error) in
if error == nil {
self.message = "Leaving Teams meeting was successful"
// Clear the chat
self.meetingMessages.removeAll()
} else {
self.message = "Leaving Teams meeting failed"
}
})
} else {
self.message = "No active call to hanup"
}
}
Teams-értekezlet csevegési szálának lekérése Egy Communication Services-felhasználó számára
A Teams-értekezlet részletei a Graph API-kkal kérhetők le, amelyek a Graph dokumentációjában találhatók. A Communication Services Calling SDK elfogad egy teljes Teams-értekezlethivatkozást vagy egy értekezlet-azonosítót. A rendszer az erőforrás részeként adja vissza őket, amely a onlineMeeting
joinWebUrl
tulajdonság alatt érhető el
A Graph API-kkal a következőt is beszerezheti threadID
: . A válasz egy chatInfo
objektummal rendelkezik, amely a következőt threadID
tartalmazza: .
A szükséges értekezletadatokat és a szálazonosítót a Teams-értekezlet-összehívás Bekapcsolódás értekezlet url-címéből is lekérheti.
A Teams-értekezletek hivatkozása a következőképpen néz ki: https://teams.microsoft.com/l/meetup-join/meeting_chat_thread_id/1606337455313?context=some_context_here
. meeting_chat_thread_id
Itt threadID
található a hivatkozás. Használat előtt győződjön meg arról, hogy a meeting_chat_thread_id
nincs beágyazva. A formátumnak a következőnek kell lennie: 19:meeting_ZWRhZDY4ZGUtYmRlNS00OWZaLTlkZTgtZWRiYjIxOWI2NTQ4@thread.v2
A kód futtatása
Futtassa az alkalmazást.
A Teams-értekezlethez való csatlakozáshoz írja be a csapat értekezletére mutató hivatkozást a felhasználói felületen.
Miután csatlakozott a csapat értekezletéhez, be kell fogadnia a felhasználót az értekezletbe a csapat ügyfélprogramjában. Miután a felhasználót beengedték, és csatlakozott a csevegéshez, küldhet és fogadhat üzeneteket.
Megjegyzés
Bizonyos funkciók jelenleg nem támogatottak a Teamsszel való együttműködési forgatókönyvekben. További információ a támogatott funkciókról: Teams-értekezletek képességei a Teams külső felhasználói számára
Ebben a rövid útmutatóban megtudhatja, hogyan cseveghet Teams-értekezleteken az Android Azure Communication Services Chat SDK használatával.
Előfeltételek
- Teams-környezet.
- Egy működő hívó alkalmazás.
A Teams együttműködési lehetőségeinek engedélyezése
A Teams-értekezletekhez vendégfelhasználóként csatlakozó Communication Services-felhasználók csak akkor férhetnek hozzá az értekezlet csevegéséhez, ha csatlakoztak a Teams-értekezlethíváshoz. Tekintse meg a Teams interop dokumentációját, amelyből megtudhatja, hogyan vehet fel Egy Communication Services-felhasználót egy Teams-értekezlethívásba.
A funkció használatához mindkét entitás tulajdonos szervezetének tagja kell lennie.
Csatlakozás az értekezlet csevegéséhez
A Teams együttműködési funkciójának engedélyezése után a Communication Services-felhasználók külső felhasználóként csatlakozhatnak a Teams-híváshoz a Hívó SDK használatával. A híváshoz való csatlakozás résztvevőként is hozzáadja őket az értekezlet csevegéséhez, ahol üzeneteket küldhetnek és fogadhatnak a hívásban részt vevő többi felhasználóval. A felhasználó nem fog hozzáférni a híváshoz való csatlakozás előtt elküldött csevegőüzenetekhez. Az értekezlethez való csatlakozáshoz és a csevegés megkezdéséhez kövesse a következő lépéseket.
Csevegés hozzáadása a Teams-hívó alkalmazáshoz
A modul szintjén build.gradle
adja hozzá a függőséget a csevegési sdk-hez.
Fontos
Ismert probléma: Ha az Android Chat és a Calling SDK együttes használatát ugyanabban az alkalmazásban használja, a CsevegésI SDK valós idejű értesítési funkciója nem fog működni. Függőségfeloldási problémát fog kapni. Miközben egy megoldáson dolgozunk, kikapcsolhatja a valós idejű értesítések funkciót, ha hozzáadja a következő kivételeket az alkalmazás fájljában build.gradle
található CsevegésI SDK-függőséghez:
implementation ("com.azure.android:azure-communication-chat:1.0.0") {
exclude group: 'com.microsoft', module: 'trouter-client-android'
}
A Teams felhasználói felületének elrendezésének hozzáadása
Cserélje le a activity_main.xml kódját a következő kódrészletre. Bemeneteket ad hozzá a szálazonosítóhoz és az üzenetek küldéséhez, egy gombot a beírt üzenet küldéséhez és egy egyszerű csevegési elrendezést.
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<EditText
android:id="@+id/teams_meeting_thread_id"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="20dp"
android:layout_marginTop="128dp"
android:ems="10"
android:hint="Meeting Thread Id"
android:inputType="textUri"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<EditText
android:id="@+id/teams_meeting_link"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="20dp"
android:layout_marginTop="64dp"
android:ems="10"
android:hint="Teams meeting link"
android:inputType="textUri"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<LinearLayout
android:id="@+id/button_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:gravity="center"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/teams_meeting_thread_id">
<Button
android:id="@+id/join_meeting_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Join Meeting" />
<Button
android:id="@+id/hangup_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hangup" />
</LinearLayout>
<TextView
android:id="@+id/call_status_bar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="40dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<TextView
android:id="@+id/recording_status_bar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="20dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<ScrollView
android:id="@+id/chat_box"
android:layout_width="374dp"
android:layout_height="294dp"
android:layout_marginTop="40dp"
android:layout_marginBottom="20dp"
app:layout_constraintBottom_toTopOf="@+id/send_message_button"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/button_layout"
android:orientation="vertical"
android:gravity="bottom"
android:layout_gravity="bottom"
android:fillViewport="true">
<LinearLayout
android:id="@+id/chat_box_layout"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="bottom"
android:layout_gravity="top"
android:layout_alignParentBottom="true"/>
</ScrollView>
<EditText
android:id="@+id/message_body"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="20dp"
android:layout_marginTop="588dp"
android:ems="10"
android:inputType="textUri"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="Type your message here..."
tools:visibility="invisible" />
<Button
android:id="@+id/send_message_button"
android:layout_width="138dp"
android:layout_height="45dp"
android:layout_marginStart="133dp"
android:layout_marginTop="48dp"
android:layout_marginEnd="133dp"
android:text="Send Message"
android:visibility="invisible"
app:layout_constraintBottom_toTopOf="@+id/recording_status_bar"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.428"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/chat_box" />
</androidx.constraintlayout.widget.ConstraintLayout>
A Teams felhasználói felület vezérlőinek engedélyezése
Csomagok importálása és állapotváltozók definiálása
A tartalomhoz MainActivity.java
adja hozzá a következő importálást:
import android.graphics.Typeface;
import android.graphics.Color;
import android.text.Html;
import android.os.Handler;
import android.view.Gravity;
import android.view.View;
import android.widget.LinearLayout;
import java.util.Collections;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import com.azure.android.communication.chat.ChatThreadAsyncClient;
import com.azure.android.communication.chat.ChatThreadClientBuilder;
import com.azure.android.communication.chat.models.ChatMessage;
import com.azure.android.communication.chat.models.ChatMessageType;
import com.azure.android.communication.chat.models.ChatParticipant;
import com.azure.android.communication.chat.models.ListChatMessagesOptions;
import com.azure.android.communication.chat.models.SendChatMessageOptions;
import com.azure.android.communication.common.CommunicationIdentifier;
import com.azure.android.communication.common.CommunicationUserIdentifier;
import com.azure.android.core.rest.util.paging.PagedAsyncStream;
import com.azure.android.core.util.AsyncStreamHandler;
Adja hozzá az MainActivity
osztályhoz a következő változókat:
// InitiatorId is used to differentiate incoming messages from outgoing messages
private static final String InitiatorId = "<USER_ID>";
private static final String ResourceUrl = "<COMMUNICATION_SERVICES_RESOURCE_ENDPOINT>";
private String threadId;
private ChatThreadAsyncClient chatThreadAsyncClient;
// The list of ids corresponsding to messages which have already been processed
ArrayList<String> chatMessages = new ArrayList<>();
Cserélje le a elemet <USER_ID>
a csevegést kezdeményező felhasználó azonosítójára.
Cserélje le a elemet <COMMUNICATION_SERVICES_RESOURCE_ENDPOINT>
a Communication Services-erőforrás végpontjára.
A ChatThreadClient inicializálása
Miután csatlakozott az értekezlethez, példányosítsa a ChatThreadClient
csevegőösszetevőket, és tegye láthatóvá a csevegési összetevőket.
Frissítse a metódus végét MainActivity.joinTeamsMeeting()
az alábbi kóddal:
private void joinTeamsMeeting() {
...
EditText threadIdView = findViewById(R.id.teams_meeting_thread_id);
threadId = threadIdView.getText().toString();
// Initialize Chat Thread Client
chatThreadAsyncClient = new ChatThreadClientBuilder()
.endpoint(ResourceUrl)
.credential(new CommunicationTokenCredential(UserToken))
.chatThreadId(threadId)
.buildAsyncClient();
Button sendMessageButton = findViewById(R.id.send_message_button);
EditText messageBody = findViewById(R.id.message_body);
// Register the method for sending messages and toggle the visibility of chat components
sendMessageButton.setOnClickListener(l -> sendMessage());
sendMessageButton.setVisibility(View.VISIBLE);
messageBody.setVisibility(View.VISIBLE);
// Start the polling for chat messages immediately
handler.post(runnable);
}
Üzenetek küldésének engedélyezése
Adja hozzá a metódust a sendMessage()
következőhöz: MainActivity
. A használatával ChatThreadClient
üzeneteket küld a felhasználó nevében.
private void sendMessage() {
// Retrieve the typed message content
EditText messageBody = findViewById(R.id.message_body);
// Set request options and send message
SendChatMessageOptions options = new SendChatMessageOptions();
options.setContent(messageBody.getText().toString());
options.setSenderDisplayName("Test User");
chatThreadAsyncClient.sendMessage(options);
// Clear the text box
messageBody.setText("");
}
Üzenetek lekérdezésének engedélyezése és megjelenítése az alkalmazásban
Fontos
Ismert probléma: Mivel a Csevegő SDK valós idejű értesítési funkciója nem működik együtt a hívó SDK-kkal, előre meghatározott időközönként le kell kérdeznünk az GetMessages
API-t. A mintánkban 3 másodperces időközöket használunk.
Az API által GetMessages
visszaadott üzenetlistából a következő adatokat szerezhetjük be:
- A
text
éshtml
az üzenetek a szálon a csatlakozás óta - A szálnévsor módosítása
- Frissítések a tématémakörhöz
MainActivity
Az osztályhoz adjon hozzá egy kezelőt és egy futtatható feladatot, amely 3 másodperces időközönként lesz futtatva:
private Handler handler = new Handler();
private Runnable runnable = new Runnable() {
@Override
public void run() {
try {
retrieveMessages();
} catch (InterruptedException e) {
e.printStackTrace();
}
// Repeat every 3 seconds
handler.postDelayed(runnable, 3000);
}
};
Vegye figyelembe, hogy a feladat már el lett indítva az MainActivity.joinTeamsMeeting()
inicializálási lépésben frissített metódus végén.
Végül hozzáadjuk a metódust a szál összes akadálymentes üzenetének lekérdezéséhez, az üzenettípus alapján történő elemzéshez és a és text
az html
üzenet megjelenítéséhez:
private void retrieveMessages() throws InterruptedException {
// Initialize the list of messages not yet processed
ArrayList<ChatMessage> newChatMessages = new ArrayList<>();
// Retrieve all messages accessible to the user
PagedAsyncStream<ChatMessage> messagePagedAsyncStream
= this.chatThreadAsyncClient.listMessages(new ListChatMessagesOptions(), null);
// Set up a lock to wait until all returned messages have been inspected
CountDownLatch latch = new CountDownLatch(1);
// Traverse the returned messages
messagePagedAsyncStream.forEach(new AsyncStreamHandler<ChatMessage>() {
@Override
public void onNext(ChatMessage message) {
// Messages that should be displayed in the chat
if ((message.getType().equals(ChatMessageType.TEXT)
|| message.getType().equals(ChatMessageType.HTML))
&& !chatMessages.contains(message.getId())) {
newChatMessages.add(message);
chatMessages.add(message.getId());
}
if (message.getType().equals(ChatMessageType.PARTICIPANT_ADDED)) {
// Handle participants added to chat operation
List<ChatParticipant> participantsAdded = message.getContent().getParticipants();
CommunicationIdentifier participantsAddedBy = message.getContent().getInitiatorCommunicationIdentifier();
}
if (message.getType().equals(ChatMessageType.PARTICIPANT_REMOVED)) {
// Handle participants removed from chat operation
List<ChatParticipant> participantsRemoved = message.getContent().getParticipants();
CommunicationIdentifier participantsRemovedBy = message.getContent().getInitiatorCommunicationIdentifier();
}
if (message.getType().equals(ChatMessageType.TOPIC_UPDATED)) {
// Handle topic updated
String newTopic = message.getContent().getTopic();
CommunicationIdentifier topicUpdatedBy = message.getContent().getInitiatorCommunicationIdentifier();
}
}
@Override
public void onError(Throwable throwable) {
latch.countDown();
}
@Override
public void onComplete() {
latch.countDown();
}
});
// Wait until the operation completes
latch.await(1, TimeUnit.MINUTES);
// Returned messages should be ordered by the createdOn field to be guaranteed a proper chronological order
// For the purpose of this demo we will just reverse the list of returned messages
Collections.reverse(newChatMessages);
for (ChatMessage chatMessage : newChatMessages)
{
LinearLayout chatBoxLayout = findViewById(R.id.chat_box_layout);
// For the purpose of this demo UI, we don't need to use HTML formatting for displaying messages
// The Teams client always sends html messages in meeting chats
String message = Html.fromHtml(chatMessage.getContent().getMessage(), Html.FROM_HTML_MODE_LEGACY).toString().trim();
TextView messageView = new TextView(this);
messageView.setText(message);
// Compare with sender identifier and align LEFT/RIGHT accordingly
// Azure Communication Services users are of type CommunicationUserIdentifier
CommunicationIdentifier senderId = chatMessage.getSenderCommunicationIdentifier();
if (senderId instanceof CommunicationUserIdentifier
&& InitiatorId.equals(((CommunicationUserIdentifier) senderId).getId())) {
messageView.setTextColor(Color.GREEN);
messageView.setGravity(Gravity.RIGHT);
} else {
messageView.setTextColor(Color.BLUE);
messageView.setGravity(Gravity.LEFT);
}
// Note: messages with the deletedOn property set to a timestamp, should be marked as deleted
// Note: messages with the editedOn property set to a timestamp, should be marked as edited
messageView.setTypeface(Typeface.SANS_SERIF, Typeface.BOLD);
chatBoxLayout.addView(messageView);
}
}
A csevegőszál résztvevőinek megjelenített neveit a Teams-ügyfél nem állítja be. A rendszer null értékként adja vissza a neveket az API-ban a résztvevők listázásakor, az participantsAdded
eseményben és az participantsRemoved
eseményben. A csevegés résztvevőinek megjelenített nevei lekérhetők az remoteParticipants
call
objektum mezőjéből.
Teams-értekezlet csevegési szálának lekérése Egy Communication Services-felhasználó számára
A Teams-értekezlet részletei a Graph API-kkal kérhetők le, amelyek a Graph dokumentációjában találhatók. A Communication Services Calling SDK elfogad egy teljes Teams-értekezlethivatkozást vagy egy értekezlet-azonosítót. A rendszer az erőforrás részeként adja vissza őket, amely a onlineMeeting
joinWebUrl
tulajdonság alatt érhető el
A Graph API-kkal a következőt is beszerezheti threadID
: . A válasz egy chatInfo
objektummal rendelkezik, amely a következőt threadID
tartalmazza: .
A szükséges értekezletadatokat és a szálazonosítót a Teams-értekezlet-összehívás Bekapcsolódás értekezlet url-címéből is lekérheti.
A Teams-értekezletek hivatkozása a következőképpen néz ki: https://teams.microsoft.com/l/meetup-join/meeting_chat_thread_id/1606337455313?context=some_context_here
. meeting_chat_thread_id
Itt threadId
található a hivatkozás. Használat előtt győződjön meg arról, hogy a meeting_chat_thread_id
nincs beágyazva. A formátumnak a következőnek kell lennie: 19:meeting_ZWRhZDY4ZGUtYmRlNS00OWZaLTlkZTgtZWRiYjIxOWI2NTQ4@thread.v2
A kód futtatása
Az alkalmazás most már elindítható az eszköztár "Alkalmazás futtatása" gombjával (Shift+F10).
Ha csatlakozni szeretne a Teams-értekezlethez és a csevegéshez, adja meg a csapat értekezlet-hivatkozását és a szálazonosítót a felhasználói felületen.
Miután csatlakozott a csapat értekezletéhez, be kell fogadnia a felhasználót az értekezletbe a csapat ügyfélprogramjában. Miután a felhasználót beengedték, és csatlakozott a csevegéshez, küldhet és fogadhat üzeneteket.
Megjegyzés
Bizonyos funkciók jelenleg nem támogatottak a Teamsszel való együttműködési forgatókönyvekben. További információ a támogatott funkciókról: Teams-értekezletek képességei a Teams külső felhasználói számára
Ebből a rövid útmutatóból megtudhatja, hogyan cseveghet Teams-értekezleteken a C# Azure Communication Services Chat SDK használatával.
Mintakód
Keresse meg a rövid útmutató kódját a GitHubon.
Előfeltételek
- Teams-telepítés.
- Egy Azure-fiók, aktív előfizetéssel. Hozzon létre ingyenes fiókot.
- Telepítse a Visual Studio 2019-et Univerzális Windows-platform fejlesztési számítási feladattal.
- Üzembe helyezett Communication Services-erőforrás. Hozzon létre egy Communication Services-erőforrást.
- Egy Teams-értekezlet hivatkozása.
Csatlakozás az értekezlet csevegéséhez
A Communication Services-felhasználók névtelen felhasználóként csatlakozhatnak a Teams-értekezletekhez a Hívó SDK használatával. Ha csatlakozik az értekezlethez, résztvevőként is hozzáadja őket az értekezlet csevegéséhez, ahol üzeneteket küldhetnek és fogadhatnak az értekezlet többi felhasználójával. A felhasználónak nem lesz hozzáférése az értekezlethez való csatlakozás előtt elküldött csevegőüzenetekhez, és nem tud üzeneteket küldeni vagy fogadni az értekezlet befejezése után. Az értekezlethez való csatlakozáshoz és a csevegés megkezdéséhez kövesse a következő lépéseket.
A kód futtatása
A kódot a Visual Studióban hozhatja létre és futtathatja. Jegyezze fel a és a megoldásplatformokat.x64
x86
ARM64
- Nyisson meg egy PowerShell-példányt, Windows terminál, parancssort vagy azzal egyenértékűt, és keresse meg azt a könyvtárat, amelybe klónozni szeretné a mintát.
git clone https://github.com/Azure-Samples/Communication-Services-dotnet-quickstarts.git
- Nyissa meg a ChatTeamsInteropQuickStart/ChatTeamsInteropQuickStart.csproj projektet a Visual Studióban.
- Telepítse a következő NuGet-csomagok (vagy újabb) verzióit:
Install-Package Azure.Communication.Calling -Version 1.0.0-beta.29
Install-Package Azure.Communication.Chat -Version 1.1.0
Install-Package Azure.Communication.Common -Version 1.0.1
Install-Package Azure.Communication.Identity -Version 1.0.1
- Ha a Communication Services-erőforrás előfeltételként van beszerzve, adja hozzá a connectionstring elemet a ChatTeamsInteropQuickStart/MainPage.xaml.cs fájlhoz.
//Azure Communication Services resource connection string i.e = "endpoint=https://your-resource.communication.azure.net/;accesskey=your-access-key";
private const string connectionString_ = "";
Fontos
- A kód futtatása előtt válassza ki a megfelelő platformot a Visual Studio Megoldásplatformok legördülő listájából. Azaz
x64
- Győződjön meg arról, hogy a "Fejlesztői mód" engedélyezve van Windows 10 (Fejlesztői beállítások)
A következő lépések nem fognak működni, ha ez nincs megfelelően konfigurálva
- Nyomja le az F5 billentyűt a projekt hibakeresési módban való elindításához.
- Illessze be a Teams-értekezlet érvényes hivatkozását a "Teams-értekezlet hivatkozása" mezőbe (lásd a következő szakaszt)
- A csevegés megkezdéséhez nyomja le a "Csatlakozás Teams-értekezlethez" gombot.
Fontos
Miután a hívó SDK kapcsolatot létesített a teams-értekezlettel Lásd: A Kommunikációs szolgáltatások meghívják a Windows alkalmazást, a csevegési műveletek kezeléséhez szükséges fő funkciók a következők: StartPollingForChatMessages és SendMessageButton_Click. Mindkét kódrészlet a ChatTeamsInteropQuickStart\MainPage.xaml.cs fájlban található.
/// <summary>
/// Background task that keeps polling for chat messages while the call connection is stablished
/// </summary>
private async Task StartPollingForChatMessages()
{
CommunicationTokenCredential communicationTokenCredential = new(user_token_);
chatClient_ = new ChatClient(EndPointFromConnectionString(), communicationTokenCredential);
await Task.Run(async () =>
{
keepPolling_ = true;
ChatThreadClient chatThreadClient = chatClient_.GetChatThreadClient(thread_Id_);
int previousTextMessages = 0;
while (keepPolling_)
{
try
{
CommunicationUserIdentifier currentUser = new(user_Id_);
AsyncPageable<ChatMessage> allMessages = chatThreadClient.GetMessagesAsync();
SortedDictionary<long, string> messageList = new();
int textMessages = 0;
string userPrefix;
await foreach (ChatMessage message in allMessages)
{
if (message.Type == ChatMessageType.Html || message.Type == ChatMessageType.Text)
{
textMessages++;
userPrefix = message.Sender.Equals(currentUser) ? "[you]:" : "";
messageList.Add(long.Parse(message.SequenceId), $"{userPrefix}{StripHtml(message.Content.Message)}");
}
}
//Update UI just when there are new messages
if (textMessages > previousTextMessages)
{
previousTextMessages = textMessages;
await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
TxtChat.Text = string.Join(Environment.NewLine, messageList.Values.ToList());
});
}
if (!keepPolling_)
{
return;
}
await SetInCallState(true);
await Task.Delay(3000);
}
catch (Exception e)
{
await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
_ = new MessageDialog($"An error ocurred while fetching messages in PollingChatMessagesAsync(). The application will shutdown. Details : {e.Message}").ShowAsync();
throw e;
});
await SetInCallState(false);
}
}
});
}
private async void SendMessageButton_Click(object sender, RoutedEventArgs e)
{
SendMessageButton.IsEnabled = false;
ChatThreadClient chatThreadClient = chatClient_.GetChatThreadClient(thread_Id_);
_ = await chatThreadClient.SendMessageAsync(TxtMessage.Text);
TxtMessage.Text = "";
SendMessageButton.IsEnabled = true;
}
Teams-értekezlet hivatkozásának lekérése
A Teams-értekezlet hivatkozása a Graph API-kkal kérhető le, amely a Graph dokumentációjában található. Ez a hivatkozás az erőforrás részeként jelenik meg, amely a onlineMeeting
joinWebUrl
tulajdonság alatt érhető el.
A szükséges értekezlethivatkozást a Teams-értekezlet-összehívás bekapcsolódás url-címéről is beszerezheti.
A Teams-értekezlet hivatkozása így néz ki: https://teams.microsoft.com/l/meetup-join/meeting_chat_thread_id/1606337455313?context=some_context_here
.
Megjegyzés
Bizonyos funkciók jelenleg nem támogatottak a Teamsszel való együttműködési forgatókönyvekben. További információ a támogatott funkciókról: Teams-értekezletek képességei a Teams külső felhasználói számára
Az erőforrások eltávolítása
Ha törölni és eltávolítani szeretne egy Communication Services-előfizetést, törölheti az erőforrást vagy az erőforráscsoportot. Az erőforráscsoport törlése a hozzá társított egyéb erőforrásokat is törli. További információ az erőforrások eltávolításáról.
Következő lépések
További információért tekintse át a következő cikkeket:
- Tekintse meg a csevegés fő képét
- További információ a csevegés működéséről