Udostępnij za pośrednictwem


Szybki start: dołączanie aplikacji wywołującej do kolejki wywołań usługi Teams

W tym przewodniku Szybki start dowiesz się, jak uruchomić wywołanie od użytkownika usług Azure Communication Services do kolejki połączeń usługi Teams. Zamierzasz to osiągnąć, wykonując następujące czynności:

  1. Włącz federację zasobów usług Azure Communication Services z dzierżawą usługi Teams.
  2. Wybierz lub utwórz kolejkę połączeń usługi Teams za pośrednictwem Centrum administracyjnego usługi Teams.
  3. Uzyskaj adres e-mail kolejki połączeń za pośrednictwem Centrum administracyjnego usługi Teams.
  4. Pobierz identyfikator obiektu kolejki wywołań za pośrednictwem interfejsu API programu Graph.
  5. Rozpocznij wywołanie za pomocą zestawu SDK wywołującego usługi Azure Communication Services.

Jeśli chcesz przejść do końca, możesz pobrać ten przewodnik Szybki start jako przykład w usłudze GitHub.

Włączanie współdziałania w dzierżawie usługi Teams

Użytkownik Firmy Microsoft Entra z rolą administratora usługi Teams może uruchamiać polecenie cmdlet programu PowerShell za pomocą modułu MicrosoftTeams, aby włączyć zasób usług komunikacyjnych w dzierżawie.

1. Przygotowanie modułu Microsoft Teams

Najpierw otwórz program PowerShell i zweryfikuj istnienie modułu Teams za pomocą następującego polecenia:

Get-module *teams* 

Jeśli moduł nie jest widoczny MicrosoftTeams , zainstaluj go najpierw. Aby zainstalować moduł, musisz uruchomić program PowerShell jako administrator. Uruchom następujące polecenie:

	Install-Module -Name MicrosoftTeams

Zostaniesz poinformowany o modułach, które zostaną zainstalowane, co można potwierdzić przy użyciu elementu Y lub A odpowiedzi. Jeśli moduł jest zainstalowany, ale jest nieaktualny, możesz uruchomić następujące polecenie, aby zaktualizować moduł:

	Update-Module MicrosoftTeams

2. Łączenie z modułem usługi Microsoft Teams

Gdy moduł jest zainstalowany i gotowy, możesz nawiązać połączenie z modułem MicrosoftTeams za pomocą następującego polecenia. Zostanie wyświetlony monit z interakcyjnym oknem, aby się zalogować. Konto użytkownika, którego będziesz używać, musi mieć uprawnienia administratora usługi Teams. W przeciwnym razie możesz uzyskać access denied odpowiedź w następnych krokach.

Connect-MicrosoftTeams

3. Włączanie konfiguracji dzierżawy

Współdziałanie z zasobami usług Communication Services jest kontrolowane za pośrednictwem konfiguracji dzierżawy i przypisanych zasad. Dzierżawa usługi Teams ma jedną konfigurację dzierżawy, a użytkownicy usługi Teams przypisyli zasady globalne lub zasady niestandardowe. Aby uzyskać więcej informacji, zobacz Przypisywanie zasad w usłudze Teams.

Po pomyślnym zalogowaniu można uruchomić polecenie cmdlet Set-CsTeamsAcsFederationConfiguration , aby włączyć zasób usług Communication Services w dzierżawie. Zastąp tekst IMMUTABLE_RESOURCE_ID niezmiennym identyfikatorem zasobu w zasobie komunikacyjnym. Więcej informacji na temat sposobu uzyskiwania tych informacji można znaleźć tutaj.

$allowlist = @('IMMUTABLE_RESOURCE_ID')
Set-CsTeamsAcsFederationConfiguration -EnableAcsUsers $True -AllowedAcsResources $allowlist

4. Włączanie zasad dzierżawy

Do każdego użytkownika usługi Teams przypisano element External Access Policy , który określa, czy użytkownicy usług Komunikacyjnych mogą wywoływać tego użytkownika usługi Teams. Użyj polecenia cmdlet Set-CsExternalAccessPolicy, aby upewnić się, że zasady przypisane do użytkownika usługi Teams mają ustawioną wartość EnableAcsFederationAccess$true

Set-CsExternalAccessPolicy -Identity Global -EnableAcsFederationAccess $true

Tworzenie lub wybieranie kolejki połączeń usługi Teams

Kolejka połączeń usługi Teams to funkcja w usłudze Microsoft Teams, która efektywnie dystrybuuje połączenia przychodzące między grupę wyznaczonych użytkowników lub agentów. Jest to przydatne w przypadku scenariuszy obsługi klienta lub centrum telefonicznego. Wywołania są umieszczane w kolejce i przypisywane do następnego dostępnego agenta na podstawie wstępnie określonej metody routingu. Agenci odbierają powiadomienia i mogą obsługiwać wywołania przy użyciu kontrolek wywołań usługi Teams. Funkcja oferuje raportowanie i analizę na potrzeby śledzenia wydajności. Upraszcza obsługę wywołań, zapewnia spójne środowisko klienta i optymalizuje produktywność agentów. Możesz wybrać istniejącą lub utworzyć nową kolejkę połączeń za pośrednictwem Centrum administracyjnego usługi Teams.

Dowiedz się więcej o sposobie tworzenia kolejki połączeń przy użyciu Centrum administracyjnego usługi Teams tutaj.

Znajdowanie identyfikatora obiektu dla kolejki wywołań

Po utworzeniu kolejki wywołań musimy znaleźć skorelowany identyfikator obiektu, aby użyć go później do wywołań. Identyfikator obiektu jest połączony z kontem zasobu dołączonym do kolejki wywołań — otwórz kartę Konta zasobów w administratorze usługi Teams i znajdź wiadomość e-mail. Zrzut ekranu przedstawiający konta zasobów w portalu administracyjnym usługi Teams. Wszystkie wymagane informacje dotyczące konta zasobu można znaleźć w Eksploratorze programu Microsoft Graph przy użyciu tej wiadomości e-mail w wyszukiwaniu.

https://graph.microsoft.com/v1.0/users/lab-test2-cq-@contoso.com

W wynikach będziemy mogli znaleźć pole "ID"

    "userPrincipalName": "lab-test2-cq@contoso.com",
    "id": "31a011c2-2672-4dd0-b6f9-9334ef4999db"

Wymagania wstępne

  • Uzyskaj konto platformy Azure z aktywną subskrypcją. Utwórz konto bezpłatnie.
  • Node.js wersji LTS Active LTS i Maintenance LTS (8.11.1 i 10.14.1)
  • Utwórz aktywny zasób usług komunikacyjnych. Utwórz zasób usług komunikacyjnych.

Konfigurowanie

Tworzenie nowej aplikacji Node.js

Otwórz terminal lub okno polecenia utwórz nowy katalog dla aplikacji i przejdź do katalogu.

mkdir calling-quickstart && cd calling-quickstart

Instalowanie pakietu

npm install Użyj polecenia , aby zainstalować zestaw SDK wywołujący usługi Azure Communication Services dla języka JavaScript.

Ważne

W tym przewodniku Szybki start jest używana wersja nextzestawu SDK wywołującego usługi Azure Communication Services.

npm install @azure/communication-common@next --save
npm install @azure/communication-calling@next --save

Konfigurowanie struktury aplikacji

Ten przewodnik Szybki start używa pakietu webpack do tworzenia pakietów zawartości aplikacji. Uruchom następujące polecenie, aby zainstalować webpackpakiety i webpack-cli webpack-dev-server npm i wyświetlić je jako zależności programistyczne w pliku package.json:

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

index.html Utwórz plik w katalogu głównym projektu. Użyjemy tego pliku do skonfigurowania podstawowego układu, który umożliwi użytkownikowi umieszczenie połączenia wideo 1:1.

Oto kod:

<!-- 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>

Usługa Azure Communication Services wywołująca model obiektów zestawu WEB SDK

Następujące klasy i interfejsy obsługują niektóre główne funkcje zestawu AZURE Communication Services Calling SDK:

Nazwa/nazwisko opis
CallClient Główny punkt wejścia do zestawu SDK wywołującego.
CallAgent Służy do uruchamiania wywołań i zarządzania nimi.
DeviceManager Służy do zarządzania urządzeniami multimedialnymi.
Call Służy do reprezentowania wywołania.
LocalVideoStream Służy do tworzenia lokalnego strumienia wideo dla urządzenia aparatu w systemie lokalnym.
RemoteParticipant Służy do reprezentowania uczestnika zdalnego w wywołaniu.
RemoteVideoStream Służy do reprezentowania zdalnego strumienia wideo z uczestnika zdalnego.

Utwórz plik w katalogu głównym projektu o nazwie client.js , aby zawierał logikę aplikacji na potrzeby tego przewodnika Szybki start. Dodaj następujący kod, aby client.js:

// 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 updates.
subscribeToCall = (call) => {
    try {
        // Inspect the initial call.id value.
        console.log(`Call Id: ${call.id}`);
        //Subscribe 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 updates.
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 remoteParticipant 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();
});

Dodawanie kodu serwera lokalnego webpack

Utwórz plik w katalogu głównym projektu o nazwie webpack.config.js zawierający logikę serwera lokalnego dla tego przewodnika Szybki start. Dodaj następujący kod, aby webpack.config.js:

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'
            ]
        }),
    ]
};

Uruchamianie kodu

Użyj polecenia , webpack-dev-server aby skompilować i uruchomić aplikację. Uruchom następujące polecenie, aby utworzyć pakiet hosta aplikacji na lokalnym serwerze internetowym:

npx webpack serve --config webpack.config.js

Ręczne kroki konfigurowania wywołania:

  1. Otwórz przeglądarkę i przejdź do strony http://localhost:8080/.
  2. Wprowadź prawidłowy token dostępu użytkownika. Zapoznaj się z dokumentacją tokenu dostępu użytkownika, jeśli nie masz jeszcze dostępnych tokenów dostępu do użycia.
  3. Kliknij przyciski "Zainicjuj agenta połączeń".
  4. Wprowadź identyfikator obiektu kolejki wywołań i wybierz przycisk "Uruchom wywołanie". Aplikacja uruchomi wywołanie wychodzące do kolejki wywołań z podanym identyfikatorem obiektu.
  5. Połączenie jest połączone z kolejką wywołań.
  6. Użytkownik usług Communication Services jest kierowany przez kolejkę wywołań na podstawie jego konfiguracji.

W tym przewodniku Szybki start dowiesz się, jak uruchomić wywołanie od użytkownika usług Azure Communication Services do kolejki połączeń usługi Teams. Zamierzasz to osiągnąć, wykonując następujące czynności:

  1. Włącz federację zasobów usług Azure Communication Services z dzierżawą usługi Teams.
  2. Wybierz lub utwórz kolejkę połączeń usługi Teams za pośrednictwem Centrum administracyjnego usługi Teams.
  3. Uzyskaj adres e-mail kolejki połączeń za pośrednictwem Centrum administracyjnego usługi Teams.
  4. Pobierz identyfikator obiektu kolejki wywołań za pośrednictwem interfejsu API programu Graph.
  5. Rozpocznij wywołanie za pomocą zestawu SDK wywołującego usługi Azure Communication Services.

Jeśli chcesz przejść do końca, możesz pobrać ten przewodnik Szybki start jako przykład w usłudze GitHub.

Włączanie współdziałania w dzierżawie usługi Teams

Użytkownik Firmy Microsoft Entra z rolą administratora usługi Teams może uruchamiać polecenie cmdlet programu PowerShell za pomocą modułu MicrosoftTeams, aby włączyć zasób usług komunikacyjnych w dzierżawie.

1. Przygotowanie modułu Microsoft Teams

Najpierw otwórz program PowerShell i zweryfikuj istnienie modułu Teams za pomocą następującego polecenia:

Get-module *teams* 

Jeśli moduł nie jest widoczny MicrosoftTeams , zainstaluj go najpierw. Aby zainstalować moduł, musisz uruchomić program PowerShell jako administrator. Uruchom następujące polecenie:

	Install-Module -Name MicrosoftTeams

Zostaniesz poinformowany o modułach, które zostaną zainstalowane, co można potwierdzić przy użyciu elementu Y lub A odpowiedzi. Jeśli moduł jest zainstalowany, ale jest nieaktualny, możesz uruchomić następujące polecenie, aby zaktualizować moduł:

	Update-Module MicrosoftTeams

2. Łączenie z modułem usługi Microsoft Teams

Gdy moduł jest zainstalowany i gotowy, możesz nawiązać połączenie z modułem MicrosoftTeams za pomocą następującego polecenia. Zostanie wyświetlony monit z interakcyjnym oknem, aby się zalogować. Konto użytkownika, którego będziesz używać, musi mieć uprawnienia administratora usługi Teams. W przeciwnym razie możesz uzyskać access denied odpowiedź w następnych krokach.

Connect-MicrosoftTeams

3. Włączanie konfiguracji dzierżawy

Współdziałanie z zasobami usług Communication Services jest kontrolowane za pośrednictwem konfiguracji dzierżawy i przypisanych zasad. Dzierżawa usługi Teams ma jedną konfigurację dzierżawy, a użytkownicy usługi Teams przypisyli zasady globalne lub zasady niestandardowe. Aby uzyskać więcej informacji, zobacz Przypisywanie zasad w usłudze Teams.

Po pomyślnym zalogowaniu można uruchomić polecenie cmdlet Set-CsTeamsAcsFederationConfiguration , aby włączyć zasób usług Communication Services w dzierżawie. Zastąp tekst IMMUTABLE_RESOURCE_ID niezmiennym identyfikatorem zasobu w zasobie komunikacyjnym. Więcej informacji na temat sposobu uzyskiwania tych informacji można znaleźć tutaj.

$allowlist = @('IMMUTABLE_RESOURCE_ID')
Set-CsTeamsAcsFederationConfiguration -EnableAcsUsers $True -AllowedAcsResources $allowlist

4. Włączanie zasad dzierżawy

Do każdego użytkownika usługi Teams przypisano element External Access Policy , który określa, czy użytkownicy usług Komunikacyjnych mogą wywoływać tego użytkownika usługi Teams. Użyj polecenia cmdlet Set-CsExternalAccessPolicy, aby upewnić się, że zasady przypisane do użytkownika usługi Teams mają ustawioną wartość EnableAcsFederationAccess$true

Set-CsExternalAccessPolicy -Identity Global -EnableAcsFederationAccess $true

Tworzenie lub wybieranie kolejki połączeń usługi Teams

Kolejka połączeń usługi Teams to funkcja w usłudze Microsoft Teams, która efektywnie dystrybuuje połączenia przychodzące między grupę wyznaczonych użytkowników lub agentów. Jest to przydatne w przypadku scenariuszy obsługi klienta lub centrum telefonicznego. Wywołania są umieszczane w kolejce i przypisywane do następnego dostępnego agenta na podstawie wstępnie określonej metody routingu. Agenci odbierają powiadomienia i mogą obsługiwać wywołania przy użyciu kontrolek wywołań usługi Teams. Funkcja oferuje raportowanie i analizę na potrzeby śledzenia wydajności. Upraszcza obsługę wywołań, zapewnia spójne środowisko klienta i optymalizuje produktywność agentów. Możesz wybrać istniejącą lub utworzyć nową kolejkę połączeń za pośrednictwem Centrum administracyjnego usługi Teams.

Dowiedz się więcej o sposobie tworzenia kolejki połączeń przy użyciu Centrum administracyjnego usługi Teams tutaj.

Znajdowanie identyfikatora obiektu dla kolejki wywołań

Po utworzeniu kolejki wywołań musimy znaleźć skorelowany identyfikator obiektu, aby użyć go później do wywołań. Identyfikator obiektu jest połączony z kontem zasobu dołączonym do kolejki wywołań — otwórz kartę Konta zasobów w administratorze usługi Teams i znajdź wiadomość e-mail. Zrzut ekranu przedstawiający konta zasobów w portalu administracyjnym usługi Teams. Wszystkie wymagane informacje dotyczące konta zasobu można znaleźć w Eksploratorze programu Microsoft Graph przy użyciu tej wiadomości e-mail w wyszukiwaniu.

https://graph.microsoft.com/v1.0/users/lab-test2-cq-@contoso.com

W wynikach będziemy mogli znaleźć pole "ID"

    "userPrincipalName": "lab-test2-cq@contoso.com",
    "id": "31a011c2-2672-4dd0-b6f9-9334ef4999db"

Aby użyć w wywołującej aplikacji, musimy dodać prefiks do tego identyfikatora. Obecnie obsługiwane są następujące elementy:

  • Kolejka wywołań chmury publicznej: 28:orgid:<id>
  • Kolejka połączeń w chmurze dla instytucji rządowych: 28:gcch:<id>

Wymagania wstępne

  • Konto platformy Azure z aktywną subskrypcją. Utwórz konto bezpłatnie.

  • Program Android Studio do tworzenia aplikacji systemu Android.

  • Wdrożony zasób usług komunikacyjnych. Utwórz zasób usług komunikacyjnych.

  • Token dostępu użytkownika dla usługi Azure Communication Service. Możesz również użyć interfejsu wiersza polecenia platformy Azure i uruchomić polecenie za pomocą parametry połączenia, aby utworzyć użytkownika i token dostępu.

    az communication identity token issue --scope voip --connection-string "yourConnectionString"
    

    Aby uzyskać szczegółowe informacje, zobacz Tworzenie tokenów dostępu za pomocą interfejsu wiersza polecenia platformy Azure i zarządzanie nimi.

  • Minimalna obsługa aplikacji wywołujących aplikację Teams: 2.12.0-beta.1

Konfigurowanie

Tworzenie aplikacji systemu Android z pustym działaniem

W programie Android Studio wybierz pozycję Uruchom nowy projekt programu Android Studio.

Zrzut ekranu przedstawiający przycisk

Wybierz szablon projektu "Puste widoki Działania" w obszarze "Telefon i tablet".

Zrzut ekranu przedstawiający opcję

Wybierz pozycję Minimalny zestaw SDK "API 26: Android 8.0 (Oreo)" lub nowszy.

Zrzut ekranu przedstawiający opcję

Instalowanie pakietu

Znajdź projekt settings.gradle.kts i upewnij się, że mavenCentral() znajduje się na liście repozytoriów w obszarze pluginManagement i dependencyResolutionManagement

pluginManagement {
    repositories {
    ...
        mavenCentral()
    ...
    }
}

dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
    ...
        mavenCentral()
    }
}

Następnie w kompilacji.gradle na poziomie modułu dodaj następujące wiersze do sekcji zależności i systemu Android

android {
    ...
    
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}

dependencies {
    ...
    implementation ("com.azure.android:azure-communication-calling:2.+")
    ...
}

Dodawanie uprawnień do manifestu aplikacji

Aby zażądać uprawnień wymaganych do wykonania wywołania, należy je zadeklarować w manifeście aplikacji (app/src/main/AndroidManifest.xml). Zastąp zawartość pliku następującym kodem:

    <?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>
    

Konfigurowanie układu aplikacji

Potrzebne są dwa dane wejściowe: wprowadzanie tekstu dla identyfikatora wywoływanego i przycisk do umieszczenia wywołania. Te dane wejściowe można dodawać za pośrednictwem projektanta lub edytując plik XML układu. Utwórz przycisk z identyfikatorem call_button i tekstem wejściowym callee_id. Przejdź do (app/src/main/res/layout/activity_main.xml) i zastąp zawartość pliku następującym kodem:

<?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>

Tworzenie szkieletu i powiązań głównego działania

Po utworzeniu układu można dodać powiązania, a także podstawowe szkielety działania. Działanie obsługuje żądanie uprawnień środowiska uruchomieniowego, tworzenie agenta wywołania i umieszczanie wywołania po naciśnięciu przycisku. Metoda onCreate jest zastępowana do wywoływania getAllPermissions i createAgent dodawania powiązań dla przycisku wywołania. To zdarzenie występuje tylko raz po utworzeniu działania. Aby uzyskać więcej informacji, onCreatezobacz przewodnik Understand the Activity Lifecycle (Omówienie cyklu życia działania).

Przejdź do MainActivity.java i zastąp zawartość następującym kodem:

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;
        }
        List<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));
    }
}

Żądanie uprawnień w czasie wykonywania

W przypadku systemu Android w wersji 6.0 lub nowszej (poziom interfejsu API 23) i targetSdkVersion 23 lub nowszej uprawnienia są przyznawane w czasie wykonywania zamiast podczas instalowania aplikacji. Aby można było go obsługiwać, getAllPermissions można zaimplementować wywołanie ActivityCompat.checkSelfPermission i ActivityCompat.requestPermissions dla każdego wymaganego uprawnienia.

/**
 * 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);
    }
}

Uwaga

Podczas projektowania aplikacji należy wziąć pod uwagę, kiedy należy zażądać tych uprawnień. Uprawnienia powinny być wymagane, ponieważ są potrzebne, a nie przed upływem czasu. Aby uzyskać więcej informacji, zobacz Przewodnik po uprawnieniach systemu Android.

Model obiektów

Następujące klasy i interfejsy obsługują niektóre główne funkcje zestawu AZURE Communication Services Calling SDK:

Nazwa/nazwisko opis
CallClient Jest CallClient to główny punkt wejścia do zestawu SDK wywołującego.
CallAgent Służy do uruchamiania CallAgent wywołań i zarządzania nimi.
CommunicationTokenCredential Element CommunicationTokenCredential jest używany jako poświadczenie tokenu w celu utworzenia wystąpienia elementu CallAgent.
CommunicationIdentifier Element CommunicationIdentifier jest używany jako inny typ uczestnika, który może być częścią połączenia.

Tworzenie agenta na podstawie tokenu dostępu użytkownika

Za pomocą tokenu użytkownika można utworzyć wystąpienie uwierzytelnionego agenta wywołania. Zazwyczaj ten token jest generowany na podstawie usługi z uwierzytelnianiem specyficznym dla aplikacji. Aby uzyskać więcej informacji na temat tokenów dostępu użytkowników, zapoznaj się z przewodnikiem Tokeny dostępu użytkowników.

W tym przewodniku Szybki start zastąp <User_Access_Token> ciąg tokenem dostępu użytkownika wygenerowanym dla zasobu usługi Azure Communication Service.


/**
 * 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();
    }
}

Uruchamianie kodu

Aplikację można teraz uruchomić przy użyciu przycisku "Uruchom aplikację" na pasku narzędzi.

Ręczne kroki konfigurowania wywołania:

  1. Uruchom aplikację przy użyciu programu Android Studio.
  2. Wprowadź identyfikator obiektu kolejki wywołań (z prefiksem) i wybierz przycisk "Rozpocznij połączenie". Aplikacja uruchomi wywołanie wychodzące do kolejki wywołań z danym identyfikatorem obiektu.
  3. Połączenie jest połączone z kolejką wywołań.
  4. Użytkownik usług Communication Services jest kierowany przez kolejkę wywołań na podstawie jego konfiguracji.

W tym przewodniku Szybki start dowiesz się, jak uruchomić wywołanie od użytkownika usług Azure Communication Services do kolejki połączeń usługi Teams. Zamierzasz to osiągnąć, wykonując następujące czynności:

  1. Włącz federację zasobów usług Azure Communication Services z dzierżawą usługi Teams.
  2. Wybierz lub utwórz kolejkę połączeń usługi Teams za pośrednictwem Centrum administracyjnego usługi Teams.
  3. Uzyskaj adres e-mail kolejki połączeń za pośrednictwem Centrum administracyjnego usługi Teams.
  4. Pobierz identyfikator obiektu kolejki wywołań za pośrednictwem interfejsu API programu Graph.
  5. Rozpocznij wywołanie za pomocą zestawu SDK wywołującego usługi Azure Communication Services.

Jeśli chcesz przejść do końca, możesz pobrać ten przewodnik Szybki start jako przykład w usłudze GitHub.

Włączanie współdziałania w dzierżawie usługi Teams

Użytkownik Firmy Microsoft Entra z rolą administratora usługi Teams może uruchamiać polecenie cmdlet programu PowerShell za pomocą modułu MicrosoftTeams, aby włączyć zasób usług komunikacyjnych w dzierżawie.

1. Przygotowanie modułu Microsoft Teams

Najpierw otwórz program PowerShell i zweryfikuj istnienie modułu Teams za pomocą następującego polecenia:

Get-module *teams* 

Jeśli moduł nie jest widoczny MicrosoftTeams , zainstaluj go najpierw. Aby zainstalować moduł, musisz uruchomić program PowerShell jako administrator. Uruchom następujące polecenie:

	Install-Module -Name MicrosoftTeams

Zostaniesz poinformowany o modułach, które zostaną zainstalowane, co można potwierdzić przy użyciu elementu Y lub A odpowiedzi. Jeśli moduł jest zainstalowany, ale jest nieaktualny, możesz uruchomić następujące polecenie, aby zaktualizować moduł:

	Update-Module MicrosoftTeams

2. Łączenie z modułem usługi Microsoft Teams

Gdy moduł jest zainstalowany i gotowy, możesz nawiązać połączenie z modułem MicrosoftTeams za pomocą następującego polecenia. Zostanie wyświetlony monit z interakcyjnym oknem, aby się zalogować. Konto użytkownika, którego będziesz używać, musi mieć uprawnienia administratora usługi Teams. W przeciwnym razie możesz uzyskać access denied odpowiedź w następnych krokach.

Connect-MicrosoftTeams

3. Włączanie konfiguracji dzierżawy

Współdziałanie z zasobami usług Communication Services jest kontrolowane za pośrednictwem konfiguracji dzierżawy i przypisanych zasad. Dzierżawa usługi Teams ma jedną konfigurację dzierżawy, a użytkownicy usługi Teams przypisyli zasady globalne lub zasady niestandardowe. Aby uzyskać więcej informacji, zobacz Przypisywanie zasad w usłudze Teams.

Po pomyślnym zalogowaniu można uruchomić polecenie cmdlet Set-CsTeamsAcsFederationConfiguration , aby włączyć zasób usług Communication Services w dzierżawie. Zastąp tekst IMMUTABLE_RESOURCE_ID niezmiennym identyfikatorem zasobu w zasobie komunikacyjnym. Więcej informacji na temat sposobu uzyskiwania tych informacji można znaleźć tutaj.

$allowlist = @('IMMUTABLE_RESOURCE_ID')
Set-CsTeamsAcsFederationConfiguration -EnableAcsUsers $True -AllowedAcsResources $allowlist

4. Włączanie zasad dzierżawy

Do każdego użytkownika usługi Teams przypisano element External Access Policy , który określa, czy użytkownicy usług Komunikacyjnych mogą wywoływać tego użytkownika usługi Teams. Użyj polecenia cmdlet Set-CsExternalAccessPolicy, aby upewnić się, że zasady przypisane do użytkownika usługi Teams mają ustawioną wartość EnableAcsFederationAccess$true

Set-CsExternalAccessPolicy -Identity Global -EnableAcsFederationAccess $true

Tworzenie lub wybieranie kolejki połączeń usługi Teams

Kolejka połączeń usługi Teams to funkcja w usłudze Microsoft Teams, która efektywnie dystrybuuje połączenia przychodzące między grupę wyznaczonych użytkowników lub agentów. Jest to przydatne w przypadku scenariuszy obsługi klienta lub centrum telefonicznego. Wywołania są umieszczane w kolejce i przypisywane do następnego dostępnego agenta na podstawie wstępnie określonej metody routingu. Agenci odbierają powiadomienia i mogą obsługiwać wywołania przy użyciu kontrolek wywołań usługi Teams. Funkcja oferuje raportowanie i analizę na potrzeby śledzenia wydajności. Upraszcza obsługę wywołań, zapewnia spójne środowisko klienta i optymalizuje produktywność agentów. Możesz wybrać istniejącą lub utworzyć nową kolejkę połączeń za pośrednictwem Centrum administracyjnego usługi Teams.

Dowiedz się więcej o sposobie tworzenia kolejki połączeń przy użyciu Centrum administracyjnego usługi Teams tutaj.

Znajdowanie identyfikatora obiektu dla kolejki wywołań

Po utworzeniu kolejki wywołań musimy znaleźć skorelowany identyfikator obiektu, aby użyć go później do wywołań. Identyfikator obiektu jest połączony z kontem zasobu dołączonym do kolejki wywołań — otwórz kartę Konta zasobów w administratorze usługi Teams i znajdź wiadomość e-mail. Zrzut ekranu przedstawiający konta zasobów w portalu administracyjnym usługi Teams. Wszystkie wymagane informacje dotyczące konta zasobu można znaleźć w Eksploratorze programu Microsoft Graph przy użyciu tej wiadomości e-mail w wyszukiwaniu.

https://graph.microsoft.com/v1.0/users/lab-test2-cq-@contoso.com

W wynikach będziemy mogli znaleźć pole "ID"

    "userPrincipalName": "lab-test2-cq@contoso.com",
    "id": "31a011c2-2672-4dd0-b6f9-9334ef4999db"

Aby użyć w wywołującej aplikacji, musimy dodać prefiks do tego identyfikatora. Obecnie obsługiwane są następujące elementy:

  • Kolejka wywołań chmury publicznej: 28:orgid:<id>
  • Kolejka połączeń w chmurze dla instytucji rządowych: 28:gcch:<id>

Wymagania wstępne

  • Uzyskaj konto platformy Azure z aktywną subskrypcją. Utwórz konto bezpłatnie.

  • Komputer Mac z uruchomionym programem Xcode wraz z prawidłowym certyfikatem dewelopera zainstalowanym w pęku kluczy.

  • Wdrożony zasób usług komunikacyjnych. Utwórz zasób usług komunikacyjnych. Musisz zarejestrować parametry połączenia na potrzeby tego przewodnika Szybki start.

  • Token dostępu użytkownika dla usługi Azure Communication Service. Możesz również użyć interfejsu wiersza polecenia platformy Azure i uruchomić polecenie za pomocą parametry połączenia, aby utworzyć użytkownika i token dostępu.

    az communication identity token issue --scope voip --connection-string "yourConnectionString"
    

    Aby uzyskać szczegółowe informacje, zobacz Tworzenie tokenów dostępu za pomocą interfejsu wiersza polecenia platformy Azure i zarządzanie nimi.

  • Minimalna obsługa aplikacji wywołujących aplikację Teams: 2.15.0

Konfigurowanie

Tworzenie projektu Xcode

W programie Xcode utwórz nowy projekt systemu iOS i wybierz szablon Aplikacja . W tym samouczku jest używana struktura SwiftUI, dlatego należy ustawić język na swift i interfejs użytkownika na swiftUI. Podczas tego przewodnika Szybki start nie utworzysz testów. Możesz usunąć zaznaczenie pola wyboru Uwzględnij testy.

Zrzut ekranu przedstawiający okno Nowy projekt w programie Xcode.

Instalowanie pakietu i zależności za pomocą narzędzia CocoaPods

  1. Aby utworzyć plik Podfile dla aplikacji, otwórz terminal i przejdź do folderu projektu i uruchom polecenie:

    pod init

  2. Dodaj następujący kod do pliku Podfile i zapisz (upewnij się, że element "target" jest zgodny z nazwą projektu):

    platform :ios, '13.0'
    use_frameworks!
    
    target 'AzureCommunicationCallingSample' do
      pod 'AzureCommunicationCalling', '~> 2.15.0'
    end
    
  3. Uruchom program pod install.

  4. Otwórz plik za .xcworkspace pomocą programu Xcode.

Żądanie dostępu do mikrofonu

Aby uzyskać dostęp do mikrofonu urządzenia, należy zaktualizować listę właściwości informacji aplikacji za pomocą elementu NSMicrophoneUsageDescription. Skojarzona wartość została ustawiona na string wartość, która została uwzględniona w oknie dialogowym używanym przez system do żądania dostępu od użytkownika.

Kliknij prawym przyciskiem myszy Info.plist wpis drzewa projektu i wybierz pozycję Otwórz jako>kod źródłowy. Dodaj następujące wiersze sekcji najwyższego poziomu <dict> , a następnie zapisz plik.

<key>NSMicrophoneUsageDescription</key>
<string>Need microphone access for VOIP calling.</string>

Konfigurowanie struktury aplikacji

Otwórz plik ContentView.swift projektu i dodaj deklarację import na początku pliku, aby zaimportować AzureCommunicationCalling libraryplik . Ponadto zaimportuj AVFoundationplik , potrzebujemy tego kodu do żądania uprawnień dźwięku w kodzie.

import AzureCommunicationCalling
import AVFoundation

Zastąp implementację ContentView struktury prostymi kontrolkami interfejsu użytkownika, które umożliwiają użytkownikowi zainicjowanie i zakończenie wywołania. Dołączamy logikę biznesową do tych kontrolek w tym przewodniku Szybki start.

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
    }
}

Model obiektów

Następujące klasy i interfejsy obsługują niektóre główne funkcje zestawu AZURE Communication Services Calling SDK:

Nazwa/nazwisko opis
CallClient Jest CallClient to główny punkt wejścia do zestawu SDK wywołującego.
CallAgent Służy do uruchamiania CallAgent wywołań i zarządzania nimi.
CommunicationTokenCredential Element CommunicationTokenCredential jest używany jako poświadczenie tokenu w celu utworzenia wystąpienia elementu CallAgent.
CommunicationUserIdentifier Element CommunicationUserIdentifier służy do reprezentowania tożsamości użytkownika, która może być jedną z następujących opcji: CommunicationUserIdentifier,PhoneNumberIdentifier lub CallingApplication.

Uwierzytelnianie użytkownika

Zainicjuj CallAgent wystąpienie przy użyciu tokenu dostępu użytkownika, co umożliwia wykonywanie i odbieranie wywołań.

W poniższym kodzie należy zastąpić <USER ACCESS TOKEN> prawidłowym tokenem dostępu użytkownika dla zasobu. Jeśli nie masz jeszcze dostępnego tokenu dostępu, zapoznaj się z dokumentacją tokenu dostępu użytkownika.

Dodaj następujący kod do wywołania zwrotnego w pliku onAppear ContentView.swift:

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.")
    }
}

Rozpoczynanie rozmowy

Metoda startCall jest ustawiana jako akcja wykonywana po naciśnięciu przycisku Uruchom wywołanie . Zaktualizuj implementację, aby rozpocząć wywołanie za pomocą polecenia ASACallAgent:

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")
                }
            }
        }
    }
}

Można również użyć właściwości w , StartCallOptions aby ustawić początkowe opcje wywołania (czyli umożliwia uruchomienie wywołania za pomocą mikrofonu wyciszonego).

Kończ połączenie

Zaimplementuj metodę endCall , aby zakończyć bieżące wywołanie po naciśnięciu przycisku Zakończ wywołanie .

func endCall()
{    
    self.call!.hangUp(options: HangUpOptions()) { (error) in
        if (error != nil) {
            print("ERROR: It was not possible to hangup the call.")
        }
    }
}

Uruchamianie kodu

Aplikację można skompilować i uruchomić w symulatorze systemu iOS, wybierając pozycję Uruchom produkt>lub za pomocą skrótu klawiaturowego (⌘-R).

Uwaga

Po pierwszym wywołaniu system wyświetli monit o dostęp do mikrofonu. W aplikacji produkcyjnej należy użyć interfejsu AVAudioSession API, aby sprawdzić stan uprawnień i bezpiecznie zaktualizować zachowanie aplikacji, gdy nie udzielono uprawnień.

Ręczne kroki konfigurowania wywołania:

  1. Uruchamianie aplikacji przy użyciu środowiska Xcode
  2. Wprowadź identyfikator obiektu kolejki wywołań (z prefiksem) i wybierz przycisk "Rozpocznij połączenie". Aplikacja uruchomi wywołanie wychodzące do kolejki wywołań z danym identyfikatorem obiektu.
  3. Połączenie jest połączone z kolejką wywołań.
  4. Użytkownik usług Communication Services jest kierowany przez kolejkę wywołań na podstawie jego konfiguracji.

W tym przewodniku Szybki start dowiesz się, jak uruchomić wywołanie od użytkownika usług Azure Communication Services do kolejki połączeń usługi Teams. Zamierzasz to osiągnąć, wykonując następujące czynności:

  1. Włącz federację zasobów usług Azure Communication Services z dzierżawą usługi Teams.
  2. Wybierz lub utwórz kolejkę połączeń usługi Teams za pośrednictwem Centrum administracyjnego usługi Teams.
  3. Uzyskaj adres e-mail kolejki połączeń za pośrednictwem Centrum administracyjnego usługi Teams.
  4. Pobierz identyfikator obiektu kolejki wywołań za pośrednictwem interfejsu API programu Graph.
  5. Rozpocznij wywołanie za pomocą zestawu SDK wywołującego usługi Azure Communication Services.

Jeśli chcesz przejść do końca, możesz pobrać ten przewodnik Szybki start jako przykład w usłudze GitHub.

Włączanie współdziałania w dzierżawie usługi Teams

Użytkownik Firmy Microsoft Entra z rolą administratora usługi Teams może uruchamiać polecenie cmdlet programu PowerShell za pomocą modułu MicrosoftTeams, aby włączyć zasób usług komunikacyjnych w dzierżawie.

1. Przygotowanie modułu Microsoft Teams

Najpierw otwórz program PowerShell i zweryfikuj istnienie modułu Teams za pomocą następującego polecenia:

Get-module *teams* 

Jeśli moduł nie jest widoczny MicrosoftTeams , zainstaluj go najpierw. Aby zainstalować moduł, musisz uruchomić program PowerShell jako administrator. Uruchom następujące polecenie:

	Install-Module -Name MicrosoftTeams

Zostaniesz poinformowany o modułach, które zostaną zainstalowane, co można potwierdzić przy użyciu elementu Y lub A odpowiedzi. Jeśli moduł jest zainstalowany, ale jest nieaktualny, możesz uruchomić następujące polecenie, aby zaktualizować moduł:

	Update-Module MicrosoftTeams

2. Łączenie z modułem usługi Microsoft Teams

Gdy moduł jest zainstalowany i gotowy, możesz nawiązać połączenie z modułem MicrosoftTeams za pomocą następującego polecenia. Zostanie wyświetlony monit z interakcyjnym oknem, aby się zalogować. Konto użytkownika, którego będziesz używać, musi mieć uprawnienia administratora usługi Teams. W przeciwnym razie możesz uzyskać access denied odpowiedź w następnych krokach.

Connect-MicrosoftTeams

3. Włączanie konfiguracji dzierżawy

Współdziałanie z zasobami usług Communication Services jest kontrolowane za pośrednictwem konfiguracji dzierżawy i przypisanych zasad. Dzierżawa usługi Teams ma jedną konfigurację dzierżawy, a użytkownicy usługi Teams przypisyli zasady globalne lub zasady niestandardowe. Aby uzyskać więcej informacji, zobacz Przypisywanie zasad w usłudze Teams.

Po pomyślnym zalogowaniu można uruchomić polecenie cmdlet Set-CsTeamsAcsFederationConfiguration , aby włączyć zasób usług Communication Services w dzierżawie. Zastąp tekst IMMUTABLE_RESOURCE_ID niezmiennym identyfikatorem zasobu w zasobie komunikacyjnym. Więcej informacji na temat sposobu uzyskiwania tych informacji można znaleźć tutaj.

$allowlist = @('IMMUTABLE_RESOURCE_ID')
Set-CsTeamsAcsFederationConfiguration -EnableAcsUsers $True -AllowedAcsResources $allowlist

4. Włączanie zasad dzierżawy

Do każdego użytkownika usługi Teams przypisano element External Access Policy , który określa, czy użytkownicy usług Komunikacyjnych mogą wywoływać tego użytkownika usługi Teams. Użyj polecenia cmdlet Set-CsExternalAccessPolicy, aby upewnić się, że zasady przypisane do użytkownika usługi Teams mają ustawioną wartość EnableAcsFederationAccess$true

Set-CsExternalAccessPolicy -Identity Global -EnableAcsFederationAccess $true

Tworzenie lub wybieranie kolejki połączeń usługi Teams

Kolejka połączeń usługi Teams to funkcja w usłudze Microsoft Teams, która efektywnie dystrybuuje połączenia przychodzące między grupę wyznaczonych użytkowników lub agentów. Jest to przydatne w przypadku scenariuszy obsługi klienta lub centrum telefonicznego. Wywołania są umieszczane w kolejce i przypisywane do następnego dostępnego agenta na podstawie wstępnie określonej metody routingu. Agenci odbierają powiadomienia i mogą obsługiwać wywołania przy użyciu kontrolek wywołań usługi Teams. Funkcja oferuje raportowanie i analizę na potrzeby śledzenia wydajności. Upraszcza obsługę wywołań, zapewnia spójne środowisko klienta i optymalizuje produktywność agentów. Możesz wybrać istniejącą lub utworzyć nową kolejkę połączeń za pośrednictwem Centrum administracyjnego usługi Teams.

Dowiedz się więcej o sposobie tworzenia kolejki połączeń przy użyciu Centrum administracyjnego usługi Teams tutaj.

Znajdowanie identyfikatora obiektu dla kolejki wywołań

Po utworzeniu kolejki wywołań musimy znaleźć skorelowany identyfikator obiektu, aby użyć go później do wywołań. Identyfikator obiektu jest połączony z kontem zasobu dołączonym do kolejki wywołań — otwórz kartę Konta zasobów w administratorze usługi Teams i znajdź wiadomość e-mail. Zrzut ekranu przedstawiający konta zasobów w portalu administracyjnym usługi Teams. Wszystkie wymagane informacje dotyczące konta zasobu można znaleźć w Eksploratorze programu Microsoft Graph przy użyciu tej wiadomości e-mail w wyszukiwaniu.

https://graph.microsoft.com/v1.0/users/lab-test2-cq-@contoso.com

W wynikach będziemy mogli znaleźć pole "ID"

    "userPrincipalName": "lab-test2-cq@contoso.com",
    "id": "31a011c2-2672-4dd0-b6f9-9334ef4999db"

Aby użyć w wywołującej aplikacji, musimy dodać prefiks do tego identyfikatora. Obecnie obsługiwane są następujące elementy:

  • Kolejka wywołań chmury publicznej: 28:orgid:<id>
  • Kolejka połączeń w chmurze dla instytucji rządowych: 28:gcch:<id>

Wymagania wstępne

Do wykonania kroków tego samouczka niezbędne jest spełnienie następujących wymagań wstępnych:

  • Konto platformy Azure z aktywną subskrypcją. Utwórz konto bezpłatnie.

  • Zainstaluj program Visual Studio 2022 z pakietem roboczym programowania platforma uniwersalna systemu Windows.

  • Wdrożony zasób usług komunikacyjnych. Utwórz zasób usług komunikacyjnych. Musisz zarejestrować parametry połączenia na potrzeby tego przewodnika Szybki start.

  • Token dostępu użytkownika dla usługi Azure Communication Service. Możesz również użyć interfejsu wiersza polecenia platformy Azure i uruchomić polecenie za pomocą parametry połączenia, aby utworzyć użytkownika i token dostępu.

    az communication identity token issue --scope voip --connection-string "yourConnectionString"
    

    Aby uzyskać szczegółowe informacje, zobacz Tworzenie tokenów dostępu za pomocą interfejsu wiersza polecenia platformy Azure i zarządzanie nimi.

  • Minimalna obsługa aplikacji wywołujących aplikacje teams: 1.11.0

Konfigurowanie

Tworzenie projektu

W programie Visual Studio utwórz nowy projekt przy użyciu szablonu Pusta aplikacja (uniwersalny system Windows), aby skonfigurować jednostronicową aplikację platforma uniwersalna systemu Windows (UWP).

Zrzut ekranu przedstawiający okno Nowy projekt platformy UWP w programie Visual Studio.

Instalowanie pakietu

Wybierz projekt prawym przyciskiem i przejdź do Manage Nuget Packages strony , aby zainstalować Azure.Communication.Calling.WindowsClient 1.4.0 lub superior. Sprawdź, Include Prerelease czy chcesz wyświetlić wersje publicznej wersji zapoznawczej.

Żądanie dostępu

Przejdź do Package.appxmanifest strony i wybierz pozycję Capabilities. Sprawdź Internet (Client) i Internet (Client & Server) , aby uzyskać dostęp przychodzący i wychodzący do Internetu. Sprawdź Microphone , czy chcesz uzyskać dostęp do kanału audio mikrofonu i Webcam uzyskać dostęp do kanału informacyjnego wideo aparatu.

Zrzut ekranu przedstawiający żądanie dostępu do Internetu i mikrofonu w programie Visual Studio.

Konfigurowanie struktury aplikacji

Musimy skonfigurować podstawowy układ, aby dołączyć naszą logikę. Aby umieścić wywołanie wychodzące, musimy TextBox podać identyfikator użytkownika wywoływanego. Potrzebujemy Start/Join call również przycisku i Hang up przycisku. Pola Mute wyboru i BackgroundBlur są również uwzględnione w tym przykładzie, aby zademonstrować funkcje przełączania stanów dźwięku i efektów wideo.

MainPage.xaml Otwórz projekt i dodaj Grid węzeł do pliku Page:

<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>

Otwórz plik MainPage.xaml.cs i zastąp zawartość następującą implementacją:

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
    }
}

Model obiektów

W następnej tabeli wymieniono klasy i interfejsy obsługujące niektóre główne funkcje zestawu SDK wywołującego usługi Azure Communication Services:

Nazwa/nazwisko opis
CallClient Jest CallClient to główny punkt wejścia do zestawu SDK wywołującego.
CallAgent Służy do uruchamiania CallAgent wywołań i zarządzania nimi.
CommunicationCall Służy CommunicationCall do zarządzania trwającym połączeniem.
CallTokenCredential Element CallTokenCredential jest używany jako poświadczenie tokenu w celu utworzenia wystąpienia elementu CallAgent.
CallIdentifier Element CallIdentifier służy do reprezentowania tożsamości użytkownika, która może być jedną z następujących opcji: UserCallIdentifier, PhoneNumberCallIdentifier itp.

Uwierzytelnianie użytkownika

Zainicjuj CallAgent wystąpienie przy użyciu tokenu dostępu użytkownika, które umożliwia nam wykonywanie i odbieranie wywołań, a opcjonalnie uzyskiwanie wystąpienia deviceManager w celu wykonywania zapytań dotyczących konfiguracji urządzeń klienckich.

W kodzie zastąp <AUTHENTICATION_TOKEN> element tokenem dostępu użytkownika. Jeśli nie masz jeszcze dostępnego tokenu dostępu, zapoznaj się z dokumentacją tokenu dostępu użytkownika.

Dodaj InitCallAgentAndDeviceManagerAsync funkcję , która uruchamia zestaw SDK. Ten pomocnik można dostosować w celu spełnienia wymagań aplikacji.

        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;
        }

Uruchamianie połączenia

StartCallOptions Po uzyskaniu CallAgent obiektu można go użyć do zainicjowania wywołania usług Azure Communication Services:

        private async Task<CommunicationCall> StartCallAsync(string acsCallee)
        {
            var options = new StartCallOptions();
            var call = await this.callAgent.StartCallAsync( new [] { new MicrosoftTeamsAppCallIdentifier(acsCallee) }, options);
            return call;
        }

Kończ połączenie

Zakończ bieżące wywołanie po kliknięciu Hang up przycisku. Dodaj implementację do HangupButton_Click, aby zakończyć wywołanie, i zatrzymać podgląd i strumienie wideo.

        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 });
            }
        }

Przełączanie wyciszenia/odłączania dźwięku

Wycisz wychodzący dźwięk po kliknięciu Mute przycisku. Dodaj implementację do MuteLocal_Click, aby wyciszyć wywołanie.

        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
            }
        }

Akceptowanie połączenia przychodzącego

IncomingCallReceived Ujście zdarzeń jest konfigurowane w pomocniku InitCallAgentAndDeviceManagerAsyncbootstrap zestawu SDK.

    this.callAgent.IncomingCallReceived += OnIncomingCallAsync;

Aplikacja ma możliwość skonfigurowania sposobu akceptowania połączenia przychodzącego, takiego jak rodzaje strumieni wideo i audio.

        private async void OnIncomingCallAsync(object sender, IncomingCallReceivedEventArgs args)
        {
            var incomingCall = args.IncomingCall;

            var acceptCallOptions = new AcceptCallOptions() { };

            call = await incomingCall.AcceptAsync(acceptCallOptions);
            call.StateChanged += OnStateChangedAsync;
        }

Monitorowanie zdarzenia zmiany stanu i reagowanie na nie

StateChanged zdarzenie na CommunicationCall obiekcie jest wyzwalane, gdy transakcje wywołania w toku z jednego stanu do innego. Aplikacja oferuje możliwości odzwierciedlenia zmian stanu w interfejsie użytkownika lub wstawiania logiki biznesowej.

        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;
                }
            }
        }

Wykonaj pracę przycisku połączenia

Gdy parametr Callee ID nie ma wartości null lub jest pusty, możesz uruchomić wywołanie.

Stan wywołania musi zostać zmieniony przy użyciu OnStateChangedAsync akcji .


    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;
        }
    
        
    }

Uruchamianie kodu

Możesz skompilować i uruchomić kod w programie Visual Studio. W przypadku platform rozwiązań obsługujemy ARM64systemy , x64i x86.

Ręczne kroki konfigurowania wywołania:

  1. Uruchom aplikację przy użyciu programu Visual Studio.
  2. Wprowadź identyfikator obiektu kolejki wywołań (z prefiksem) i wybierz przycisk "Rozpocznij połączenie". Aplikacja uruchomi wywołanie wychodzące do kolejki wywołań z danym identyfikatorem obiektu.
  3. Połączenie jest połączone z kolejką wywołań.
  4. Użytkownik usług Communication Services jest kierowany przez kolejkę wywołań na podstawie jego konfiguracji.

Czyszczenie zasobów

Jeśli chcesz wyczyścić i usunąć subskrypcję usług Komunikacyjnych, możesz usunąć zasób lub grupę zasobów. Usunięcie grupy zasobów powoduje również usunięcie wszelkich innych skojarzonych z nią zasobów. Dowiedz się więcej o czyszczeniu zasobów.

Następne kroki

Aby uzyskać więcej informacji, zobacz następujące artykuły: