Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Steigen Sie in die Nutzung von Azure Communication Services ein, indem Sie Ihre Chatlösung mit Microsoft Teams verbinden.
In diesem Artikel wird beschrieben, wie Sie in einer Teams-Besprechung mit dem Azure Communication Services Chat SDK für JavaScript chatten.
Beispielcode
Laden Sie diesen Code bei den Azure-Beispielen auf GitHub herunter und verbinden Sie Ihre Chat-App mit einer Teams-Besprechung.
Voraussetzungen
- Eine Teams-Bereitstellung
- Eine funktionierende Chat-App.
Beitritt zum Besprechungs-Chat
Ein Kommunikationsdienste-Benutzer kann über das Calling SDK an einer Teams-Besprechung als anonymer Benutzer teilnehmen. Wenn Sie an der Besprechung teilnehmen, werden sie auch als Teilnehmer zum Besprechungschat hinzugefügt, in dem sie Nachrichten mit anderen Benutzern in der Besprechung senden und empfangen können. Der Benutzer hat keinen Zugriff auf Chatnachrichten, die gesendet wurden, bevor er an der Besprechung teilnimmt, und er kann keine Nachrichten senden oder empfangen, nachdem die Besprechung beendet wurde. Führen Sie die folgenden Schritte aus, um an der Besprechung teilzunehmen und mit dem Chatten zu beginnen.
Erstellen einer neuen Node.js-Anwendung
Öffnen Sie Ihr Terminal- oder Befehlsfenster, erstellen Sie ein neues Verzeichnis für Ihre App, und navigieren Sie zu diesem Verzeichnis.
mkdir chat-interop-quickstart && cd chat-interop-quickstart
Führen Sie npm init -y
aus, um die Datei package.json mit den Standardeinstellungen zu erstellen.
npm init -y
Installieren der Chatpakete
Verwenden Sie den Befehl npm install
, um die notwendigen Communication Services-SDKs für JavaScript zu installieren.
npm install @azure/communication-common --save
npm install @azure/communication-identity --save
npm install @azure/communication-chat --save
npm install @azure/communication-calling --save
Mit der Option --save
wird die Bibliothek als Abhängigkeit in Ihrer Datei package.json aufgelistet.
Einrichten des App-Frameworks
In diesem Beispiel wird webpack verwendet, um die Anwendungsressourcen zu bündeln. Führen Sie den folgenden Befehl aus, um webpack-, webpack-cli- und webpack-dev-server npm-Pakete zu installieren und diese als Entwicklungsabhängigkeiten in Ihrem package.jsonaufzulisten:
npm install webpack@5.89.0 webpack-cli@5.1.4 webpack-dev-server@4.15.1 --save-dev
Erstellen Sie im Stammverzeichnis Ihres Projekts die Datei index.html. Wir verwenden diese Datei, um ein einfaches Layout zu konfigurieren, das es dem Benutzer ermöglicht, an einer Besprechung teilzunehmen und mit dem Chatten zu beginnen.
Hinzufügen der Steuerelemente der Teams-Benutzeroberfläche
Ersetzen Sie den Code in „index.html“ durch den folgenden Codeausschnitt.
Verwenden Sie das Textfeld oben auf der Seite, um den Teams-Besprechungskontext einzugeben. Endbenutzer können an der angegebenen Besprechung teilnehmen, indem Sie auf die Schaltfläche " An Teams-Besprechung teilnehmen" klicken.
Unten auf der Seite wird ein Chatpopup angezeigt. Endbenutzer können sie verwenden, um Nachrichten im Besprechungsthread zu senden. Er zeigt in Echtzeit alle Nachrichten an, die im Thread gesendet werden, während der Benutzer der Kommunikationsdienste Mitglied ist.
<!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: 400px;" />
<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>
Aktivieren der Steuerelemente der Teams-Benutzeroberfläche
Ersetzen Sie den Inhalt der Datei „client.js“ durch den folgenden Codeausschnitt.
Ersetzen Sie in diesem Codeausschnitt
SECRET_CONNECTION_STRING
durch die Verbindungszeichenfolge für Ihre Communication Services-Instanz
import { CallClient } 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 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 messages = "";
var chatThreadId = "";
async function init() {
const connectionString = "<SECRET_CONNECTION_STRING>";
const endpointUrl = connectionString.split(";")[0].replace("endpoint=", "");
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();
const joinCall = (urlString, callAgent) => {
const url = new URL(urlString);
console.log(url);
if (url.pathname.startsWith("/meet")) {
// Short teams URL, so for now call meetingID and pass code API
return callAgent.join({
meetingId: url.pathname.split("/").pop(),
passcode: url.searchParams.get("p"),
});
} else {
return callAgent.join({ meetingLink: urlString }, {});
}
};
callButton.addEventListener("click", async () => {
// join with meeting link
try {
call = joinCall(meetingLinkInput.value, callAgent);
} catch {
throw new Error("Could not join meeting - have you set your connection string?");
}
// Chat thread ID is provided from the call info, after connection.
call.on("stateChanged", async () => {
callStateElement.innerText = call.state;
if (call.state === "Connected" && !chatThreadClient) {
chatThreadId = call.info?.threadId;
chatThreadClient = chatClient.getChatThreadClient(chatThreadId);
chatBox.style.display = "block";
messagesContainer.innerHTML = messages;
// 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 (chatThreadId != e.threadId) {
return;
}
if (e.sender.communicationUserId != userId) {
renderReceivedMessage(e.message);
} else {
renderSentMessage(e.message);
}
});
}
});
// toggle button and chat box states
hangUpButton.disabled = false;
callButton.disabled = true;
console.log(call);
});
async function renderReceivedMessage(message) {
messages += '<div class="container lighter">' + message + "</div>";
messagesContainer.innerHTML = messages;
}
async function renderSentMessage(message) {
messages += '<div class="container darker">' + message + "</div>";
messagesContainer.innerHTML = messages;
}
hangUpButton.addEventListener("click", async () => {
// end the current call
await call.hangUp();
// Stop notifications
chatClient.stopRealtimeNotifications();
// toggle button states
hangUpButton.disabled = true;
callButton.disabled = false;
callStateElement.innerText = "-";
// toggle chat states
chatBox.style.display = "none";
messages = "";
// Remove local ref
chatThreadClient = undefined;
});
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}`);
});
Der Teams-Client legt die Anzeigenamen der Chatthreadteilnehmer nicht fest. Beim Ereignis participantsAdded
und participantsRemoved
werden die Namen in der API für die Auflistung von Teilnehmer*innen als NULL zurückgegeben. Die Anzeigenamen der Chatteilnehmer können aus dem remoteParticipants
-Feld des call
-Objekts abgerufen werden. Wenn Sie eine Benachrichtigung über eine Listenänderung erhalten, können Sie den folgenden Code verwenden, um den Namen des Benutzers abzurufen, der hinzugefügt oder entfernt wurde:
var displayName = call.remoteParticipants.find(p => p.identifier.communicationUserId == '<REMOTE_USER_ID>').displayName;
Ausführen des Codes
Verwenden Sie webpack-dev-server
, um Ihre App zu erstellen und auszuführen. Führen Sie den folgenden Befehl aus, um Ihren Anwendungshost auf einem lokalen Webserver zu bündeln:
npx webpack-dev-server --entry ./client.js --output bundle.js --debug --devtool inline-source-map
Öffnen Sie Ihren Browser und gehen Sie zu http://localhost:8080/
. Die App sollte nun gestartet werden, wie im folgenden Screenshot gezeigt:
Fügen Sie den Teams-Besprechungslink in das Textfeld ein. Benutzer können auf " An Teams-Besprechung teilnehmen " klicken, um an der Teams-Besprechung teilzunehmen. Nachdem der Benutzer der Kommunikationsdienste in die Besprechung zugelassen wurde, können Sie innerhalb Ihrer Kommunikationsdienste-Anwendung chatten. Navigieren Sie zu dem Feld unten auf der Seite, um mit dem Chatten zu beginnen. Der Einfachheit halber zeigt die Anwendung nur die letzten beiden Nachrichten im Chat an.
Hinweis
Bestimmte Funktionen werden derzeit für Szenarien zur Interoperabilität mit Teams nicht unterstützt. Weitere Informationen zu unterstützten Features finden Sie unter Teams-Besprechungsfunktionen für externe Teams-Benutzer.
In diesem Artikel wird beschrieben, wie Sie in einer Teams-Besprechung mit dem Azure Communication Services Chat SDK für iOS chatten.
Beispielcode
Laden Sie diesen Code unter GitHub Azure Samples herunter, um Ihre Chat-App mit einer Teams-Besprechung zu verbinden.
Voraussetzungen
- Ein Azure-Konto mit einem aktiven Abonnement. Kostenlos ein Konto erstellen
- Einen Mac mit Xcode zusammen mit einem gültigen in Ihrer Keychain installierten Entwicklerzertifikat.
- Eine Teams-Bereitstellung
- Ein Benutzerzugriffstoken für Ihren Azure Communication Service Sie können auch die Azure CLI verwenden und den Befehl mit Ihrer Verbindungszeichenfolge ausführen, um einen Benutzer und ein Zugriffs-Token zu erstellen.
az communication user-identity token issue --scope voip chat --connection-string "yourConnectionString"
Ausführliche Informationen finden Sie unter Verwenden der Azure CLI zum Erstellen und Verwalten von Zugriffstoken.
Einrichten
Erstellen des Xcode-Projekts
Erstellen Sie in Xcode ein neues iOS-Projekt, und wählen Sie die Vorlage Single View App (Einzelansicht-App) aus. In diesem Tutorial wird das SwiftUI-Framework verwendet – legen Sie daher „Sprache“ auf „Swift“ und „Benutzeroberfläche“ auf „SwiftUI“ fest. Im Rahmen dieses Schnellstarts werden keine Tests erstellt. Sie können gerne die Option Tests einschließen deaktivieren.
Installieren von CocoaPods
Verwenden Sie diese Anleitung, um CocoaPods auf Ihrem Mac zu installieren.
Installieren des Pakets und der Abhängigkeiten mit CocoaPods
Zum Erstellen einer
Podfile
-Datei für Ihre Anwendung öffnen Sie das Terminal, navigieren Sie zum Projektordner, und führen Sie „pod init“ aus.Fügen Sie
Podfile
unter dem Ziel den folgenden Code hinzu, und speichern Sie.
target 'Chat Teams Interop' do
# Comment the next line if you don't want to use dynamic frameworks
use_frameworks!
# Pods for Chat Teams Interop
pod 'AzureCommunicationCalling'
pod 'AzureCommunicationChat'
end
Führen Sie
pod install
aus.Öffnen Sie die
.xcworkspace
-Datei mit Xcode.
Anfordern des Zugriffs auf das Mikrofon
Um auf das Mikrofon des Geräts zugreifen zu können, müssen Sie die Liste der Informationseigenschaften Ihrer App mit einer NSMicrophoneUsageDescription
aktualisieren. Legen Sie den zugehörigen Wert auf eine Zeichenfolge (string
) fest, die in den Dialog aufgenommen wurde, mit dem das System den Zugriff beim Benutzer anfordert.
Wählen Sie im Zielbereich die Registerkarte Info
aus, und fügen Sie eine Zeichenkette für Privacy - Microphone Usage Description
hinzu.
Deaktivieren der Verwendung einer Benutzerskript-Sandbox
Einige der Skripte in den verknüpften Bibliotheken schreiben Dateien während des Buildprozesses. Um das Schreiben von Dateien zu ermöglichen, deaktivieren Sie die Benutzerskript-Sandbox in Xcode.
Suchen Sie unter den Buildeinstellungen nach sandbox
, und legen Sie User Script Sandboxing
auf No
fest.
Beitritt zum Besprechungschat
Ein Communication Services-Benutzer kann mithilfe des Calling SDK einer Teams-Besprechung als anonymer Benutzer beitreten. Sobald ein Benutzer an der Teams-Besprechung teilnimmt, kann er Nachrichten mit anderen Besprechungsteilnehmern senden und empfangen. Der Benutzer hat keinen Zugriff auf Chatnachrichten, die vor der Teilnahme gesendet wurden, und kann auch keine Nachrichten senden oder empfangen, wenn er sich nicht in der Besprechung befindet.
Führen Sie die nächsten Schritte aus, um an der Besprechung teilzunehmen und mit dem Chatten zu beginnen.
Einrichten des App-Frameworks
Importieren Sie die Azure Communication-Pakete in ContentView.swift
, indem Sie den folgenden Codeschnipsel hinzufügen:
import AVFoundation
import SwiftUI
import AzureCommunicationCalling
import AzureCommunicationChat
Fügen Sie in ContentView.swift
den folgenden Codeschnipsel direkt oberhalb der struct ContentView: View
-Deklaration hinzu:
let endpoint = "<ADD_YOUR_ENDPOINT_URL_HERE>"
let token = "<ADD_YOUR_USER_TOKEN_HERE>"
let displayName: String = "Quickstart User"
Ersetzen Sie <ADD_YOUR_ENDPOINT_URL_HERE>
durch den Endpunkt Ihrer Communication Services-Ressource.
Ersetzen Sie <ADD_YOUR_USER_TOKEN_HERE>
mit dem zuvor generierten Token mithilfe der Azure-Client-Befehlszeile.
Weitere Informationen finden Sie unter Benutzerzugriffstoken
Ersetzen Sie Quickstart User
durch den gewünschten Anzeigenamen im Chat.
Um den Zustand zu speichern, fügen Sie der ContentView
-Struktur die folgenden Variablen hinzu:
@State var message: String = ""
@State var meetingLink: String = ""
@State var chatThreadId: String = ""
// Calling state
@State var callClient: CallClient?
@State var callObserver: CallDelegate?
@State var callAgent: CallAgent?
@State var call: Call?
// Chat state
@State var chatClient: ChatClient?
@State var chatThreadClient: ChatThreadClient?
@State var chatMessage: String = ""
@State var meetingMessages: [MeetingMessage] = []
Fügen Sie nun die Variable des Haupttexts hinzu, um die UI-Elemente zu speichern. Wir fügen Geschäftslogik diesen Steuerelementen zu. Fügen Sie der ContentView
-Struktur den folgenden Code hinzu:
var body: some View {
NavigationView {
Form {
Section {
TextField("Teams Meeting URL", text: $meetingLink)
.onChange(of: self.meetingLink, perform: { value in
if let threadIdFromMeetingLink = getThreadId(from: value) {
self.chatThreadId = threadIdFromMeetingLink
}
})
TextField("Chat thread ID", text: $chatThreadId)
}
Section {
HStack {
Button(action: joinMeeting) {
Text("Join Meeting")
}.disabled(
chatThreadId.isEmpty || callAgent == nil || call != nil
)
Spacer()
Button(action: leaveMeeting) {
Text("Leave Meeting")
}.disabled(call == nil)
}
Text(message)
}
Section {
ForEach(meetingMessages, id: \.id) { message in
let currentUser: Bool = (message.displayName == displayName)
let foregroundColor = currentUser ? Color.white : Color.black
let background = currentUser ? Color.blue : Color(.systemGray6)
let alignment = currentUser ? HorizontalAlignment.trailing : .leading
HStack {
if currentUser {
Spacer()
}
VStack(alignment: alignment) {
Text(message.displayName).font(Font.system(size: 10))
Text(message.content)
.frame(maxWidth: 200)
}
.padding(8)
.foregroundColor(foregroundColor)
.background(background)
.cornerRadius(8)
if !currentUser {
Spacer()
}
}
}
.frame(maxWidth: .infinity)
}
TextField("Enter your message...", text: $chatMessage)
Button(action: sendMessage) {
Text("Send Message")
}.disabled(chatThreadClient == nil)
}
.navigationBarTitle("Teams Chat Interop")
}
.onAppear {
// Handle initialization of the call and chat clients
}
}
Initialisieren von ChatClient
Instanziieren Sie ChatClient
, und aktivieren Sie Nachrichtenbenachrichtigungen. Wir verwenden Echtzeitbenachrichtigungen für den Empfang von Chatnachrichten.
Nachdem der Hauptteil eingerichtet wurde, fügen wir die Funktionen zur Einrichtung der Anruf- und Chat-Clients hinzu.
Fügen Sie in der onAppear
-Funktion den folgenden Code hinzu, um CallClient
und ChatClient
zu initialisieren:
if let threadIdFromMeetingLink = getThreadId(from: self.meetingLink) {
self.chatThreadId = threadIdFromMeetingLink
}
// Authenticate
do {
let credentials = try CommunicationTokenCredential(token: token)
self.callClient = CallClient()
self.callClient?.createCallAgent(
userCredential: credentials
) { agent, error in
if let e = error {
self.message = "ERROR: It was not possible to create a call agent."
print(e)
return
} else {
self.callAgent = agent
}
}
// Start the chat client
self.chatClient = try ChatClient(
endpoint: endpoint,
credential: credentials,
withOptions: AzureCommunicationChatClientOptions()
)
// Register for real-time notifications
self.chatClient?.startRealTimeNotifications { result in
switch result {
case .success:
self.chatClient?.register(
event: .chatMessageReceived,
handler: receiveMessage
)
case let .failure(error):
self.message = "Could not register for message notifications: " + error.localizedDescription
print(error)
}
}
} catch {
print(error)
self.message = error.localizedDescription
}
Funktion für Beitritt zur Besprechung hinzufügen
Fügen Sie der ContentView
-Struktur die folgende Funktion hinzu, um den Beitritt zur Besprechung zu bearbeiten.
func joinMeeting() {
// Ask permissions
AVAudioSession.sharedInstance().requestRecordPermission { (granted) in
if granted {
let teamsMeetingLink = TeamsMeetingLinkLocator(
meetingLink: self.meetingLink
)
self.callAgent?.join(
with: teamsMeetingLink,
joinCallOptions: JoinCallOptions()
) {(call, error) in
if let e = error {
self.message = "Failed to join call: " + e.localizedDescription
print(e.localizedDescription)
return
}
self.call = call
self.callObserver = CallObserver(self)
self.call?.delegate = self.callObserver
self.message = "Teams meeting joined successfully"
}
} else {
self.message = "Not authorized to use mic"
}
}
}
Initialisieren von ChatThreadClient
Wir initialisieren ChatThreadClient
nachdem der Benutzer an der Besprechung teilnimmt. Danach sollten wir den Besprechungsstatus des Delegierten überprüfen und dann ChatThreadClient
mit threadId
initialisieren, wenn wir der Besprechung beitreten.
Erstellen Sie die connectChat()
-Funktion mit dem folgenden Code:
func connectChat() {
do {
self.chatThreadClient = try chatClient?.createClient(
forThread: self.chatThreadId
)
self.message = "Joined meeting chat successfully"
} catch {
self.message = "Failed to join the chat thread: " + error.localizedDescription
}
}
Fügen Sie nach Möglichkeit ContentView
die folgende Hilfsfunktion hinzu, die zum Analysieren der Thread-ID des Chats aus dem Besprechungslink des Teams dient. Falls diese Extraktion fehlschlägt, muss der Benutzer die Chatthread-ID manuell mithilfe von Graph-APIs eingeben, um die Thread-ID abzurufen.
func getThreadId(from teamsMeetingLink: String) -> String? {
if let range = teamsMeetingLink.range(of: "meetup-join/") {
let thread = teamsMeetingLink[range.upperBound...]
if let endRange = thread.range(of: "/")?.lowerBound {
return String(thread.prefix(upTo: endRange))
}
}
return nil
}
Aktivieren des Sendens von Nachrichten
Fügen Sie die Funktion sendMessage()
zu ContentView
hinzu. Diese Funktion verwendet ChatThreadClient
, um Nachrichten der Benutzer*innen zu senden.
func sendMessage() {
let message = SendChatMessageRequest(
content: self.chatMessage,
senderDisplayName: displayName,
type: .text
)
self.chatThreadClient?.send(message: message) { result, _ in
switch result {
case .success:
print("Chat message sent")
self.chatMessage = ""
case let .failure(error):
self.message = "Failed to send message: " + error.localizedDescription + "\n Has your token expired?"
}
}
}
Aktivieren des Empfangens von Nachrichten
Um Nachrichten zu empfangen, implementieren wir den Handler für ChatMessageReceived
-Ereignisse. Wenn neue Nachrichten an den Thread gesendet werden, fügt dieser Handler die Nachrichten der Variablen meetingMessages
hinzu, damit sie auf der Benutzeroberfläche angezeigt werden können.
Fügen Sie zuerst die folgende Struktur zu ContentView.swift
hinzu. Die Benutzeroberfläche verwendet die Daten in der Struktur, um unsere Chatnachrichten anzuzeigen.
struct MeetingMessage: Identifiable {
let id: String
let date: Date
let content: String
let displayName: String
static func fromTrouter(event: ChatMessageReceivedEvent) -> MeetingMessage {
let displayName: String = event.senderDisplayName ?? "Unknown User"
let content: String = event.message.replacingOccurrences(
of: "<[^>]+>", with: "",
options: String.CompareOptions.regularExpression
)
return MeetingMessage(
id: event.id,
date: event.createdOn?.value ?? Date(),
content: content,
displayName: displayName
)
}
}
Fügen Sie als Nächstes die Funktion receiveMessage()
zu ContentView
hinzu. Wenn ein Messagingereignis auftritt, wird diese Funktion aufgerufen. Sie müssen alle Ereignisse anmelden, die Sie in der switch
Anweisung über die chatClient?.register()
Methode behandeln möchten.
func receiveMessage(event: TrouterEvent) -> Void {
switch event {
case let .chatMessageReceivedEvent(messageEvent):
let message = MeetingMessage.fromTrouter(event: messageEvent)
self.meetingMessages.append(message)
/// OTHER EVENTS
// case .realTimeNotificationConnected:
// case .realTimeNotificationDisconnected:
// case .typingIndicatorReceived(_):
// case .readReceiptReceived(_):
// case .chatMessageEdited(_):
// case .chatMessageDeleted(_):
// case .chatThreadCreated(_):
// case .chatThreadPropertiesUpdated(_):
// case .chatThreadDeleted(_):
// case .participantsAdded(_):
// case .participantsRemoved(_):
default:
break
}
}
Schließlich müssen wir den Delegatenhandler für den Anrufclient implementieren. Verwenden Sie diesen Handler, um den Anrufstatus zu überprüfen und den Chatclient zu initialisieren, wenn der Benutzer an der Besprechung teilnimmt.
class CallObserver : NSObject, CallDelegate {
private var owner: ContentView
init(_ view: ContentView) {
owner = view
}
func call(
_ call: Call,
didChangeState args: PropertyChangedEventArgs
) {
owner.message = CallObserver.callStateToString(state: call.state)
if call.state == .disconnected {
owner.call = nil
owner.message = "Left Meeting"
} else if call.state == .inLobby {
owner.message = "Waiting in lobby (go let them in!)"
} else if call.state == .connected {
owner.message = "Connected"
owner.connectChat()
}
}
private static func callStateToString(state: CallState) -> String {
switch state {
case .connected: return "Connected"
case .connecting: return "Connecting"
case .disconnected: return "Disconnected"
case .disconnecting: return "Disconnecting"
case .earlyMedia: return "EarlyMedia"
case .none: return "None"
case .ringing: return "Ringing"
case .inLobby: return "InLobby"
default: return "Unknown"
}
}
}
Verlassen des Chats
Wenn der Benutzer die Teams-Besprechung verlässt, löschen wir die Chatnachrichten aus der Benutzeroberfläche und hängen den Anruf auf. Sehen Sie sich das folgende vollständige Codebeispiel an.
func leaveMeeting() {
if let call = self.call {
self.chatClient?.unregister(event: .chatMessageReceived)
self.chatClient?.stopRealTimeNotifications()
call.hangUp(options: nil) { (error) in
if let e = error {
self.message = "Leaving Teams meeting failed: " + e.localizedDescription
} else {
self.message = "Leaving Teams meeting was successful"
}
}
self.meetingMessages.removeAll()
} else {
self.message = "No active call to hangup"
}
}
Abrufen eines Teams-Besprechungschatthreads für einen Communication Services-Benutzer
Die Details für die Teams-Besprechung können über Graph-APIs abgerufen werden, wie in der Graph-Dokumentation ausführlich erläutert. Das Communication Services Calling SDK akzeptiert einen vollständigen Teams-Besprechungslink oder eine Besprechungs-ID. Beide werden als Teil der onlineMeeting
-Ressource zurückgegeben, auf die unter der joinWebUrl
-Eigenschaft zugegriffen werden kann.
Mit den Graph APIs können Sie auch das threadID
abrufen. Die Antwort umfasst ein chatInfo
-Objekt, das die threadID
enthält.
Ausführen des Codes
Führen Sie die Anwendung aus.
Um an der Teams-Besprechung teilzunehmen, geben Sie auf der Benutzeroberfläche den Besprechungslink Ihres Teams ein.
Nachdem Sie der Teams-Besprechung beigetreten sind, müssen Sie die Benutzer*innen in Ihrem Teams-Client zur Besprechung zulassen. Sobald der Benutzer zugelassen ist und dem Chat beitritt, kann er Nachrichten senden und empfangen.
Hinweis
Bestimmte Funktionen werden derzeit für Szenarien zur Interoperabilität mit Teams nicht unterstützt. Weitere Informationen zu unterstützten Features finden Sie unter Teams-Besprechungsfunktionen für externe Teams-Benutzer.
In diesem Artikel wird beschrieben, wie Sie Ihrer App mithilfe des Azure Communication Services Chat SDK für Android Teams-Besprechungschats hinzufügen.
Beispielcode
Laden Sie diesen Code bei GitHub Azure Samples herunter verbinden Sie Ihre Chat-App mit einem Teams-Meeting.
Voraussetzungen
- Eine Teams-Bereitstellung
- Eine funktionierende Anruf-App.
Aktivieren der Teams-Interoperabilität
Ein Benutzer der Kommunikationsdienste, der als Gastbenutzer an einer Teams-Besprechung teilnimmt, kann erst nach dem Beitritt zum Teams-Besprechungsanruf auf den Besprechungschat zugreifen. Weitere Informationen zum Hinzufügen eines Kommunikationsdienste-Benutzers zu einem Teams-Besprechungsanruf finden Sie unter Teams-Interoperabilität.
Sie müssen Mitglied der besitzenden Organisation beider Entitäten sein, um dieses Feature verwenden zu können.
Beitritt zum Besprechungs-Chat
Nachdem Sie die Interoperabilität von Teams aktiviert haben, kann ein Kommunikationsdienste-Benutzer den Teams-Anruf als externer Benutzer über das Anruf-SDK beitreten. Wenn Sie am Anruf teilnehmen, werden sie auch als Teilnehmer zum Besprechungschat hinzugefügt. Vom Chat aus können sie Nachrichten mit anderen Benutzern im Anruf senden und empfangen. Der Benutzer besitzt keinen Zugriff auf Chatnachrichten, die gesandt wurden, bevor er dem Anruf beigetreten ist. Führen Sie die folgenden Schritte aus, um Ihren Endbenutzern zu ermöglichen, an den Teams-Besprechungen teilzunehmen und mit dem Chatten zu beginnen.
Hinzufügen von Chat zur Anruf-App von Teams
Fügen Sie in Ihrer Modulebene build.gradle
die Abhängigkeit vom Chat-SDK hinzu.
Wichtig
Bekanntes Problem: Wenn Sie Android Chat und Calling SDK zusammen in derselben Anwendung verwenden, funktionieren die Echtzeitbenachrichtigungsfeatures des Chat-SDKs nicht. Sie verursachen ein Problem bei der Abhängigkeitsauflösung. Während wir an einer Lösung arbeiten, können Sie das Feature für Echtzeitbenachrichtigungen deaktivieren, indem Sie der Chat SDK-Abhängigkeit in der build.gradle
-Datei der App die folgenden Ausschlüsse hinzufügen:
implementation ("com.azure.android:azure-communication-chat:2.0.3") {
exclude group: 'com.microsoft', module: 'trouter-client-android'
}
Hinzufügen des Layouts der Teams-Benutzeroberfläche
Ersetzen Sie den Code in „activity_main.xml“ durch den folgenden Codeausschnitt. Dadurch werden Eingaben für die Thread-ID und für das Senden von Nachrichten, eine Schaltfläche zum Senden der eingegebenen Nachricht und ein einfaches Chatlayout hinzugefügt.
<?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>
Aktivieren der Steuerelemente der Teams-Benutzeroberfläche
Importieren von Paketen und Definieren von Zustandsvariablen
Fügen Sie dem Inhalt von MainActivity.java
die folgenden Importe hinzu:
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 java.util.List;
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;
Fügen Sie der Klasse MainActivity
die folgenden Variablen hinzu:
// 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 corresponding to messages which have already been processed
ArrayList<String> chatMessages = new ArrayList<>();
Ersetzen Sie <USER_ID>
durch die ID des Benutzers, der den Chat initiiert.
Ersetzen Sie <COMMUNICATION_SERVICES_RESOURCE_ENDPOINT>
durch den Endpunkt Ihrer Communication Services-Ressource.
Initialisieren von ChatThreadClient
Instanziieren Sie nach dem Beitritt zur Besprechung den ChatThreadClient
, und machen Sie die Chatkomponenten sichtbar.
Aktualisieren Sie das Ende der MainActivity.joinTeamsMeeting()
Methode mit dem folgenden Code:
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);
}
Aktivieren des Sendens von Nachrichten
Fügen Sie die sendMessage()
-Methode zu MainActivity
hinzu. Diese Funktion verwendet ChatThreadClient
, um Nachrichten im Namen der Benutzer*innen zu senden.
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("");
}
Aktivieren des Abrufs für Nachrichten und Rendern von Nachrichten in der Anwendung
Wichtig
Bekanntes Problem: Da das Feature für Echtzeitbenachrichtigungen des Chat-SDK nicht mit den aufrufenden SDKs funktioniert, müssen Sie die GetMessages
API in vordefinierten Intervallen abrufen. In diesem Beispiel verwenden wir 3-Sekunden-Intervalle.
Wir können die folgenden Daten aus der von der GetMessages
-API zurückgegebenen Nachrichtenliste abrufen:
- Die
text
- undhtml
-Nachrichten im Thread seit dem Beitritt - Änderungen an der Threadliste
- Aktualisierungen des Threadthemas
Fügen Sie der MainActivity
Klasse einen Handler und eine ausführungsfähige Aufgabe hinzu, die in 3-Sekunden-Intervallen ausgeführt wird:
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);
}
};
Die Aufgabe wurde bereits am Ende der MainActivity.joinTeamsMeeting()
-Methode gestartet, die im Initialisierungsschritt aktualisiert wurde.
Abschließend fügen wir die Methode hinzu, um alle zugänglichen Nachrichten im Thread abzufragen, sie anhand des Nachrichtentyps zu analysieren und die html
- und text
-Nachrichten anzuzeigen:
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 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);
}
}
Der Teams-Client legt die Anzeigenamen der Chatthreadteilnehmer nicht fest. Beim Ereignis participantsAdded
und participantsRemoved
werden die Namen in der API für die Auflistung von Teilnehmer*innen als NULL zurückgegeben. Die Anzeigenamen der Chatteilnehmer können aus dem remoteParticipants
-Feld des call
-Objekts abgerufen werden.
Abrufen eines Teams-Besprechungschatthreads für einen Communication Services-Benutzer
Die Details für die Teams-Besprechung können über Graph-APIs abgerufen werden, wie in der Graph-Dokumentation ausführlich erläutert. Das Communication Services Calling SDK akzeptiert einen vollständigen Teams-Besprechungslink oder eine Besprechungs-ID. Beide werden als Teil der onlineMeeting
-Ressource zurückgegeben, auf die unter der joinWebUrl
-Eigenschaft zugegriffen werden kann.
Mit den Graph-APIs können Sie auch das threadID
abrufen. Die Antwort umfasst ein chatInfo
-Objekt, das die threadID
enthält.
Ausführen des Codes
Sie können die App jetzt über die Schaltfläche " App ausführen " auf der Symbolleiste starten (UMSCHALT+F10).
Um an der Microsoft Teams-Besprechung und am Chat teilzunehmen, geben Sie den Besprechungslink aus Microsoft Teams und die Thread-ID in die Benutzeroberfläche ein.
Nach dem Beitritt zur Teams-Besprechung müssen Sie den*die Benutzer*in in Ihrem Teams-Client zur Besprechung zulassen. Sobald der Benutzer zugelassen ist und dem Chat beitritt, kann er Nachrichten senden und empfangen.
Hinweis
Bestimmte Funktionen werden derzeit für Szenarien zur Interoperabilität mit Teams nicht unterstützt. Weitere Informationen zu unterstützten Features finden Sie unter Teams-Besprechungsfunktionen für externe Teams-Benutzer
In diesem Artikel wird beschrieben, wie Sie mit dem Azure Communication Services Chat SDK für C# in einer Teams-Besprechung chatten.
Beispielcode
Laden Sie diesen Code von GitHub Azure Samples herunter und verbinden Sie Ihre Chat-App mit einem Teams-Meeting.
Voraussetzungen
- Eine Teams-Bereitstellung
- Ein Azure-Konto mit einem aktiven Abonnement. Sie können kostenlos ein Konto erstellen.
- Installieren Sie Visual Studio 2019 mit der Workload „Entwicklung für die universelle Windows-Plattform“.
- Eine bereitgestellte Communication Services-Ressource. Erstellen Sie eine Communication Services-Ressource.
- Einen Teams-Besprechungslink.
Beitritt zum Besprechungs-Chat
Ein Kommunikationsdienste-Benutzer kann anonym über das Anruf-SDK an einer Teams-Besprechung teilnehmen. Wenn Sie an dem Meeting teilnehmen, werden Sie auch als Teilnehmer zum Meeting-Chat hinzugefügt. Im Chat können sie Nachrichten mit anderen Benutzern in der Besprechung senden und empfangen. Der Benutzer hat keinen Zugriff auf Chatnachrichten, die gesendet wurden, bevor er an der Besprechung teilnimmt. Sie können keine Nachrichten senden oder empfangen, nachdem die Besprechung beendet wurde. Führen Sie die folgenden Schritte aus, um Benutzern die Teilnahme an den Teams-Besprechungen zu ermöglichen und mit dem Chatten zu beginnen.
Ausführen des Codes
Sie können den Build in Visual Studio erstellen und den Code ausführen. Die unterstützten Lösungsplattformen sind: x64
,x86
, und ARM64
.
Öffnen Sie eine Instanz von PowerShell, des Windows-Terminals, einer Eingabeaufforderung oder ein Äquivalent dazu, und navigieren Sie zu dem Verzeichnis, in dem Sie das Beispiel klonen möchten.
git clone https://github.com/Azure-Samples/Communication-Services-dotnet-quickstarts.git
Öffnen Sie das Projekt
ChatTeamsInteropQuickStart/ChatTeamsInteropQuickStart.csproj
in Visual Studio.Installieren Sie die folgenden NuGet-Paketversionen (oder höher):
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
Fügen Sie der Datei ChatTeamsInteropQuickStart/MainPage.xaml.cs die Verbindungszeichenfolge mit der in den Voraussetzungen vermittelten Communication Services-Ressource hinzu.
//Azure Communication Services resource connection string, i.e., = "endpoint=https://your-resource.communication.azure.net/;accesskey=your-access-key"; private const string connectionString_ = "";
Wichtig
- Wählen Sie die richtige Plattform aus der Dropdownliste "Lösungsplattformen " in Visual Studio aus, bevor Sie den Code ausführen, z. B.
x64
- Stellen Sie sicher, dass Sie den Entwicklermodus in Windows aktivieren (Entwicklereinstellungen)
Die nächsten Schritte funktionieren nicht, wenn die Plattform nicht ordnungsgemäß konfiguriert ist.
- Wählen Sie die richtige Plattform aus der Dropdownliste "Lösungsplattformen " in Visual Studio aus, bevor Sie den Code ausführen, z. B.
Drücken Sie F5 , um das Projekt im Debugmodus zu starten.
Fügen Sie einen gültigen Teambesprechungslink in das Feld " Teams-Besprechungslink " ein (siehe den nächsten Abschnitt).
Endbenutzer klicken auf "An Teams-Besprechung teilnehmen ", um mit dem Chatten zu beginnen.
Wichtig
Sobald das aufrufende SDK eine Verbindung mit der Teamsitzung hergestellt hat siehe „Communication Services, die die Windows App aufrufen“, sind die Schlüsselfunktionen zur Handhabung von Chatvorgängen: StartPollingForChatMessages
und SendMessageButton_Click
. Beide Codeausschnitte befinden sich in der ChatTeamsInteropQuickStart\MainPage.xaml.cs
Datei.
/// <summary>
/// Background task that keeps polling for chat messages while the call connection is established
/// </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 occurred 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;
}
Erhalten des Teams-Besprechungslinks
Rufen Sie den Teams-Besprechungslink mithilfe von Graph-APIs ab, wie in der Graph-Dokumentation beschrieben. Dieser Link wird als Teil der onlineMeeting
-Ressource zurückgegeben, auf die unter der joinWebUrl
-Eigenschaft zugegriffen werden kann.
Der erforderliche Besprechungslink kann auch der URL für den Besprechungsbeitritt aus der Teams-Besprechungseinladung entnommen werden.
Ein Teams-Besprechungslink sieht wie die folgende URL aus:
https://teams.microsoft.com/l/meetup-join/meeting_chat_thread_id/1606337455313?context=some_context_here`.
Wenn Ihr Teams-Link ein anderes Format aufweist, müssen Sie die Thread-ID mithilfe der Graph-API abrufen.
Hinweis
Bestimmte Funktionen werden derzeit für Szenarien zur Interoperabilität mit Teams nicht unterstützt. Weitere Informationen zu unterstützten Features finden Sie unter Teams-Besprechungsfunktionen für externe Teams-Benutzer.
Bereinigen von Ressourcen
Wenn Sie ein Communication Services-Abonnement bereinigen und entfernen möchten, können Sie die Ressource oder die Ressourcengruppe löschen. Wenn Sie die Ressourcengruppe löschen, werden auch alle anderen Ressourcen gelöscht, die ihr zugeordnet sind. Weitere Informationen zum Bereinigen von Ressourcen finden Sie hier.
Verwandte Artikel
- Sehen Sie sich unser Hero-Beispiel für Chat an.
- Erfahren Sie mehr über die Funktionsweise des Chats.