Communication Services Calling SDK を使用した Teams ユーザーの通話を管理する

Azure Communication Services SDK を使用して通話を管理する方法について説明します。 通話を行い、参加者とプロパティを管理する方法について説明します。

前提条件

SDK のインストール

npm install コマンドを使用して、JavaScript 用の Azure Communication Services 通話と共通の各 SDK をインストールします。

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

必要なオブジェクトを初期化する

CallClient インスタンスを作成して、通話スタックを開始します。 AzureLogger インスタンスと setLogLevel メソッドを使用して、通話 SDK のログ記録を構成できます。 メソッド getDeviceManager を使用して、オペレーティング システムの deviceManager にアクセスできます。

次に、メソッド createTeamsCallAgent を使用して、Teams ユーザーの着信と発信の通話を管理する TeamsCallAgent インスタンスを非同期的に作成します。 このメソッドは、Teams ユーザーのアクセス トークンを表す引数として CommunicationTokenCredential を取ります。

const { CallClient } = require('@azure/communication-calling');
const { AzureCommunicationTokenCredential} = require('@azure/communication-common');
const { AzureLogger, setLogLevel } = require("@azure/logger");

// Set the logger's log level
setLogLevel('verbose');

// Redirect log output to wherever desired. To console, file, buffer, REST API, etc...
AzureLogger.log = (...args) => {
    console.log(...args); // Redirect log output to console
};

const userToken = '<USER_TOKEN>';
callClient = new CallClient();
const tokenCredential = new AzureCommunicationTokenCredential(userToken);
const teamsCallAgent = await callClient.createTeamsCallAgent(tokenCredential);
const deviceManager = await callClient.getDeviceManager();

通話を行う

teamsCallAgentstartCall API を使用して、同期的な 1 対 1 またはグループ通話を開始します。 通話のターゲットを定義するパラメーターとして MicrosoftTeamsUserIdentifier または PhoneNumberIdentifier を指定できます。 通話イベントをサブスクライブできるようにする TeamsCall インスタンスがメソッドから返されます。

Note

teamsCallAgent でグループ通話を開始するには、startCall メソッドの呼び出し時にチャットの threadId が必要になります。 作成された TeamsCall インスタンスには、このスレッドをキャプチャするプロパティ threadId があります。 Communication Services Calling SDK では、チャットの参加者と通話名簿の同期は行われません。Microsft では、最適なユーザー エクスペリエンスを提供するために、名簿の同期を維持するように開発者に推奨しています。 チャット スレッドを管理する方法について参照してください。

Teams ユーザーへの 1 対 1 のボイス オーバー IP (VoIP) 通話を開始します。

const userCallee = { microsoftTeamsUserId: '<MICROSOFT_TEAMS_USER_ID>' };
const oneToOneCall = teamsCallAgent.startCall(userCallee);

E.164 電話番号への 1 対 1 の音声通話を開始します。

const phoneCallee = { phoneNumber: '<PHONE_NUMBER_E164_FORMAT>' }
const oneToOneCall = teamsCallAgent.startCall(phoneCallee );

ボイス オーバー IP (VoIP) と電話番号を使用して Teams ユーザーへのグループ通話を開始します。

const userCallee = { microsoftTeamsUserId: '<MICROSOFT_TEAMS_USER_ID>' }
const phoneCallee = { phoneNumber: '<PHONE_NUMBER_E164_FORMAT>'};
const groupCall = teamsCallAgent.startCall([userCallee, phoneCallee], { threadId: '<THREAD_ID>' });

通話への参加

Teams 会議に参加する

teamsCallAgent インスタンスでメソッド join を使用して Teams 会議に参加できます。 Teams ユーザーは、TeamsMeetingLinkLocatorTeamsMeetingCoordinatesLocator、または TeamsMeetingIdLocator を指定して Teams 会議に参加できます。

会議 URL を使用して Teams 会議に参加します。

const meetingCall = teamsCallAgent.join({ meetingLink: '<MEETING_LINK>' });

スレッド ID、開催者 ID、テナント ID、メッセージ ID を組み合わせて Teams 会議に参加します。

const meetingCall = teamsCallAgent.join({ threadId: '<THREAD_ID>', organizerId: '<ORGANIZER_ID>', tenantId: '<TENANT_ID>', messageId: '<MESSAGE_ID>' });

次の会議コードとパスコードを使用して Teams 会議に参加します。

const meetingCall = teamsCallAgent.join({ meetingId: '<MEETING_CODE>', passcode: '<PASSCODE>'});

次の会議 ID とパスコードを使用して Teams 会議に参加します。

開発者は、複数の方法で参加者を Teams 会議に接続できます。 1 つが、招待された Teams 会議にデバイスやアプリケーションから参加できる会議 ID とパスコードです。 会議に参加するには、常に会議 ID とパスコードの両方が必要です。 パスコードでは、大文字と小文字が区別されます。

  • 会議 ID とパスコードの形式は次のとおりです:

    • 会議 ID: 12 桁。
    • パスコード: 6 文字
  • 会議 ID とパスコードはどのくらいの頻度で更新する必要がありますか?

    • 一度作成された会議 ID とパスコードは変更されません。 開発者はどちらも更新する必要はありません。
    • Teams 会議の開催者は、会議 ID とパスコードを再生成できません。
  • ユーザーが URL または会議 ID とパスコードを通じて参加した場合、Teams 会議のエクスペリエンスに違いはありますか?

    • いいえ。Teams 会議 URL または会議 ID とパスコードを使用して Teams 会議に参加する場合も、参加者のエクスペリエンスは同じです。
  • 開発者はパスコードをどのように保存および管理する必要がありますか?

    • 会議に参加するには、会議 ID とパスコードが必要です。 開発者はそれらをシークレットとして扱う必要があります。暗号化する必要があります。保存されている場合は、アクセス制御された環境にいることを確認してください。
    • 座標が公開されると、すべてのユーザーが会議に参加でき、会議の参加者全員のエクスペリエンスが損なわれます。
  • 会議 ID とパスコードはどのように取得しますか?

    1. Graph API: Graph API を使用して onlineMeeting リソースに関する情報を取得し、プロパティ joinMeetingIdSettings のオブジェクトを確認します。
    2. Teams: Teams アプリケーションで Calendar アプリに移動し会議の詳細を開きます。 オンライン会議には、会議の定義内に会議 ID とパスコードがあります。
    3. Outlook: 会議 ID とパスコードは、カレンダー イベントまたはメール会議招待の中で確認できます。
    4. 開発者は、SDK を呼び出して会議 ID とパスコードを取得したり、詳細なコンソール ログから取得したりすることはできません。
  • 会議ID とパスコードが正しいことを確認するにはどうすればいいですか?

Teams の着信通話を受信する

teamsCallAgent インスタンスで incomingCall イベントをサブスクライブして、Teams ユーザーへの着信通話を登録できます。 このイベントには、着信通話を accept または reject できるようにする TeamsIncomingCall インスタンスを持つ teamsIncomingCall プロパティがあります。

const incomingCallHandler = async (args: { teamsIncomingCall: TeamsIncomingCall }) => {
    const incomingCall = args.teamsIncomingCall;
    // Get Teams incoming call ID
    const incomingCallId = incomingCall.id;
    // Get information about this Call. This API is provided as a preview for developers
    // and may change based on feedback that we receive. Do not use this API in a production environment.
    // To use this API please use 'beta' release of Azure Communication Services Calling Web SDK
    const callInfo = incomingCall.info;
    // Get information about caller
    const callerInfo = incomingCall.callerInfo
    // Accept the call
    const teamsCall = await incomingCall.accept();
    // Reject the call
    incomingCall.reject();
    // Subscribe to callEnded event and get the call end reason
    incomingCall.on('callEnded', args => {
        console.log(args.callEndReason);
    });
    // callEndReason is also a property of IncomingCall
    var callEndReason = incomingCall.callEndReason;
};
teamsCallAgent.on('incomingCall', incomingCallHandler);

ビデオを有効または無効にする

TeamsCall インスタンスのプロパティ localVideoStreams からローカル ビデオ ストリーム コレクションを取得できます。 有効にすると、このコレクションに画面共有ストリームとカメラ ビデオ フィードが含まれるようになります。 リモート参加者のビデオ ストリームを取得するには、プロパティ TeamsCall.remoteParticipants を調べます。ここで、各参加者はビデオ ストリームのコレクションをプロパティ videoStreams 内に保持しています。

ミュートとミュート解除

TeamsCall インスタンスで mute および unmute の非同期 API を使用して、Teams ユーザーをローカルでミュートまたはミュート解除できます。 ローカル ミュートでは、音声が他の参加者に送信されなくなります。

//mute local device
await call.mute();
//unmute local device
await call.unmute();

他の参加者をミュートする

他のすべての参加者をミュートしたり、特定の参加者をミュートしたりするには、呼び出しに非同期 API muteAllRemoteParticipantsを使用し、リモート参加者に次の mute を使用できます。

//mute all participants except yourself
await call.muteAllRemoteParticipants();

//mute a specific participant
await call.remoteParticipants[0].mute();

Note

この API は開発者向けにプレビューとして提供されており、寄せられたフィードバックにもとづいて変更される場合があります。 この API は運用環境で使用しないでください。 この API を使用するには、Azure Communication Services Calling Web SDK の "ベータ" リリースを使用してください

リモート参加者を管理する

他の通話参加者は、TeamsCall インスタンスのプロパティ remoteParticipants で利用可能です。 RemoteParticipant オブジェクトのコレクションです。 他の参加者を一覧表示したり、通話に対して追加または削除したりできます。

Note

参加者メソッドを追加するには、チャットの threadId が必要になります。 Communication Services Calling SDK では、チャットの参加者と通話名簿の同期は行われません。Microsft では、最適なユーザー エクスペリエンスを提供するために、名簿の同期を維持するように開発者に推奨しています。 チャット スレッドを管理する方法について参照してください。

新しい Teams ユーザーまたは電話番号を Teams 通話または Teams 会議に追加するには、オブジェクト TeamsCall でメソッド addParticipant を呼び出します。 このメソッドは、識別子 MicrosoftTeamsUserIdentifier または PhoneNumberIdentifier を入力として受け取り、RemoteParticipant のインスタンスを同期的に返し、TeamsCall インスタンスでイベント remoteParticipantsUpdated をトリガーします。

Teams 通話または Teams 会議から参加者を削除するには、TeamsCall インスタンスで removeParticipant メソッドを非同期的に呼び出します。 このメソッドは、識別子の MicrosoftTeamsUserIdentifier または PhoneNumberIdentifier を入力として受け取ります。 このメソッドは、RemoteParticipantremoteParticipants コレクションから削除され、TeamsCall インスタンスのイベント remoteParticipantsUpdated がトリガーされると解決されます。

他の通話参加者を一覧表示します。

const participants = call.remoteParticipants; // [remoteParticipant, remoteParticipant....]

Teams 通話または Teams 会議に Teams ユーザーと電話番号を追加します。

const teamsUser = { microsoftTeamsUserId: '<MICROSOFT_TEAMS_USER_ID>' };
const phoneUser = { phoneNumber: '<PHONE_NUMBER_E164_FORMAT>' }
const remoteParticipant = call.addParticipant(teamsUser , { threadId: '<THREAD_ID>' });
const remoteParticipant2 = call.addParticipant(phoneUser , { threadId: '<THREAD_ID>' });

Teams 通話または Teams 会議から Teams ユーザーと電話番号を削除します。

const teamsUser = { microsoftTeamsUserId: '<MICROSOFT_TEAMS_USER_ID>' };
const phoneUser = { phoneNumber: '<PHONE_NUMBER_E164_FORMAT>' }
await call.removeParticipant(teamsUser);
await call.removeParticipant(phoneUser);

リモート参加者

リモート参加者は、進行中の Teams 通話または Teams 会議に接続されているエンドポイントを表します。 クラス remoteParticipant には、次のプロパティとコレクションのセットがあります。

  • identifier: 次のいずれかの識別子を返します: CommunicationUserIdentifierMicrosoftTeamsUserIdentifierPhoneNumberIdentifier、または UnknownIdentifier
const identifier = remoteParticipant.identifier;
  • state: リモート参加者の状態を表す string を返します。 状態は次のいずれかの値になります。
状態の値 When 説明
Idle 初期状態 これは参加者の最初の状態です
Connecting Idle の後 参加者が通話に接続している間の遷移状態。
Ringing Connecting の後 参加者が incomingCall 通知を受け取ったか、Teams クライアントが発信中です
Connected RingingConnectingEarlyMedia、または InLobby の後 参加者が通話の招待を受け入れたか、通話に参加しました。 メディアが参加者に送信されます。
Hold Connected の後 通話の参加者は保留中です。
EarlyMedia Connecting の後 参加者が通話に接続する前にメディアが再生されます
InLobby RingingConnecting、または EarlyMedia の後 参加者が Teams 会議ロビーにいます。
Disconnected 最終状態 参加者は通話から切断されました。 リモート参加者がネットワーク接続を失うと、2 分後に状態は Disconnected に変わります。

1 対 1 またはグループ通話でのリモート参加者の状態: 1 対 1 またはグループ通話のリモート参加者の通話状態の図。

Teams 会議でのリモート参加者の状態: Teams 会議のリモート参加者の通話状態の図。

const state = remoteParticipant.state;
  • callEndReason: 通話が終了した理由に関する追加情報を含むオブジェクトを返します。 プロパティ code は理由に関連する数値を返し、subCode はコードと理由に関連する数値を返します。 エラー コードの詳細については、「コール エンド応答コードのトラブルシューティング」を参照してください。
const callEndReason = remoteParticipant.callEndReason;
const callEndReasonCode = callEndReason.code
const callEndReasonSubCode = callEndReason.subCode
  • isMuted: ローカル ミュートの状態を表す Boolean 値を返します。
const isMuted = remoteParticipant.isMuted;
  • isSpeaking: 送信中の空ではない音声の状態を表す Boolean 値を返します。
const isSpeaking = remoteParticipant.isSpeaking;
  • videoStreams: 参加者によって送信された RemoteVideoStream オブジェクトのコレクションを返します。
const videoStreams = remoteParticipant.videoStreams; // [RemoteVideoStream, ...]
  • displayName: 表示名を表す string を返します。 Communication Services 通話 SDK では、Teams ユーザーにこの値を設定しません。
const displayName = remoteParticipant.displayName;

Call

  • id: 一意の通話識別子を表す文字列を返します。
const callId = call.id;

info: 通話に関する情報を返します。

Note

この API は開発者向けにプレビューとして提供されており、寄せられたフィードバックにもとづいて変更される場合があります。 この API は運用環境で使用しないでください。 この API を使用するには、Azure Communication Services Calling Web SDK の "ベータ" リリースを使用してください

info: 通話に関する情報を含むオブジェクトを返します。 プロパティ threadId は、Teams クライアントに表示されるチャットのスレッド ID を表す文字列です。

const callInfo = call.info;
const threadId = call.info.threadId;

remoteParticipants: Teams 通話または Teams 会議の他の参加者を表す remoteParticipant オブジェクトのコレクションを返します。

const remoteParticipants = call.remoteParticipants;

callerInfo: 着信呼び出しの CallerInfo オブジェクトを返します。 プロパティ identifier には、オブジェクト CommunicationUserIdentifierMicrosoftTeamsUserIdentifierPhoneNumberIdentifier、または UnknownIdentifier のいずれかを指定できます。 プロパティ displayName は、表示する名前を表す文字列です (設定されている場合)。

const callerIdentity = call.callerInfo.identifier;
const callerIdentity = call.callerInfo.displayName;

state: 通話の状態を表す文字列を返します。 プロパティには、次のいずれかの値を設定できます。

状態の値 When 説明
None 初期状態 通話の初期状態。
Connecting None の後 Teams 通話または Teams 会議が設定、参加、または受け入れられたときの状態。
Ringing Connecting の後 リモート参加者が incomingCall イベントを受信したか、Teams クライアントが発信中です。
EarlyMedia Ringing または Connecting の後 通話が接続される前にメディアが再生されます。
Connected RingingEarlyMediaInLobbyLocalHold、および RemoteHold の後 通話は接続されています。 ローカル エンドポイントとリモート参加者の間でメディアが送信されています。
LocalHold Connected の後 通話がローカル参加者によって保留にされました。 ローカル エンドポイントとリモート参加者の間でメディアは送信されていません。
RemoteHold Connected の後 通話がリモート参加者によって保留にされました。 ローカル エンドポイントとリモート参加者の間でメディアは送信されていません。
InLobby Ringing または Connecting の後 リモート参加者は Teams 会議ロビーにいます。 ローカル エンドポイントとリモート参加者の間でメディアは送信されていません。
Disconnecting すべての状態の後 通話が Disconnected 状態になる前の遷移状態。
Disconnected 最終状態 通話の最終状態。 ネットワーク接続が失われると、2 分後に状態は Disconnected になります。

1 対 1 またはグループ呼び出しの状態: 1 対 1 またはグループ通話の呼び出し状態を示す図。

Teams 会議の状態: Teams 会議の通話状態を示す図。

const callState = call.state;

callEndReason: 終了した通話に関する追加情報を含むオブジェクト CallEndReason を返します。 プロパティ code は理由に関連する数値を返し、subCode はコードと理由に関連する数値を返します。 エラー コードの詳細については、「コール エンド応答コードのトラブルシューティング」を参照してください。

const callEndReason = call.callEndReason;
const callEndReasonCode = callEndReason.code
const callEndReasonSubCode = callEndReason.subCode

direction: 通話の方向を表す string を返します。 プロパティには、'Incoming' または Outgoing のいずれかの値を指定できます。

const isIncoming = call.direction == 'Incoming';
const isOutgoing = call.direction == 'Outgoing';

isMuted: ローカル ミュートの状態を表す Boolean 値を返します。

const muted = call.isMuted;

isScreenSharingOn: 画面共有ストリームを他の参加者に送信する場合は、Boolean 値の TRUE を返します。

const isScreenSharingOn = call.isScreenSharingOn;

localVideoStreams: リモート参加者に送信されるビデオ ストリームを表す LocalVideoStream オブジェクトのコレクションを返します。

const localVideoStreams = call.localVideoStreams;

チャット スレッドを管理する

グループ通話を行い、参加者を既存の通話に追加するには、チャット ID を指定する必要があります。 関連付けられたチャットと通話には、別個の参加者の一覧があります。 通話に参加者を追加する前に、最適なユーザー エクスペリエンスを提供し、情報バリアの要件を満たすためにユーザーをチャットに追加します。 ユーザーをチャットに追加せずに通話にユーザーを追加すると、情報バリアが設定されている場合は例外が発生する可能性があります。

次のシナリオについて考えます。Alice が Bob に通話を行った後、Alice が Charlie を追加し、3 分後に Alice が Charlie を通話から削除します。

  1. Alice、Bob、および Charlie の間にチャット スレッドを作成します。 チャット threadId を後のために保持します。
  2. Alice は、TeamsCallAgent インスタンスで startCall メソッドを使用して Bob と Charlie を呼び出します。
  3. メンバーを追加するための Chat Graph API を使用して、threadId を持つチャット スレッドに Dan を追加します。
  4. Alice は、calladdParticipant メソッドを使用して Dan を通話に追加し、threadId を指定します。
  5. Alice は、callremoveParticipant メソッドを使用して Dan を通話から削除し、threadId を指定します。
  6. メンバーを削除するための Chat Graph API を使用して、threadId を持つチャット スレッドから Dan を削除します。

Teams ユーザーが通話の記録を停止すると、記録はスレッドに関連付けられたチャットに配置されます。 指定されたチャット ID は、Teams クライアント内の Teams ユーザーのエクスペリエンスに影響を与えます。

チャット ID の管理に関する推奨事項:

  • 別の電話参加者を追加することによる 1:1 音声通話のエスカレーション: Graph API を使用して、Teams ユーザーのみを含む既存のチャット ID を参加者として取得するか、参加者: Teams ユーザー ID と "00000000-0000-0000-0000-000000000000" で新しいグループ チャットを作成します。
  • 1 つの Teams ユーザーと複数の電話参加者によるグループ通話: Graph API を使用して、Teams ユーザーのみを含む既存のチャット ID を参加者として取得するか、参加者: Teams ユーザー ID と "00000000-0000-0000-0000-000000000000" で新しいグループ チャットを作成します。
  • 2 人を超える Teams ユーザーとのグループ通話: Graph API を使用して、Teams ユーザーとのグループチャットを取得または作成します。