Schnellstart: Verknüpfen Ihrer Anruf-App mit einer Teams-Anrufwarteschlange
In diesem Schnellstart werden Sie erfahren, wie Sie einen Anruf von einem Azure Communication Services-Benutzer an die Teams-Anrufwarteschlange starten. Sie werden dies mit den folgenden Schritten erreichen:
- Aktivieren Sie den Verbund der Azure Communication Services-Ressource mit dem Teams-Mandanten.
- Wählen oder erstellen Sie die Teams-Anrufwarteschlange über das Teams Admin Center.
- Rufen Sie die E-Mail-Adresse der Anrufwarteschlange über das Teams Admin Center ab.
- Rufen Sie die Objekt-ID der Anrufwarteschlange über die Graph-API ab.
- Starten Sie einen Anruf mit dem Anruf-SDK von Azure Communication Services.
Wenn Sie direkt zum Ende springen möchten, können Sie diese Schnellstartanleitung als Beispiel auf GitHub herunterladen.
Aktivieren der Interoperabilität in Ihrem Teams-Mandanten
Microsoft Entra-Benutzer mit der Teams-Administratorrolle können das PowerShell-Cmdlet mit dem MicrosoftTeams-Modul ausführen, um die Communication Services-Ressource im Mandanten zu aktivieren.
1. Vorbereiten des Microsoft Teams-Moduls
Öffnen Sie zunächst die PowerShell, und überprüfen Sie das Vorhandensein des Teams-Moduls mit dem folgenden Befehl:
Get-module *teams*
Wenn das MicrosoftTeams
-Modul nicht angezeigt wird, installieren Sie es zuerst. Um das Modul zu installieren, müssen Sie PowerShell als Administrator ausführen. Führen Sie dann den folgenden Befehl aus:
Install-Module -Name MicrosoftTeams
Sie werden über die Module informiert, die installiert werden, die Sie mit der Antwort Y
oder A
bestätigen können. Wenn das Modul installiert, aber veraltet ist, können Sie den folgenden Befehl ausführen, um das Modul zu aktualisieren:
Update-Module MicrosoftTeams
2. Herstellen einer Verbindung mit dem Microsoft Teams-Modul
Wenn das Modul installiert und bereit ist, können Sie mit dem folgenden Befehl eine Verbindung mit dem MicrosftTeams-Modul herstellen. Sie werden aufgefordert, sich mit einem interaktiven Fenster anzumelden. Das Benutzerkonto, das Sie verwenden möchten, muss über Teams-Administratorberechtigungen verfügen. Andernfalls erhalten Sie möglicherweise in den nächsten Schritten die Antwort access denied
.
Connect-MicrosoftTeams
3. Aktivieren der Mandantenkonfiguration
Die Interoperabilität mit Communication Services-Ressourcen wird über die Mandantenkonfiguration und die zugewiesene Richtlinie gesteuert. Der Teams-Mandant verfügt über eine einzelne Mandantenkonfiguration, und Teams-Benutzer*innen wurde eine globale Richtlinie oder eine benutzerdefinierte Richtlinie zugewiesen. Weitere Informationen finden Sie unter Zuweisen von Richtlinien in Teams.
Nach erfolgreicher Anmeldung können Sie das Cmdlet Set-CsTeamsAcsFederationConfiguration ausführen, um die Communication Services-Ressource in Ihrem Mandanten zu aktivieren. Ersetzen Sie den Text IMMUTABLE_RESOURCE_ID
durch eine unveränderliche Ressourcen-ID in Ihrer Kommunikationsressource. Weitere Informationen zum Abrufen dieser Informationen finden Sie hier.
$allowlist = @('IMMUTABLE_RESOURCE_ID')
Set-CsTeamsAcsFederationConfiguration -EnableAcsUsers $True -AllowedAcsResources $allowlist
4. Aktivieren der Mandantenrichtlinie
Jedem Teams-Benutzer wurde eine External Access Policy
zugewiesen, die festlegt, ob Communication Services-Benutzer*innen diese Teams-Benutzer*in bzw. diesen Teams-Benutzer aufrufen können. Verwenden Sie das Cmdlet Set-CsExternalAccessPolicy, um sicherzustellen, dass für die der Teams-Benutzer*in bzw. dem Teams-Benutzer zugewiesene Richtlinie EnableAcsFederationAccess
auf $true
festgelegt ist
Set-CsExternalAccessPolicy -Identity Global -EnableAcsFederationAccess $true
Erstellen oder Auswählen einer Teams-Anrufwarteschlange
Die Teams-Anrufwarteschlange ist ein Feature in Microsoft Teams, das eingehende Anrufe effizient an eine Gruppe von bestimmten Benutzern oder Agenten verteilt. Es ist nützlich für Kundensupport- oder Callcenterszenarien. Aufrufe werden in eine Warteschlange gestellt und dem nächsten verfügbaren Agenten basierend auf einer vordefinierten Routingmethode zugewiesen. Agenten erhalten Benachrichtigungen und können Anrufe mithilfe der Anrufsteuerelementen von Teams verarbeiten. Das Feature bietet Berichte und Analysen für die Leistungsnachverfolgung. Es vereinfacht die Anrufbehandlung, stellt eine konsistente Kundenerfahrung sicher und optimiert die Produktivität der Agenten. Sie können über das Teams Admin Center eine vorhandene Anrufwarteschlange auswählen oder eine neue erstellen.
Weitere Informationen zum Erstellen der Anrufwarteschlange mit dem Teams Admin Center finden Sie hier.
Objekt-ID für Anrufwarteschlange suchen
Nachdem die Anrufwarteschlange erstellt wurde, müssen wir die korrelierte Objekt-ID suchen, um sie später für Aufrufe verwenden zu können. Die Objekt-ID ist mit dem Ressourcenkonto verbunden, das an die Anrufwarteschlange angefügt wurde. Öffnen Sie die Registerkarte „Ressourcenkonten“ in Teams Admin, und suchen Sie nach der E-Mail. Alle erforderlichen Informationen zu Ressourcenkonten können im Microsoft Graph-Explorer gefunden werden, indem diese E-Mail in der Suche verwendet wird.
https://graph.microsoft.com/v1.0/users/lab-test2-cq-@contoso.com
In den Ergebnissen können wir das Feld „ID“ finden
"userPrincipalName": "lab-test2-cq@contoso.com",
"id": "31a011c2-2672-4dd0-b6f9-9334ef4999db"
Voraussetzungen
- Rufen Sie ein Azure-Konto mit einem aktiven Abonnement ab. Sie können kostenlos ein Konto erstellen.
- Node.js: Active LTS- und Maintenance LTS-Versionen (8.11.1 und 10.14.1).
- Erstellen Sie eine aktive Communication Services-Ressource. Erstellen Sie eine Communication Services-Ressource.
Einrichten
Erstellen einer neuen Node.js-Anwendung
Öffnen Sie das Terminal- oder Befehlsfenster, erstellen Sie ein neues Verzeichnis für Ihre App, und navigieren Sie zu diesem Verzeichnis.
mkdir calling-quickstart && cd calling-quickstart
Installieren des Pakets
Verwenden Sie den Befehl npm install
, um das Azure Communication Services Calling SDK für JavaScript zu installieren.
Wichtig
In dieser Schnellstartanleitung wird Version next
des Azure Communication Services Calling SDK verwendet.
npm install @azure/communication-common@next --save
npm install @azure/communication-calling@next --save
Einrichten des App-Frameworks
In dieser Schnellstartanleitung wird Webpack verwendet, um die Anwendungsressourcen zu bündeln. Führen Sie den folgenden Befehl aus, um die npm-Pakete webpack
, webpack-cli
und webpack-dev-server
zu installieren und diese als Entwicklungsabhängigkeiten in package.json
aufzulisten:
npm install copy-webpack-plugin@^11.0.0 webpack@^5.88.2 webpack-cli@^5.1.4 webpack-dev-server@^4.15.1 --save-dev
Erstellen Sie im Stammverzeichnis Ihres Projekts die Datei index.html
. Diese Datei wird zum Konfigurieren eines grundlegenden Layouts verwendet, das es dem Benutzer ermöglicht, einen 1:1-Videoanruf zu tätigen.
Der Code lautet wie folgt:
<!-- index.html -->
<!DOCTYPE html>
<html>
<head>
<title>Azure Communication Services - Calling Web SDK</title>
</head>
<body>
<h4>Azure Communication Services - Calling Web SDK</h4>
<input id="user-access-token"
type="text"
placeholder="User access token"
style="margin-bottom:1em; width: 500px;"/>
<button id="initialize-teams-call-agent" type="button">Initialize Call Agent</button>
<br>
<br>
<input id="application-object-id"
type="text"
placeholder="Enter callee's Teams user identity in format: 'APP_GUID'"
style="margin-bottom:1em; width: 500px; display: block;"/>
<button id="start-call-button" type="button" disabled="true">Start Call</button>
<button id="hangup-call-button" type="button" disabled="true">Hang up Call</button>
<button id="accept-call-button" type="button" disabled="true">Accept Call</button>
<button id="start-video-button" type="button" disabled="true">Start Video</button>
<button id="stop-video-button" type="button" disabled="true">Stop Video</button>
<br>
<br>
<div id="connectedLabel" style="color: #13bb13;" hidden>Call is connected!</div>
<br>
<div id="remoteVideoContainer" style="width: 40%;" hidden>Remote participants' video streams:</div>
<br>
<div id="localVideoContainer" style="width: 30%;" hidden>Local video stream:</div>
<!-- points to the bundle generated from client.js -->
<script src="./main.js"></script>
</body>
</html>
Objektmodell des Azure Communication Services Calling Web SDK
Die folgenden Klassen und Schnittstellen befassen sich mit einigen der wichtigsten Features des Azure Communication Services Calling SDK:
Name | BESCHREIBUNG |
---|---|
CallClient |
Der Haupteinstiegspunkt des Calling SDK. |
CallAgent |
Dient zum Starten und Verwalten von Anrufen. |
DeviceManager |
Dient zum Verwalten von Mediengeräten. |
Call |
Dient zum Darstellen eines Anrufs. |
LocalVideoStream |
Dient zum Erstellen eines lokalen Videostreams für ein Kameragerät auf dem lokalen System. |
RemoteParticipant |
Dient zum Darstellen eines Remote-Teilnehmers im Anruf. |
RemoteVideoStream |
Dient zum Darstellen eines Remotevideostreams von einem Remoteteilnehmer. |
Erstellen Sie im Stammverzeichnis Ihres Projekts eine Datei mit dem Namen client.js
, die die Anwendungslogik für diese Schnellstartanleitung enthalten soll. Fügen Sie den folgenden Code zu client.js hinzu.
// Make sure to install the necessary dependencies
const { CallClient, VideoStreamRenderer, LocalVideoStream } = require('@azure/communication-calling');
const { AzureCommunicationTokenCredential } = require('@azure/communication-common');
const { AzureLogger, setLogLevel } = require("@azure/logger");
// Set the log level and output
setLogLevel('verbose');
AzureLogger.log = (...args) => {
console.log(...args);
};
// Calling web sdk objects
let callAgent;
let deviceManager;
let call;
let incomingCall;
let localVideoStream;
let localVideoStreamRenderer;
// UI widgets
let userAccessToken = document.getElementById('user-access-token');
let callQueueId = document.getElementById('application-object-id');
let initializeCallAgentButton = document.getElementById('initialize-teams-call-agent');
let startCallButton = document.getElementById('start-call-button');
let hangUpCallButton = document.getElementById('hangup-call-button');
let acceptCallButton = document.getElementById('accept-call-button');
let startVideoButton = document.getElementById('start-video-button');
let stopVideoButton = document.getElementById('stop-video-button');
let connectedLabel = document.getElementById('connectedLabel');
let remoteVideoContainer = document.getElementById('remoteVideoContainer');
let localVideoContainer = document.getElementById('localVideoContainer');
/**
* Create an instance of CallClient. Initialize a CallAgent instance with a AzureCommunicationTokenCredential via created CallClient. CallAgent enables us to make outgoing calls and receive incoming calls.
* You can then use the CallClient.getDeviceManager() API instance to get the DeviceManager.
*/
initializeCallAgentButton.onclick = async () => {
try {
const callClient = new CallClient();
tokenCredential = new AzureCommunicationTokenCredential(userAccessToken.value.trim());
callAgent = await callClient.createCallAgent(tokenCredential)
// Set up a camera device to use.
deviceManager = await callClient.getDeviceManager();
await deviceManager.askDevicePermission({ video: true });
await deviceManager.askDevicePermission({ audio: true });
// Listen for an incoming call to accept.
callAgent.on('incomingCall', async (args) => {
try {
incomingCall = args.incomingCall;
acceptCallButton.disabled = false;
startCallButton.disabled = true;
} catch (error) {
console.error(error);
}
});
startCallButton.disabled = false;
initializeCallAgentButton.disabled = true;
} catch(error) {
console.error(error);
}
}
/**
* Place a 1:1 outgoing video call to a Teams Call Queue
* Add an event listener to initiate a call when the `startCallButton` is selected.
* Enumerate local cameras using the deviceManager `getCameraList` API.
* In this quickstart, we're using the first camera in the collection. Once the desired camera is selected, a
* LocalVideoStream instance will be constructed and passed within `videoOptions` as an item within the
* localVideoStream array to the call method. When the call connects, your application will be sending a video stream to the other participant.
*/
startCallButton.onclick = async () => {
try {
const localVideoStream = await createLocalVideoStream();
const videoOptions = localVideoStream ? { localVideoStreams: [localVideoStream] } : undefined;
call = callAgent.startCall([{ teamsAppId: callQueueId.value.trim(), cloud:"public" }], { videoOptions: videoOptions });
// Subscribe to the call's properties and events.
subscribeToCall(call);
} catch (error) {
console.error(error);
}
}
/**
* Accepting an incoming call with a video
* Add an event listener to accept a call when the `acceptCallButton` is selected.
* You can accept incoming calls after subscribing to the `CallAgent.on('incomingCall')` event.
* You can pass the local video stream to accept the call with the following code.
*/
acceptCallButton.onclick = async () => {
try {
const localVideoStream = await createLocalVideoStream();
const videoOptions = localVideoStream ? { localVideoStreams: [localVideoStream] } : undefined;
call = await incomingCall.accept({ videoOptions });
// Subscribe to the call's properties and events.
subscribeToCall(call);
} catch (error) {
console.error(error);
}
}
// Subscribe to a call obj.
// Listen for property changes and collection udpates.
subscribeToCall = (call) => {
try {
// Inspect the initial call.id value.
console.log(`Call Id: ${call.id}`);
//Subsribe to call's 'idChanged' event for value changes.
call.on('idChanged', () => {
console.log(`Call ID changed: ${call.id}`);
});
// Inspect the initial call.state value.
console.log(`Call state: ${call.state}`);
// Subscribe to call's 'stateChanged' event for value changes.
call.on('stateChanged', async () => {
console.log(`Call state changed: ${call.state}`);
if(call.state === 'Connected') {
connectedLabel.hidden = false;
acceptCallButton.disabled = true;
startCallButton.disabled = true;
hangUpCallButton.disabled = false;
startVideoButton.disabled = false;
stopVideoButton.disabled = false;
} else if (call.state === 'Disconnected') {
connectedLabel.hidden = true;
startCallButton.disabled = false;
hangUpCallButton.disabled = true;
startVideoButton.disabled = true;
stopVideoButton.disabled = true;
console.log(`Call ended, call end reason={code=${call.callEndReason.code}, subCode=${call.callEndReason.subCode}}`);
}
});
call.localVideoStreams.forEach(async (lvs) => {
localVideoStream = lvs;
await displayLocalVideoStream();
});
call.on('localVideoStreamsUpdated', e => {
e.added.forEach(async (lvs) => {
localVideoStream = lvs;
await displayLocalVideoStream();
});
e.removed.forEach(lvs => {
removeLocalVideoStream();
});
});
call.on('isLocalVideoStartedChanged', () => {
console.log(`isLocalVideoStarted changed: ${call.isLocalVideoStarted}`);
});
console.log(`isLocalVideoStarted: ${call.isLocalVideoStarted}`);
// Inspect the call's current remote participants and subscribe to them.
call.remoteParticipants.forEach(remoteParticipant => {
subscribeToRemoteParticipant(remoteParticipant);
});
// Subscribe to the call's 'remoteParticipantsUpdated' event to be
// notified when new participants are added to the call or removed from the call.
call.on('remoteParticipantsUpdated', e => {
// Subscribe to new remote participants that are added to the call.
e.added.forEach(remoteParticipant => {
subscribeToRemoteParticipant(remoteParticipant)
});
// Unsubscribe from participants that are removed from the call
e.removed.forEach(remoteParticipant => {
console.log('Remote participant removed from the call.');
});
});
} catch (error) {
console.error(error);
}
}
// Subscribe to a remote participant obj.
// Listen for property changes and collection udpates.
subscribeToRemoteParticipant = (remoteParticipant) => {
try {
// Inspect the initial remoteParticipant.state value.
console.log(`Remote participant state: ${remoteParticipant.state}`);
// Subscribe to remoteParticipant's 'stateChanged' event for value changes.
remoteParticipant.on('stateChanged', () => {
console.log(`Remote participant state changed: ${remoteParticipant.state}`);
});
// Inspect the remoteParticipants's current videoStreams and subscribe to them.
remoteParticipant.videoStreams.forEach(remoteVideoStream => {
subscribeToRemoteVideoStream(remoteVideoStream)
});
// Subscribe to the remoteParticipant's 'videoStreamsUpdated' event to be
// notified when the remoteParticiapant adds new videoStreams and removes video streams.
remoteParticipant.on('videoStreamsUpdated', e => {
// Subscribe to newly added remote participant's video streams.
e.added.forEach(remoteVideoStream => {
subscribeToRemoteVideoStream(remoteVideoStream)
});
// Unsubscribe from newly removed remote participants' video streams.
e.removed.forEach(remoteVideoStream => {
console.log('Remote participant video stream was removed.');
})
});
} catch (error) {
console.error(error);
}
}
/**
* Subscribe to a remote participant's remote video stream obj.
* You have to subscribe to the 'isAvailableChanged' event to render the remoteVideoStream. If the 'isAvailable' property
* changes to 'true' a remote participant is sending a stream. Whenever the availability of a remote stream changes
* you can choose to destroy the whole 'Renderer' a specific 'RendererView' or keep them. Displaying RendererView without a video stream will result in a blank video frame.
*/
subscribeToRemoteVideoStream = async (remoteVideoStream) => {
// Create a video stream renderer for the remote video stream.
let videoStreamRenderer = new VideoStreamRenderer(remoteVideoStream);
let view;
const renderVideo = async () => {
try {
// Create a renderer view for the remote video stream.
view = await videoStreamRenderer.createView();
// Attach the renderer view to the UI.
remoteVideoContainer.hidden = false;
remoteVideoContainer.appendChild(view.target);
} catch (e) {
console.warn(`Failed to createView, reason=${e.message}, code=${e.code}`);
}
}
remoteVideoStream.on('isAvailableChanged', async () => {
// Participant has switched video on.
if (remoteVideoStream.isAvailable) {
await renderVideo();
// Participant has switched video off.
} else {
if (view) {
view.dispose();
view = undefined;
}
}
});
// Participant has video on initially.
if (remoteVideoStream.isAvailable) {
await renderVideo();
}
}
// Start your local video stream.
// This will send your local video stream to remote participants so they can view it.
startVideoButton.onclick = async () => {
try {
const localVideoStream = await createLocalVideoStream();
await call.startVideo(localVideoStream);
} catch (error) {
console.error(error);
}
}
// Stop your local video stream.
// This will stop your local video stream from being sent to remote participants.
stopVideoButton.onclick = async () => {
try {
await call.stopVideo(localVideoStream);
} catch (error) {
console.error(error);
}
}
/**
* To render a LocalVideoStream, you need to create a new instance of VideoStreamRenderer, and then
* create a new VideoStreamRendererView instance using the asynchronous createView() method.
* You may then attach view.target to any UI element.
*/
// Create a local video stream for your camera device
createLocalVideoStream = async () => {
const camera = (await deviceManager.getCameras())[0];
if (camera) {
return new LocalVideoStream(camera);
} else {
console.error(`No camera device found on the system`);
}
}
// Display your local video stream preview in your UI
displayLocalVideoStream = async () => {
try {
localVideoStreamRenderer = new VideoStreamRenderer(localVideoStream);
const view = await localVideoStreamRenderer.createView();
localVideoContainer.hidden = false;
localVideoContainer.appendChild(view.target);
} catch (error) {
console.error(error);
}
}
// Remove your local video stream preview from your UI
removeLocalVideoStream = async() => {
try {
localVideoStreamRenderer.dispose();
localVideoContainer.hidden = true;
} catch (error) {
console.error(error);
}
}
// End the current call
hangUpCallButton.addEventListener("click", async () => {
// end the current call
await call.hangUp();
});
Hinzufügen des lokalen Webpack-Servercodes
Erstellen Sie im Stammverzeichnis Ihres Projekts eine Datei mit dem Namen webpack.config.js, die die lokale Serverlogik für diesen Schnellstart enthalten soll. Fügen Sie der Datei webpack.config.js den folgenden Code hinzu:
const path = require('path');
const CopyPlugin = require("copy-webpack-plugin");
module.exports = {
mode: 'development',
entry: './client.js',
output: {
filename: 'main.js',
path: path.resolve(__dirname, 'dist'),
},
devServer: {
static: {
directory: path.join(__dirname, './')
},
},
plugins: [
new CopyPlugin({
patterns: [
'./index.html'
]
}),
]
};
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 den Anwendungshost auf einem lokalen Webserver zu bündeln:
npx webpack serve --config webpack.config.js
Manuelle Schritte zum Einrichten des Anrufs:
- Navigieren Sie in Ihrem Browser zu http://localhost:8080/..
- Geben Sie ein gültiges Benutzerzugriffstoken ein. Wenn Sie noch über kein Zugriffstoken verfügen, finden Sie in der Dokumentation zu Benutzerzugriffstoken weitere Informationen.
- Klicken Sie auf die Schaltflächen „Anruf-Agent initialisieren“.
- Geben Sie die ID des Anrufwarteschlangenobjekts ein, und wählen Sie die Schaltfläche „Anruf starten“ aus. Die Anwendung wird den ausgehenden Aufruf an die Anrufwarteschlange mit der angegebenen Objekt-ID starten.
- Der Anruf ist mit der Anrufwarteschlange verbunden.
- Der Communication Services-Benutzer wird basierend auf der Konfiguration durch die Anrufwarteschlange weitergeleitet.
Wichtig
Dieses Feature von Azure Communication Services befindet sich derzeit in der Vorschau.
Vorschau-APIs und -SDKs werden ohne Vereinbarung zum Servicelevel bereitgestellt. Es wird empfohlen, diese nicht für Produktionsworkloads zu verwenden. Einige Features werden möglicherweise nicht unterstützt oder bieten nur eingeschränkte Funktionalität.
Weitere Informationen finden Sie in den ergänzenden Nutzungsbestimmungen für Microsoft Azure-Vorschauversionen.
In diesem Schnellstart werden Sie erfahren, wie Sie einen Anruf von einem Azure Communication Services-Benutzer an die Teams-Anrufwarteschlange starten. Sie werden dies mit den folgenden Schritten erreichen:
- Aktivieren Sie den Verbund der Azure Communication Services-Ressource mit dem Teams-Mandanten.
- Wählen oder erstellen Sie die Teams-Anrufwarteschlange über das Teams Admin Center.
- Rufen Sie die E-Mail-Adresse der Anrufwarteschlange über das Teams Admin Center ab.
- Rufen Sie die Objekt-ID der Anrufwarteschlange über die Graph-API ab.
- Starten Sie einen Anruf mit dem Anruf-SDK von Azure Communication Services.
Wenn Sie direkt zum Ende springen möchten, können Sie diese Schnellstartanleitung als Beispiel auf GitHub herunterladen.
Aktivieren der Interoperabilität in Ihrem Teams-Mandanten
Microsoft Entra-Benutzer mit der Teams-Administratorrolle können das PowerShell-Cmdlet mit dem MicrosoftTeams-Modul ausführen, um die Communication Services-Ressource im Mandanten zu aktivieren.
1. Vorbereiten des Microsoft Teams-Moduls
Öffnen Sie zunächst die PowerShell, und überprüfen Sie das Vorhandensein des Teams-Moduls mit dem folgenden Befehl:
Get-module *teams*
Wenn das MicrosoftTeams
-Modul nicht angezeigt wird, installieren Sie es zuerst. Um das Modul zu installieren, müssen Sie PowerShell als Administrator ausführen. Führen Sie dann den folgenden Befehl aus:
Install-Module -Name MicrosoftTeams
Sie werden über die Module informiert, die installiert werden, die Sie mit der Antwort Y
oder A
bestätigen können. Wenn das Modul installiert, aber veraltet ist, können Sie den folgenden Befehl ausführen, um das Modul zu aktualisieren:
Update-Module MicrosoftTeams
2. Herstellen einer Verbindung mit dem Microsoft Teams-Modul
Wenn das Modul installiert und bereit ist, können Sie mit dem folgenden Befehl eine Verbindung mit dem MicrosftTeams-Modul herstellen. Sie werden aufgefordert, sich mit einem interaktiven Fenster anzumelden. Das Benutzerkonto, das Sie verwenden möchten, muss über Teams-Administratorberechtigungen verfügen. Andernfalls erhalten Sie möglicherweise in den nächsten Schritten die Antwort access denied
.
Connect-MicrosoftTeams
3. Aktivieren der Mandantenkonfiguration
Die Interoperabilität mit Communication Services-Ressourcen wird über die Mandantenkonfiguration und die zugewiesene Richtlinie gesteuert. Der Teams-Mandant verfügt über eine einzelne Mandantenkonfiguration, und Teams-Benutzer*innen wurde eine globale Richtlinie oder eine benutzerdefinierte Richtlinie zugewiesen. Weitere Informationen finden Sie unter Zuweisen von Richtlinien in Teams.
Nach erfolgreicher Anmeldung können Sie das Cmdlet Set-CsTeamsAcsFederationConfiguration ausführen, um die Communication Services-Ressource in Ihrem Mandanten zu aktivieren. Ersetzen Sie den Text IMMUTABLE_RESOURCE_ID
durch eine unveränderliche Ressourcen-ID in Ihrer Kommunikationsressource. Weitere Informationen zum Abrufen dieser Informationen finden Sie hier.
$allowlist = @('IMMUTABLE_RESOURCE_ID')
Set-CsTeamsAcsFederationConfiguration -EnableAcsUsers $True -AllowedAcsResources $allowlist
4. Aktivieren der Mandantenrichtlinie
Jedem Teams-Benutzer wurde eine External Access Policy
zugewiesen, die festlegt, ob Communication Services-Benutzer*innen diese Teams-Benutzer*in bzw. diesen Teams-Benutzer aufrufen können. Verwenden Sie das Cmdlet Set-CsExternalAccessPolicy, um sicherzustellen, dass für die der Teams-Benutzer*in bzw. dem Teams-Benutzer zugewiesene Richtlinie EnableAcsFederationAccess
auf $true
festgelegt ist
Set-CsExternalAccessPolicy -Identity Global -EnableAcsFederationAccess $true
Erstellen oder Auswählen einer Teams-Anrufwarteschlange
Die Teams-Anrufwarteschlange ist ein Feature in Microsoft Teams, das eingehende Anrufe effizient an eine Gruppe von bestimmten Benutzern oder Agenten verteilt. Es ist nützlich für Kundensupport- oder Callcenterszenarien. Aufrufe werden in eine Warteschlange gestellt und dem nächsten verfügbaren Agenten basierend auf einer vordefinierten Routingmethode zugewiesen. Agenten erhalten Benachrichtigungen und können Anrufe mithilfe der Anrufsteuerelementen von Teams verarbeiten. Das Feature bietet Berichte und Analysen für die Leistungsnachverfolgung. Es vereinfacht die Anrufbehandlung, stellt eine konsistente Kundenerfahrung sicher und optimiert die Produktivität der Agenten. Sie können über das Teams Admin Center eine vorhandene Anrufwarteschlange auswählen oder eine neue erstellen.
Weitere Informationen zum Erstellen der Anrufwarteschlange mit dem Teams Admin Center finden Sie hier.
Objekt-ID für Anrufwarteschlange suchen
Nachdem die Anrufwarteschlange erstellt wurde, müssen wir die korrelierte Objekt-ID suchen, um sie später für Aufrufe verwenden zu können. Die Objekt-ID ist mit dem Ressourcenkonto verbunden, das an die Anrufwarteschlange angefügt wurde. Öffnen Sie die Registerkarte „Ressourcenkonten“ in Teams Admin, und suchen Sie nach der E-Mail. Alle erforderlichen Informationen zu Ressourcenkonten können im Microsoft Graph-Explorer gefunden werden, indem diese E-Mail in der Suche verwendet wird.
https://graph.microsoft.com/v1.0/users/lab-test2-cq-@contoso.com
In den Ergebnissen können wir das Feld „ID“ finden
"userPrincipalName": "lab-test2-cq@contoso.com",
"id": "31a011c2-2672-4dd0-b6f9-9334ef4999db"
Um sie in der Anruf-App zu verwenden, müssen wir dieser ID ein Präfix hinzufügen. Derzeit wird Folgendes unterstützt:
- Anrufwarteschleife in der öffentlichen Cloud:
28:orgid:<id>
- Anrufwarteschleife in der Government Cloud:
28:gcch:<id>
Voraussetzungen
Ein Azure-Konto mit einem aktiven Abonnement. Sie können kostenlos ein Konto erstellen.
Android Studio zum Erstellen Ihrer Android-Anwendung
Eine bereitgestellte Communication Services-Ressource. Erstellen Sie eine Communication Services-Ressource.
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 identity token issue --scope voip --connection-string "yourConnectionString"
Ausführliche Informationen finden Sie unter Verwenden der Azure CLI zum Erstellen und Verwalten von Zugriffstoken.
Mindestunterstützung für Teams-Anrufanwendungen: 2.12.0-beta.1
Einrichten
Erstellen Sie eine Android-App mit einer leeren Aktivität.
Wählen Sie in Android Studio „Start a new Android Studio project“ (Neues Android Studio-Projekt starten) aus.
Wählen Sie unter „Phone and Tablet“ (Telefon und Tablet) die Projektvorlage „Empty Views Activity“ (Leere Ansicht-Aktivität) aus.
Wählen Sie das SDK „API 26: Android 8.0 (Oreo)“ oder höher aus.
Installieren des Pakets
Wählen Sie Ihr Projekt settings.gradle.kts
aus, und stellen Sie sicher, dass Sie mavenCentral()
zur Liste der Repositorys unter pluginManagement
und dependencyResolutionManagement
hinzufügen
pluginManagement {
repositories {
...
mavenCentral()
...
}
}
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
...
mavenCentral()
}
}
Fügen Sie anschließend in der Datei „build.gradle“ auf Modulebene die folgenden Zeilen zu den Abschnitten „dependencies“ und „android“ hinzu.
android {
...
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
...
implementation ("com.azure.android:azure-communication-calling:2.6.0")
...
}
Hinzufügen von Berechtigungen zum Anwendungsmanifest
Damit Sie Berechtigungen anfordern können, die für einen Anruf erforderlich sind, müssen diese zunächst im Anwendungsmanifest (app/src/main/AndroidManifest.xml
) deklariert werden. Ersetzen Sie den Inhalt der Datei durch den folgenden Code:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.contoso.acsquickstart">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<!--Our Calling SDK depends on the Apache HTTP SDK.
When targeting Android SDK 28+, this library needs to be explicitly referenced.
See https://developer.android.com/about/versions/pie/android-9.0-changes-28#apache-p-->
<uses-library android:name="org.apache.http.legacy" android:required="false"/>
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Festlegen des Layouts für die App
Zwei Eingaben sind erforderlich: eine Texteingabe für die Angerufenen-ID und eine Schaltfläche zum Tätigen des Anrufs. Diese Eingaben können über den Designer oder durch Bearbeiten der Layout-XML-Datei hinzugefügt werden. Erstellen Sie eine Schaltfläche mit der ID von call_button
und einer Texteingabe für callee_id
. Navigieren Sie zu app/src/main/res/layout/activity_main.xml
, und ersetzen Sie den Inhalt der Datei durch den folgenden Code:
<?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="${launchApp}">
<EditText
android:id="@+id/callee_id"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:hint="Callee Id"
android:inputType="textPersonName"
android:layout_marginTop="100dp"
android:layout_marginHorizontal="20dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="46dp"
android:gravity="center"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">
<Button
android:id="@+id/call_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Call" />
<Button
android:id="@+id/hangup_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hangup" />
</LinearLayout>
<TextView
android:id="@+id/status_bar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Erstellen des Hauptaktivitätsgerüsts und der Bindungen
Nachdem das Layout erstellt wurde, können die Bindungen und das Grundgerüst der Aktivität hinzugefügt werden. Die Aktivität verarbeitet das Anfordern von Runtime-Berechtigungen, erstellt den Anruf-Agent und platziert den Anruf, wenn die Schaltfläche gedrückt wird. Die onCreate
-Methode wird überschrieben, um getAllPermissions
und createAgent
aufzurufen und die Bindungen für die Schaltfläche „Anruf“ hinzuzufügen. Dieses Ereignis tritt nur einmal auf, wenn die Aktivität erstellt wird. Weitere Informationen zu onCreate
finden Sie im Leitfaden mit grundlegenden Informationen zum Aktivitätslebenszyklus.
Navigieren Sie zu MainActivity.java, und ersetzen Sie den Inhalt durch den folgenden Code:
package com.contoso.acsquickstart;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import android.Manifest;
import android.content.pm.PackageManager;
import android.media.AudioManager;
import android.os.Bundle;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.concurrent.ExecutionException;
import com.azure.android.communication.common.CommunicationIdentifier;
import com.azure.android.communication.common.CommunicationUserIdentifier;
import com.azure.android.communication.calling.Call;
import com.azure.android.communication.calling.CallAgent;
import com.azure.android.communication.calling.CallClient;
import com.azure.android.communication.calling.HangUpOptions;
import com.azure.android.communication.common.CommunicationTokenCredential;
import com.azure.android.communication.calling.StartCallOptions;
public class MainActivity extends AppCompatActivity {
private static final String[] allPermissions = new String[] { Manifest.permission.RECORD_AUDIO, Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_PHONE_STATE };
private static final String UserToken = "<User_Access_Token>";
TextView statusBar;
private CallAgent agent;
private Call call;
private Button callButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
callButton = findViewById(R.id.call_button);
getAllPermissions();
createAgent();
callButton.setOnClickListener(l -> startCall());
Button hangupButton = findViewById(R.id.hangup_button);
hangupButton.setOnClickListener(l -> endCall());
statusBar = findViewById(R.id.status_bar);
setVolumeControlStream(AudioManager.STREAM_VOICE_CALL);
}
/**
* Start a call
*/
private void startCall() {
if (UserToken.startsWith("<")) {
Toast.makeText(this, "Please enter token in source code", Toast.LENGTH_SHORT).show();
return;
}
EditText calleeIdView = findViewById(R.id.callee_id);
String calleeId = calleeIdView.getText().toString();
if (calleeId.isEmpty()) {
Toast.makeText(this, "Please enter callee", Toast.LENGTH_SHORT).show();
return;
}
ArrayList<CommunicationIdentifier> participants = new ArrayList<>();
participants.add(new MicrosoftTeamsAppIdentifier(calleeId));
StartCallOptions options = new StartCallOptions();
call = agent.startCall(
getApplicationContext(),
participants,
options);
call.addOnStateChangedListener(p -> setStatus(call.getState().toString()));
}
/**
* Ends the call previously started
*/
private void endCall() {
try {
call.hangUp(new HangUpOptions()).get();
} catch (ExecutionException | InterruptedException e) {
Toast.makeText(this, "Unable to hang up call", Toast.LENGTH_SHORT).show();
}
}
/**
* Create the call agent
*/
private void createAgent() {
try {
CommunicationTokenCredential credential = new CommunicationTokenCredential(UserToken);
agent = new CallClient().createCallAgent(getApplicationContext(), credential).get();
} catch (Exception ex) {
Toast.makeText(getApplicationContext(), "Failed to create call agent.", Toast.LENGTH_SHORT).show();
}
}
/**
* Ensure all permissions were granted, otherwise inform the user permissions are missing.
*/
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, int[] grantResults) {
boolean allPermissionsGranted = true;
for (int result : grantResults) {
allPermissionsGranted &= (result == PackageManager.PERMISSION_GRANTED);
}
if (!allPermissionsGranted) {
Toast.makeText(this, "All permissions are needed to make the call.", Toast.LENGTH_LONG).show();
finish();
}
}
/**
* Shows message in the status bar
*/
private void setStatus(String status) {
runOnUiThread(() -> statusBar.setText(status));
}
}
Anfordern von Berechtigungen zur Runtime
Für Android 6.0 und höher (API-Ebene 23) und targetSdkVersion
23 oder höher werden Berechtigungen zur Runtime gewährt und nicht bei der Installation der App. Damit dies unterstützt wird, kann getAllPermissions
implementiert werden, um für jede erforderliche Berechtigung ActivityCompat.checkSelfPermission
und ActivityCompat.requestPermissions
aufzurufen.
/**
* Request each required permission if the app doesn't already have it.
*/
private void getAllPermissions() {
ArrayList<String> permissionsToAskFor = new ArrayList<>();
for (String permission : allPermissions) {
if (ActivityCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) {
permissionsToAskFor.add(permission);
}
}
if (!permissionsToAskFor.isEmpty()) {
ActivityCompat.requestPermissions(this, permissionsToAskFor.toArray(new String[0]), 1);
}
}
Hinweis
Berücksichtigen Sie beim Entwerfen der App, wann diese Berechtigungen angefordert werden sollen. Berechtigungen müssen angefordert werden, wenn sie benötigt werden, und nicht vorher. Weitere Informationen finden Sie im Leitfaden zu Android-Berechtigungen.
Objektmodell
Die folgenden Klassen und Schnittstellen befassen sich mit einigen der wichtigsten Features des Azure Communication Services Calling SDK:
Name | BESCHREIBUNG |
---|---|
CallClient |
CallClient ist der Haupteinstiegspunkt des Calling SDK. |
CallAgent |
CallAgent dient zum Starten und Verwalten von Anrufen. |
CommunicationTokenCredential |
CommunicationTokenCredential dient als tokengestützte Anmeldeinformation zum Instanziieren von CallAgent . |
CommunicationIdentifier |
CommunicationIdentifier wird als anderer Typ von Teilnehmer verwendet, der Teil eines Anrufs sein könnte. |
Erstellen eines Agents aus dem Benutzerzugriffstoken
Mit einem Benutzertoken kann ein authentifizierter Anruf-Agent instanziiert werden. In der Regel wird dieses Token von einem Dienst mit einer für die Anwendung spezifischen Authentifizierung generiert. Weitere Informationen zu Benutzerzugriffstoken finden Sie im Leitfaden zu Benutzerzugriffstoken.
Ersetzen Sie für den Schnellstart <User_Access_Token>
durch ein Benutzerzugriffstoken, das für Ihre Azure Communication Service-Ressource generiert wurde.
/**
* Create the call agent for placing calls
*/
private void createAgent() {
String userToken = "<User_Access_Token>";
try {
CommunicationTokenCredential credential = new CommunicationTokenCredential(userToken);
callAgent = new CallClient().createCallAgent(getApplicationContext(), credential).get();
} catch (Exception ex) {
Toast.makeText(getApplicationContext(), "Failed to create call agent.", Toast.LENGTH_SHORT).show();
}
}
Ausführen des Codes
Die App kann jetzt mithilfe der Schaltfläche „Anwendung ausführen“ auf der Symbolleiste gestartet werden.
Manuelle Schritte zum Einrichten des Anrufs:
- Starten Sie die App mit Android Studio.
- Geben Sie die ID des Anrufwarteschlangenobjekts ein (mit Präfix), und wählen Sie die Schaltfläche „Anruf starten“ aus. Die Anwendung wird den ausgehenden Aufruf an die Anrufwarteschlange mit der angegebenen Objekt-ID starten.
- Der Anruf ist mit der Anrufwarteschlange verbunden.
- Der Communication Services-Benutzer wird basierend auf der Konfiguration durch die Anrufwarteschlange weitergeleitet.
Wichtig
Dieses Feature von Azure Communication Services befindet sich derzeit in der Vorschau.
Vorschau-APIs und -SDKs werden ohne Vereinbarung zum Servicelevel bereitgestellt. Es wird empfohlen, diese nicht für Produktionsworkloads zu verwenden. Einige Features werden möglicherweise nicht unterstützt oder bieten nur eingeschränkte Funktionalität.
Weitere Informationen finden Sie in den ergänzenden Nutzungsbestimmungen für Microsoft Azure-Vorschauversionen.
In diesem Schnellstart werden Sie erfahren, wie Sie einen Anruf von einem Azure Communication Services-Benutzer an die Teams-Anrufwarteschlange starten. Sie werden dies mit den folgenden Schritten erreichen:
- Aktivieren Sie den Verbund der Azure Communication Services-Ressource mit dem Teams-Mandanten.
- Wählen oder erstellen Sie die Teams-Anrufwarteschlange über das Teams Admin Center.
- Rufen Sie die E-Mail-Adresse der Anrufwarteschlange über das Teams Admin Center ab.
- Rufen Sie die Objekt-ID der Anrufwarteschlange über die Graph-API ab.
- Starten Sie einen Anruf mit dem Anruf-SDK von Azure Communication Services.
Wenn Sie direkt zum Ende springen möchten, können Sie diese Schnellstartanleitung als Beispiel auf GitHub herunterladen.
Aktivieren der Interoperabilität in Ihrem Teams-Mandanten
Microsoft Entra-Benutzer mit der Teams-Administratorrolle können das PowerShell-Cmdlet mit dem MicrosoftTeams-Modul ausführen, um die Communication Services-Ressource im Mandanten zu aktivieren.
1. Vorbereiten des Microsoft Teams-Moduls
Öffnen Sie zunächst die PowerShell, und überprüfen Sie das Vorhandensein des Teams-Moduls mit dem folgenden Befehl:
Get-module *teams*
Wenn das MicrosoftTeams
-Modul nicht angezeigt wird, installieren Sie es zuerst. Um das Modul zu installieren, müssen Sie PowerShell als Administrator ausführen. Führen Sie dann den folgenden Befehl aus:
Install-Module -Name MicrosoftTeams
Sie werden über die Module informiert, die installiert werden, die Sie mit der Antwort Y
oder A
bestätigen können. Wenn das Modul installiert, aber veraltet ist, können Sie den folgenden Befehl ausführen, um das Modul zu aktualisieren:
Update-Module MicrosoftTeams
2. Herstellen einer Verbindung mit dem Microsoft Teams-Modul
Wenn das Modul installiert und bereit ist, können Sie mit dem folgenden Befehl eine Verbindung mit dem MicrosftTeams-Modul herstellen. Sie werden aufgefordert, sich mit einem interaktiven Fenster anzumelden. Das Benutzerkonto, das Sie verwenden möchten, muss über Teams-Administratorberechtigungen verfügen. Andernfalls erhalten Sie möglicherweise in den nächsten Schritten die Antwort access denied
.
Connect-MicrosoftTeams
3. Aktivieren der Mandantenkonfiguration
Die Interoperabilität mit Communication Services-Ressourcen wird über die Mandantenkonfiguration und die zugewiesene Richtlinie gesteuert. Der Teams-Mandant verfügt über eine einzelne Mandantenkonfiguration, und Teams-Benutzer*innen wurde eine globale Richtlinie oder eine benutzerdefinierte Richtlinie zugewiesen. Weitere Informationen finden Sie unter Zuweisen von Richtlinien in Teams.
Nach erfolgreicher Anmeldung können Sie das Cmdlet Set-CsTeamsAcsFederationConfiguration ausführen, um die Communication Services-Ressource in Ihrem Mandanten zu aktivieren. Ersetzen Sie den Text IMMUTABLE_RESOURCE_ID
durch eine unveränderliche Ressourcen-ID in Ihrer Kommunikationsressource. Weitere Informationen zum Abrufen dieser Informationen finden Sie hier.
$allowlist = @('IMMUTABLE_RESOURCE_ID')
Set-CsTeamsAcsFederationConfiguration -EnableAcsUsers $True -AllowedAcsResources $allowlist
4. Aktivieren der Mandantenrichtlinie
Jedem Teams-Benutzer wurde eine External Access Policy
zugewiesen, die festlegt, ob Communication Services-Benutzer*innen diese Teams-Benutzer*in bzw. diesen Teams-Benutzer aufrufen können. Verwenden Sie das Cmdlet Set-CsExternalAccessPolicy, um sicherzustellen, dass für die der Teams-Benutzer*in bzw. dem Teams-Benutzer zugewiesene Richtlinie EnableAcsFederationAccess
auf $true
festgelegt ist
Set-CsExternalAccessPolicy -Identity Global -EnableAcsFederationAccess $true
Erstellen oder Auswählen einer Teams-Anrufwarteschlange
Die Teams-Anrufwarteschlange ist ein Feature in Microsoft Teams, das eingehende Anrufe effizient an eine Gruppe von bestimmten Benutzern oder Agenten verteilt. Es ist nützlich für Kundensupport- oder Callcenterszenarien. Aufrufe werden in eine Warteschlange gestellt und dem nächsten verfügbaren Agenten basierend auf einer vordefinierten Routingmethode zugewiesen. Agenten erhalten Benachrichtigungen und können Anrufe mithilfe der Anrufsteuerelementen von Teams verarbeiten. Das Feature bietet Berichte und Analysen für die Leistungsnachverfolgung. Es vereinfacht die Anrufbehandlung, stellt eine konsistente Kundenerfahrung sicher und optimiert die Produktivität der Agenten. Sie können über das Teams Admin Center eine vorhandene Anrufwarteschlange auswählen oder eine neue erstellen.
Weitere Informationen zum Erstellen der Anrufwarteschlange mit dem Teams Admin Center finden Sie hier.
Objekt-ID für Anrufwarteschlange suchen
Nachdem die Anrufwarteschlange erstellt wurde, müssen wir die korrelierte Objekt-ID suchen, um sie später für Aufrufe verwenden zu können. Die Objekt-ID ist mit dem Ressourcenkonto verbunden, das an die Anrufwarteschlange angefügt wurde. Öffnen Sie die Registerkarte „Ressourcenkonten“ in Teams Admin, und suchen Sie nach der E-Mail. Alle erforderlichen Informationen zu Ressourcenkonten können im Microsoft Graph-Explorer gefunden werden, indem diese E-Mail in der Suche verwendet wird.
https://graph.microsoft.com/v1.0/users/lab-test2-cq-@contoso.com
In den Ergebnissen können wir das Feld „ID“ finden
"userPrincipalName": "lab-test2-cq@contoso.com",
"id": "31a011c2-2672-4dd0-b6f9-9334ef4999db"
Um sie in der Anruf-App zu verwenden, müssen wir dieser ID ein Präfix hinzufügen. Derzeit wird Folgendes unterstützt:
- Anrufwarteschleife in der öffentlichen Cloud:
28:orgid:<id>
- Anrufwarteschleife in der Government Cloud:
28:gcch:<id>
Voraussetzungen
Rufen Sie ein Azure-Konto mit einem aktiven Abonnement ab. Sie können kostenlos ein Konto erstellen.
Einen Mac mit Xcode zusammen mit einem gültigen in Ihrer Keychain installierten Entwicklerzertifikat.
Eine bereitgestellte Communication Services-Ressource. Erstellen Sie eine Communication Services-Ressource. Für diese Schnellstartanleitung müssen Sie Ihre Verbindungszeichenfolge erfassen.
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 identity token issue --scope voip --connection-string "yourConnectionString"
Ausführliche Informationen finden Sie unter Verwenden der Azure CLI zum Erstellen und Verwalten von Zugriffstoken.
Mindestunterstützung für Teams-Anrufanwendungen: 2.14.0-beta.1
Einrichten
Erstellen des Xcode-Projekts
Erstellen Sie in Xcode ein neues iOS-Projekt, und wählen Sie die Vorlage App aus. In diesem Tutorial wird das SwiftUI-Framework verwendet, weshalb Sie Language (Sprache) auf Swift und User Interface (Benutzeroberfläche) auf SwiftUI festlegen müssen. Im Rahmen dieses Schnellstarts werden keine Tests erstellt. Sie können die Option Tests einschließen daher deaktivieren.
Installieren des Pakets und der Abhängigkeiten mit CocoaPods
Zum Erstellen einer Podfile-Datei für Ihre Anwendung müssen Sie das Terminal öffnen, zum Projektordner navigieren und Folgendes ausführen:
pod init
Fügen Sie den folgenden Code in die Podfile-Datei ein, und speichern Sie die Datei (stellen Sie sicher, dass „target (Ziel)“ mit dem Namen Ihres Projekts übereinstimmt):
platform :ios, '13.0' use_frameworks! target 'AzureCommunicationCallingSample' do pod 'AzureCommunicationCalling', '~> 2.14.0-beta.1' end
Führen Sie
pod install
aus.Öffnen Sie
.xcworkspace
mit Xcode.
Anfordern des Zugriffs auf das Mikrofon
Damit Sie auf das Mikrofon des Geräts zugreifen zu können, müssen Sie die Liste der Informationseigenschaften Ihrer App mit 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.
Klicken Sie mit der rechten Maustaste auf den Eintrag Info.plist
der Projektstruktur, und wählen Sie anschließend Open As (Öffnen als) >Source Code (Quellcode) aus. Fügen Sie die folgenden Zeilen im Abschnitt <dict>
der obersten Ebene hinzu, und speichern anschließend Sie die Datei.
<key>NSMicrophoneUsageDescription</key>
<string>Need microphone access for VOIP calling.</string>
Einrichten des App-Frameworks
Öffnen Sie die Datei ContentView.swift Ihres Projekts, und fügen Sie am Anfang der Datei eine import
-Deklaration hinzu, um AzureCommunicationCalling library
zu importieren. Importieren Sie außerdem AVFoundation
; wir benötigen diesen Code für die Berechtigungsanforderung für Audio im Code.
import AzureCommunicationCalling
import AVFoundation
Ersetzen Sie die Implementierung der ContentView
-Struktur durch einige einfache Benutzeroberflächen-Steuerelemente, die einem Benutzer das Initiieren und Beenden eines Anrufs ermöglichen. In dieser Schnellstartanleitung fügen wir Geschäftslogik an diese Steuerelemente an.
struct ContentView: View {
@State var callee: String = ""
@State var callClient: CallClient?
@State var callAgent: CallAgent?
@State var call: Call?
var body: some View {
NavigationView {
Form {
Section {
TextField("Who would you like to call?", text: $callee)
Button(action: startCall) {
Text("Start Call")
}.disabled(callAgent == nil)
Button(action: endCall) {
Text("End Call")
}.disabled(call == nil)
}
}
.navigationBarTitle("Calling Quickstart")
}.onAppear {
// Initialize call agent
}
}
func startCall() {
// Ask permissions
AVAudioSession.sharedInstance().requestRecordPermission { (granted) in
if granted {
// Add start call logic
}
}
}
func endCall() {
// Add end call logic
}
}
Objektmodell
Die folgenden Klassen und Schnittstellen befassen sich mit einigen der wichtigsten Features des Azure Communication Services Calling SDK:
Name | BESCHREIBUNG |
---|---|
CallClient |
CallClient ist der Haupteinstiegspunkt des Calling SDK. |
CallAgent |
CallAgent dient zum Starten und Verwalten von Anrufen. |
CommunicationTokenCredential |
CommunicationTokenCredential dient als tokengestützte Anmeldeinformation zum Instanziieren von CallAgent . |
CommunicationUserIdentifier |
CommunicationUserIdentifier wird zur Darstellung der Identität des Benutzers verwendet, die eine der folgenden Optionen sein kann: CommunicationUserIdentifier , PhoneNumberIdentifier oder CallingApplication. |
Authentifizieren des Clients
Initialisieren Sie eine CallAgent
-Instanz mit einem Benutzerzugriffs-Token, das es uns ermöglicht, Anrufe zu tätigen und zu empfangen.
Im folgenden Code müssen Sie <USER ACCESS TOKEN>
durch ein gültiges Benutzerzugriffs-Token für Ihre Ressource ersetzen. Wenn Sie noch über kein Token verfügen, finden Sie unter Benutzerzugriffstoken weitere Informationen.
Fügen Sie den folgenden Code zum onAppear
-Rückruf in ContentView.swift hinzu:
var userCredential: CommunicationTokenCredential?
do {
userCredential = try CommunicationTokenCredential(token: "<USER ACCESS TOKEN>")
} catch {
print("ERROR: It was not possible to create user credential.")
return
}
self.callClient = CallClient()
// Creates the call agent
self.callClient?.createCallAgent(userCredential: userCredential!) { (agent, error) in
if error != nil {
print("ERROR: It was not possible to create a call agent.")
return
}
else {
self.callAgent = agent
print("Call agent successfully created.")
}
}
Beginnen eines Anrufs
Die Methode startCall
wird als die Aktion festgelegt, die ausgeführt wird, wenn auf die Schaltfläche Start Call (Anruf starten) getippt wird. Aktualisieren Sie die Implementierung, um einen Anruf mit ASACallAgent
zu beginnen:
func startCall()
{
// Ask permissions
AVAudioSession.sharedInstance().requestRecordPermission { (granted) in
if granted {
// start call logic
let callees:[CommunicationIdentifier] = [MicrosoftTeamsAppIdentifier(self.callee)]
self.callAgent?.startCall(participants: callees, options: StartCallOptions()) { (call, error) in
if (error == nil) {
self.call = call
} else {
print("Failed to get call object")
}
}
}
}
}
Sie können auch die Eigenschaften in StartCallOptions
verwenden, um die Anfangsoptionen für den Anruf festzulegen (d. h. Sie können den Anruf mit stummgeschaltetem Mikrofon starten).
Beenden eines Anrufs
Implementieren Sie die Methode endCall
, um den aktuellen Anruf zu beenden, wenn auf die Schaltfläche End Call (Anruf beenden) getippt wird.
func endCall()
{
self.call!.hangUp(options: HangUpOptions()) { (error) in
if (error != nil) {
print("ERROR: It was not possible to hangup the call.")
}
}
}
Ausführen des Codes
Sie können Ihre App im iOS-Simulator erstellen und ausführen, indem Sie Produkt>Ausführen auswählen oder den Tastaturkurzbefehl (⌘-R) verwenden.
Hinweis
Wenn Sie zum ersten Mal einen Anruf tätigen, fordert das System Zugriff auf das Mikrofon an. Verwenden Sie in einer Produktionsanwendung die AVAudioSession
-API, um den Berechtigungsstatus zu überprüfen und das Verhalten Ihrer Anwendung entsprechend zu aktualisieren, wenn die Berechtigung nicht erteilt wird.
Manuelle Schritte zum Einrichten des Anrufs:
- Starten der App mit Xcode
- Geben Sie die ID des Anrufwarteschlangenobjekts ein (mit Präfix), und wählen Sie die Schaltfläche „Anruf starten“ aus. Die Anwendung wird den ausgehenden Aufruf an die Anrufwarteschlange mit der angegebenen Objekt-ID starten.
- Der Anruf ist mit der Anrufwarteschlange verbunden.
- Der Communication Services-Benutzer wird basierend auf der Konfiguration durch die Anrufwarteschlange weitergeleitet.
Wichtig
Dieses Feature von Azure Communication Services befindet sich derzeit in der Vorschau.
Vorschau-APIs und -SDKs werden ohne Vereinbarung zum Servicelevel bereitgestellt. Es wird empfohlen, diese nicht für Produktionsworkloads zu verwenden. Einige Features werden möglicherweise nicht unterstützt oder bieten nur eingeschränkte Funktionalität.
Weitere Informationen finden Sie in den ergänzenden Nutzungsbestimmungen für Microsoft Azure-Vorschauversionen.
In diesem Schnellstart werden Sie erfahren, wie Sie einen Anruf von einem Azure Communication Services-Benutzer an die Teams-Anrufwarteschlange starten. Sie werden dies mit den folgenden Schritten erreichen:
- Aktivieren Sie den Verbund der Azure Communication Services-Ressource mit dem Teams-Mandanten.
- Wählen oder erstellen Sie die Teams-Anrufwarteschlange über das Teams Admin Center.
- Rufen Sie die E-Mail-Adresse der Anrufwarteschlange über das Teams Admin Center ab.
- Rufen Sie die Objekt-ID der Anrufwarteschlange über die Graph-API ab.
- Starten Sie einen Anruf mit dem Anruf-SDK von Azure Communication Services.
Wenn Sie direkt zum Ende springen möchten, können Sie diese Schnellstartanleitung als Beispiel auf GitHub herunterladen.
Aktivieren der Interoperabilität in Ihrem Teams-Mandanten
Microsoft Entra-Benutzer mit der Teams-Administratorrolle können das PowerShell-Cmdlet mit dem MicrosoftTeams-Modul ausführen, um die Communication Services-Ressource im Mandanten zu aktivieren.
1. Vorbereiten des Microsoft Teams-Moduls
Öffnen Sie zunächst die PowerShell, und überprüfen Sie das Vorhandensein des Teams-Moduls mit dem folgenden Befehl:
Get-module *teams*
Wenn das MicrosoftTeams
-Modul nicht angezeigt wird, installieren Sie es zuerst. Um das Modul zu installieren, müssen Sie PowerShell als Administrator ausführen. Führen Sie dann den folgenden Befehl aus:
Install-Module -Name MicrosoftTeams
Sie werden über die Module informiert, die installiert werden, die Sie mit der Antwort Y
oder A
bestätigen können. Wenn das Modul installiert, aber veraltet ist, können Sie den folgenden Befehl ausführen, um das Modul zu aktualisieren:
Update-Module MicrosoftTeams
2. Herstellen einer Verbindung mit dem Microsoft Teams-Modul
Wenn das Modul installiert und bereit ist, können Sie mit dem folgenden Befehl eine Verbindung mit dem MicrosftTeams-Modul herstellen. Sie werden aufgefordert, sich mit einem interaktiven Fenster anzumelden. Das Benutzerkonto, das Sie verwenden möchten, muss über Teams-Administratorberechtigungen verfügen. Andernfalls erhalten Sie möglicherweise in den nächsten Schritten die Antwort access denied
.
Connect-MicrosoftTeams
3. Aktivieren der Mandantenkonfiguration
Die Interoperabilität mit Communication Services-Ressourcen wird über die Mandantenkonfiguration und die zugewiesene Richtlinie gesteuert. Der Teams-Mandant verfügt über eine einzelne Mandantenkonfiguration, und Teams-Benutzer*innen wurde eine globale Richtlinie oder eine benutzerdefinierte Richtlinie zugewiesen. Weitere Informationen finden Sie unter Zuweisen von Richtlinien in Teams.
Nach erfolgreicher Anmeldung können Sie das Cmdlet Set-CsTeamsAcsFederationConfiguration ausführen, um die Communication Services-Ressource in Ihrem Mandanten zu aktivieren. Ersetzen Sie den Text IMMUTABLE_RESOURCE_ID
durch eine unveränderliche Ressourcen-ID in Ihrer Kommunikationsressource. Weitere Informationen zum Abrufen dieser Informationen finden Sie hier.
$allowlist = @('IMMUTABLE_RESOURCE_ID')
Set-CsTeamsAcsFederationConfiguration -EnableAcsUsers $True -AllowedAcsResources $allowlist
4. Aktivieren der Mandantenrichtlinie
Jedem Teams-Benutzer wurde eine External Access Policy
zugewiesen, die festlegt, ob Communication Services-Benutzer*innen diese Teams-Benutzer*in bzw. diesen Teams-Benutzer aufrufen können. Verwenden Sie das Cmdlet Set-CsExternalAccessPolicy, um sicherzustellen, dass für die der Teams-Benutzer*in bzw. dem Teams-Benutzer zugewiesene Richtlinie EnableAcsFederationAccess
auf $true
festgelegt ist
Set-CsExternalAccessPolicy -Identity Global -EnableAcsFederationAccess $true
Erstellen oder Auswählen einer Teams-Anrufwarteschlange
Die Teams-Anrufwarteschlange ist ein Feature in Microsoft Teams, das eingehende Anrufe effizient an eine Gruppe von bestimmten Benutzern oder Agenten verteilt. Es ist nützlich für Kundensupport- oder Callcenterszenarien. Aufrufe werden in eine Warteschlange gestellt und dem nächsten verfügbaren Agenten basierend auf einer vordefinierten Routingmethode zugewiesen. Agenten erhalten Benachrichtigungen und können Anrufe mithilfe der Anrufsteuerelementen von Teams verarbeiten. Das Feature bietet Berichte und Analysen für die Leistungsnachverfolgung. Es vereinfacht die Anrufbehandlung, stellt eine konsistente Kundenerfahrung sicher und optimiert die Produktivität der Agenten. Sie können über das Teams Admin Center eine vorhandene Anrufwarteschlange auswählen oder eine neue erstellen.
Weitere Informationen zum Erstellen der Anrufwarteschlange mit dem Teams Admin Center finden Sie hier.
Objekt-ID für Anrufwarteschlange suchen
Nachdem die Anrufwarteschlange erstellt wurde, müssen wir die korrelierte Objekt-ID suchen, um sie später für Aufrufe verwenden zu können. Die Objekt-ID ist mit dem Ressourcenkonto verbunden, das an die Anrufwarteschlange angefügt wurde. Öffnen Sie die Registerkarte „Ressourcenkonten“ in Teams Admin, und suchen Sie nach der E-Mail. Alle erforderlichen Informationen zu Ressourcenkonten können im Microsoft Graph-Explorer gefunden werden, indem diese E-Mail in der Suche verwendet wird.
https://graph.microsoft.com/v1.0/users/lab-test2-cq-@contoso.com
In den Ergebnissen können wir das Feld „ID“ finden
"userPrincipalName": "lab-test2-cq@contoso.com",
"id": "31a011c2-2672-4dd0-b6f9-9334ef4999db"
Um sie in der Anruf-App zu verwenden, müssen wir dieser ID ein Präfix hinzufügen. Derzeit wird Folgendes unterstützt:
- Anrufwarteschleife in der öffentlichen Cloud:
28:orgid:<id>
- Anrufwarteschleife in der Government Cloud:
28:gcch:<id>
Voraussetzungen
Zum Durchführen dieses Tutorials benötigen Sie Folgendes:
Ein Azure-Konto mit einem aktiven Abonnement. Sie können kostenlos ein Konto erstellen.
Installieren Sie Visual Studio 2022 mit der Workload „Entwicklung für die universelle Windows-Plattform“.
Eine bereitgestellte Communication Services-Ressource. Erstellen Sie eine Communication Services-Ressource. Für diese Schnellstartanleitung müssen Sie Ihre Verbindungszeichenfolge erfassen.
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 identity token issue --scope voip --connection-string "yourConnectionString"
Ausführliche Informationen finden Sie unter Verwenden der Azure CLI zum Erstellen und Verwalten von Zugriffstoken.
Mindestunterstützung für Teams-Anrufanwendungen: 1.10.0-beta.1
Einrichten
Erstellen des Projekts
Erstellen Sie in Visual Studio ein neues Projekt mit der Vorlage Leere App (Universelle Windows-App) , um eine einseitige UWP-App (Universelle Windows-Plattform) einzurichten.
Installieren des Pakets
Klicken Sie mit der rechten Maustaste auf Ihr Projekt, und wechseln Sie zu Manage Nuget Packages
, um Azure.Communication.Calling.WindowsClient
1.4.0 oder höher zu installieren. Stellen Sie sicher, dass Include Prerelease
aktiviert ist, wenn Sie die Versionen für die öffentliche Vorschau anzeigen möchten.
Anfordern des Zugriffs
Wechseln Sie zu Package.appxmanifest
, und wählen Sie Capabilities
aus.
Aktivieren Sie Internet (Client)
und Internet (Client & Server)
, um ein- und ausgehenden Zugriff auf das Internet zu erhalten. Markieren Sie Microphone
, um auf den Audiofeed des Mikrofons zuzugreifen und Webcam
, um auf den Videofeed der Kamera zuzugreifen.
Einrichten des App-Frameworks
Wir müssen ein einfaches Layout konfigurieren, um unsere Logik anzufügen. Um einen ausgehenden Anruf zu tätigen, benötigen wir ein TextBox
-Element, um die Benutzer-ID des Angerufenen bereitzustellen. Außerdem benötigen wir die Schaltflächen Start/Join call
und Hang up
. In diesem Beispiel sind auch die Kontrollkästchen A Mute
und a BackgroundBlur
enthalten, um die Funktionen des Umschaltens von Audiozuständen und Videoeffekten zu veranschaulichen.
Öffnen Sie das MainPage.xaml
-Element Ihres Projekts, und fügen Sie Ihrer Page
den Knoten Grid
hinzu:
<Page
x:Class="CallingQuickstart.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:CallingQuickstart"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" Width="800" Height="600">
<!-- Don't forget to replace ‘CallingQuickstart’ with your project’s name -->
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="16*"/>
<RowDefinition Height="30*"/>
<RowDefinition Height="200*"/>
<RowDefinition Height="60*"/>
<RowDefinition Height="16*"/>
</Grid.RowDefinitions>
<TextBox Grid.Row="1" x:Name="CalleeTextBox" PlaceholderText="Who would you like to call?" TextWrapping="Wrap" VerticalAlignment="Center" Height="30" Margin="10,10,10,10" />
<Grid x:Name="AppTitleBar" Background="LightSeaGreen">
<TextBlock x:Name="QuickstartTitle" Text="Calling Quickstart sample title bar" Style="{StaticResource CaptionTextBlockStyle}" Padding="7,7,0,0"/>
</Grid>
<Grid Grid.Row="2">
<Grid.RowDefinitions>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<MediaPlayerElement x:Name="LocalVideo" HorizontalAlignment="Center" Stretch="UniformToFill" Grid.Column="0" VerticalAlignment="Center" AutoPlay="True" />
<MediaPlayerElement x:Name="RemoteVideo" HorizontalAlignment="Center" Stretch="UniformToFill" Grid.Column="1" VerticalAlignment="Center" AutoPlay="True" />
</Grid>
<StackPanel Grid.Row="3" Orientation="Vertical" Grid.RowSpan="2">
<StackPanel Orientation="Horizontal">
<Button x:Name="CallButton" Content="Start/Join call" Click="CallButton_Click" VerticalAlignment="Center" Margin="10,0,0,0" Height="40" Width="123"/>
<Button x:Name="HangupButton" Content="Hang up" Click="HangupButton_Click" VerticalAlignment="Center" Margin="10,0,0,0" Height="40" Width="123"/>
<CheckBox x:Name="MuteLocal" Content="Mute" Margin="10,0,0,0" Click="MuteLocal_Click" Width="74"/>
</StackPanel>
</StackPanel>
<TextBox Grid.Row="5" x:Name="Stats" Text="" TextWrapping="Wrap" VerticalAlignment="Center" Height="30" Margin="0,2,0,0" BorderThickness="2" IsReadOnly="True" Foreground="LightSlateGray" />
</Grid>
</Page>
Öffnen Sie MainPage.xaml.cs
, und ersetzen Sie den Inhalt durch folgende Implementierung:
using Azure.Communication.Calling.WindowsClient;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Threading.Tasks;
using Windows.ApplicationModel;
using Windows.ApplicationModel.Core;
using Windows.Media.Core;
using Windows.Networking.PushNotifications;
using Windows.UI;
using Windows.UI.ViewManagement;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
namespace CallingQuickstart
{
public sealed partial class MainPage : Page
{
private const string authToken = "<AUTHENTICATION_TOKEN>";
private CallClient callClient;
private CallTokenRefreshOptions callTokenRefreshOptions = new CallTokenRefreshOptions(false);
private CallAgent callAgent;
private CommunicationCall call;
private LocalOutgoingAudioStream micStream;
#region Page initialization
public MainPage()
{
this.InitializeComponent();
// Additional UI customization code goes here
}
protected override async void OnNavigatedTo(NavigationEventArgs e)
{
await InitCallAgentAndDeviceManagerAsync();
base.OnNavigatedTo(e);
}
#endregion
#region UI event handlers
private async void CallButton_Click(object sender, RoutedEventArgs e)
{
// Start a call
}
private async void HangupButton_Click(object sender, RoutedEventArgs e)
{
// Hang up a call
}
private async void MuteLocal_Click(object sender, RoutedEventArgs e)
{
// Toggle mute/unmute audio state of a call
}
#endregion
#region API event handlers
private async void OnIncomingCallAsync(object sender, IncomingCallReceivedEventArgs args)
{
// Handle incoming call event
}
private async void OnStateChangedAsync(object sender, PropertyChangedEventArgs args)
{
// Handle connected and disconnected state change of a call
}
#endregion
#region Helper methods
private async Task InitCallAgentAndDeviceManagerAsync()
{
//Initialize the call agent and search for devices
}
private async Task<CommunicationCall> StartCallAsync(string acsCallee)
{
// Start a call to an Azure Communication Services user using the CallAgent and the callee id
}
#endregion
}
}
Objektmodell
Die folgende Tabelle führt die Klassen und Schnittstellen auf, die sich mit einigen der wichtigsten Features des Calling SDK von Azure Communication Services befassen:
Name | BESCHREIBUNG |
---|---|
CallClient |
CallClient ist der Haupteinstiegspunkt des Calling SDK. |
CallAgent |
CallAgent dient zum Starten und Verwalten von Anrufen. |
CommunicationCall |
CommunicationCall wird verwendet, um einen laufenden Anruf zu verwalten. |
CallTokenCredential |
CallTokenCredential dient als tokengestützte Anmeldeinformation zum Instanziieren von CallAgent . |
CallIdentifier |
CallIdentifier wird zur Darstellung der Identität des Benutzers verwendet, die eine der folgenden Optionen sein kann: UserCallIdentifier oder PhoneNumberCallIdentifier usw. |
Authentifizieren des Clients
Initialisieren Sie eine CallAgent
-Instanz mit einem Benutzerzugriffs-Token, mit dem wir Anrufe tätigen und empfangen können, und rufen Sie optional eine DeviceManager-Instanz ab, um auf Client-Gerätekonfigurationen abzufragen.
Ersetzen Sie im folgenden Code <AUTHENTICATION_TOKEN>
durch ein Benutzerzugriffs-Token. Wenn Sie noch über kein Token verfügen, finden Sie in der Dokumentation zu Benutzerzugriffstoken weitere Informationen.
Fügen Sie die Funktion InitCallAgentAndDeviceManagerAsync
hinzu , die das SDK lädt. Dieses Hilfsprogramm kann an die Anforderungen Ihrer Anwendung angepasst werden.
private async Task InitCallAgentAndDeviceManagerAsync()
{
this.callClient = new CallClient(new CallClientOptions() {
Diagnostics = new CallDiagnosticsOptions() {
// make sure to put your project AppName
AppName = "CallingQuickstart",
AppVersion="1.0",
Tags = new[] { "Calling", "ACS", "Windows" }
}
});
// Set up local audio stream using the first mic enumerated
var deviceManager = await this.callClient.GetDeviceManagerAsync();
var mic = deviceManager?.Microphones?.FirstOrDefault();
micStream = new LocalOutgoingAudioStream();
var tokenCredential = new CallTokenCredential(authToken, callTokenRefreshOptions);
var callAgentOptions = new CallAgentOptions()
{
DisplayName = $"{Environment.MachineName}/{Environment.UserName}",
};
this.callAgent = await this.callClient.CreateCallAgentAsync(tokenCredential, callAgentOptions);
this.callAgent.IncomingCallReceived += OnIncomingCallAsync;
}
Starten des Anrufs
Sobald ein Objekt StartCallOptions
abgerufen wurde, kann CallAgent
zum Initiieren des ACS-Anrufs (Azure Communication Services) verwendet werden:
private async Task<CommunicationCall> StartCallAsync(string acsCallee)
{
var options = new StartCallOptions();
var call = await this.callAgent.StartCallAsync( new [] { new MicrosoftTeamsAppCallIdentifier(acsCallee) }, options);
return call;
}
Beenden eines Anrufs
Beenden Sie den aktuellen Anruf, nachdem auf die Schaltfläche Hang up
geklickt wurde. Fügen Sie die Implementierung zum „HangupButton_Click“ hinzu, um einen Anruf zu beenden, und beenden Sie die Vorschau und Videostreams.
private async void HangupButton_Click(object sender, RoutedEventArgs e)
{
var call = this.callAgent?.Calls?.FirstOrDefault();
if (call != null)
{
await call.HangUpAsync(new HangUpOptions() { ForEveryone = false });
}
}
Stummschalten/Lautschalten bei Audio
Schalten Sie das ausgehende Audio stumm, wenn auf die Schaltfläche Mute
geklickt wird. Fügen Sie die Implementierung zum „MuteLocal_Click“ hinzu, um den Aufruf stummzuschalten.
private async void MuteLocal_Click(object sender, RoutedEventArgs e)
{
var muteCheckbox = sender as CheckBox;
if (muteCheckbox != null)
{
var call = this.callAgent?.Calls?.FirstOrDefault();
if (call != null)
{
if ((bool)muteCheckbox.IsChecked)
{
await call.MuteOutgoingAudioAsync();
}
else
{
await call.UnmuteOutgoingAudioAsync();
}
}
// Update the UI to reflect the state
}
}
Annehmen eines eingehenden Anrufs
Die Ereignissenke IncomingCallReceived
ist im SDK-Bootstrap-Hilfsprogramm InitCallAgentAndDeviceManagerAsync
eingerichtet.
this.callAgent.IncomingCallReceived += OnIncomingCallAsync;
Die Anwendung hat die Möglichkeit, zu konfigurieren, wie der eingehende Anruf angenommen werden soll, z. B. Video- und Audiostreamtypen.
private async void OnIncomingCallAsync(object sender, IncomingCallReceivedEventArgs args)
{
var incomingCall = args.IncomingCall;
var acceptCallOptions = new AcceptCallOptions() { };
call = await incomingCall.AcceptAsync(acceptCallOptions);
call.StateChanged += OnStateChangedAsync;
}
Überwachen und Reagieren auf ein Anrufstatusänderungsereignis
Das Ereignis StateChanged
für das Objekt CommunicationCall
wird ausgelöst, wenn ein gerade ausgeführter Vorgang Transaktionen von einem Zustand in einen anderen aufruft. Der Anwendung wird die Möglichkeit geboten, die Zustandsänderungen auf der Benutzeroberfläche widerzuspiegeln oder Geschäftslogiken einzufügen.
private async void OnStateChangedAsync(object sender, PropertyChangedEventArgs args)
{
var call = sender as CommunicationCall;
if (call != null)
{
var state = call.State;
// Update the UI
switch (state)
{
case CallState.Connected:
{
await call.StartAudioAsync(micStream);
break;
}
case CallState.Disconnected:
{
call.StateChanged -= OnStateChangedAsync;
call.Dispose();
break;
}
default: break;
}
}
}
Ruftaste aktivieren
Sobald Callee ID
nicht null oder leer ist, können Sie einen Aufruf starten.
Der Aufrufstatus muss mithilfe der OnStateChangedAsync
-Aktion geändert werden.
private async void CallButton_Click(object sender, RoutedEventArgs e)
{
var callString = CalleeTextBox.Text.Trim();
if (!string.IsNullOrEmpty(callString))
{
call = await StartCallAsync(callString);
call.StateChanged += OnStateChangedAsync;
}
}
Ausführen des Codes
Sie können den Build in Visual Studio erstellen und den Code ausführen. Für Lösungsplattformen unterstützen wir ARM64
, x64
und x86
.
Manuelle Schritte zum Einrichten des Anrufs:
- Veröffentlichen Sie die App mithilfe von Visual Studio.
- Geben Sie die ID des Anrufwarteschlangenobjekts ein (mit Präfix), und wählen Sie die Schaltfläche „Anruf starten“ aus. Die Anwendung wird den ausgehenden Aufruf an die Anrufwarteschlange mit der angegebenen Objekt-ID starten.
- Der Anruf ist mit der Anrufwarteschlange verbunden.
- Der Communication Services-Benutzer wird basierend auf der Konfiguration durch die Anrufwarteschlange weitergeleitet.
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.
Nächste Schritte
Weitere Informationen finden Sie in den folgenden Artikeln:
- Erste Schritte mit der Benutzeroberfläche für Anrufe an Teams Voice Apps
- Informieren Sie sich über die Funktionen des Calling SDK.
- Informieren Sie sich über die Funktionsweise von Anrufen.