Rövid útmutató: Csatlakozás a csevegőalkalmazáshoz Teams-értekezlethez

Ismerkedés az Azure Communication Services szolgáltatással a csevegőmegoldás Microsoft Teamshez való csatlakoztatásával.

Ebben a rövid útmutatóban megtudhatja, hogyan cseveghet Teams-értekezleteken az Azure Communication Services Chat SDK for JavaScript használatával.

Mintakód

Keresse meg a gitHubon a rövid útmutató véglegesített kódját.

Előfeltételek

Bekapcsolódás az értekezlet csevegésbe

A Communication Services-felhasználók névtelen felhasználóként csatlakozhatnak a Teams-értekezletekhez a Hívás SDK használatával. Az értekezlethez való csatlakozás résztvevőként is hozzáadja őket az értekezlet csevegéséhez, ahol üzeneteket küldhetnek és fogadhatnak az értekezlet többi felhasználójával. A felhasználónak nem lesz hozzáférése az értekezlethez való csatlakozás előtt elküldött csevegőüzenetekhez, és nem tud üzeneteket küldeni vagy fogadni az értekezlet befejezése után. Az értekezlethez való csatlakozáshoz és a csevegés megkezdéséhez kövesse a következő lépéseket.

Új Node.js-alkalmazás létrehozása

Nyissa meg a terminált vagy a parancsablakot, hozzon létre egy új könyvtárat az alkalmazáshoz, és navigáljon hozzá.

mkdir chat-interop-quickstart && cd chat-interop-quickstart

Futtassa npm init -y az alapértelmezett beállításokkal rendelkező package.json fájl létrehozásához.

npm init -y

A csevegőcsomagok telepítése

npm install A parancs használatával telepítheti a JavaScripthez szükséges Communication Services SDK-kat.

npm install @azure/communication-common --save

npm install @azure/communication-identity --save

npm install @azure/communication-chat --save

npm install @azure/communication-calling --save

A --save beállítás függőségként sorolja fel a tárat a package.json fájlban.

Az alkalmazás-keretrendszer beállítása

Ez a rövid útmutató a Webpack használatával kötegeli az alkalmazásegységeket. Futtassa a következő parancsot a Webpack, a webpack-cli és a webpack-dev-server npm csomagok telepítéséhez, és sorolja fel őket fejlesztési függőségekként a package.json:

npm install webpack@5.89.0 webpack-cli@5.1.4 webpack-dev-server@4.15.1 --save-dev

Hozzon létre egy index.html fájlt a projekt gyökérkönyvtárában. Ezzel a fájllal olyan alapszintű elrendezést konfigurálunk, amely lehetővé teszi, hogy a felhasználó bekapcsolódjon egy értekezletbe, és csevegni kezdjen.

A Teams felhasználói felület vezérlőinek hozzáadása

Cserélje le a index.html kódját a következő kódrészletre. A rendszer a lap tetején található szövegdobozt használja a Teams-értekezlet környezetének megadásához. A "Teams-értekezletbe való bekapcsolódás" gomb a megadott értekezlethez való csatlakozásra szolgál. A lap alján megjelenik egy csevegési előugró ablak. Segítségével üzeneteket küldhet az értekezleti szálon, és valós időben jeleníti meg a szálon küldött üzeneteket, miközben a Communication Services-felhasználó tagja.

<!DOCTYPE html>
<html>
   <head>
      <title>Communication Client - Calling and Chat Sample</title>
      <style>
         body {box-sizing: border-box;}
         /* The popup chat - hidden by default */
         .chat-popup {
         display: none;
         position: fixed;
         bottom: 0;
         left: 15px;
         border: 3px solid #f1f1f1;
         z-index: 9;
         }
         .message-box {
         display: none;
         position: fixed;
         bottom: 0;
         left: 15px;
         border: 3px solid #FFFACD;
         z-index: 9;
         }
         .form-container {
         max-width: 300px;
         padding: 10px;
         background-color: white;
         }
         .form-container textarea {
         width: 90%;
         padding: 15px;
         margin: 5px 0 22px 0;
         border: none;
         background: #e1e1e1;
         resize: none;
         min-height: 50px;
         }
         .form-container .btn {
         background-color: #4CAF40;
         color: white;
         padding: 14px 18px;
         margin-bottom:10px;
         opacity: 0.6;
         border: none;
         cursor: pointer;
         width: 100%;
         }
         .container {
         border: 1px solid #dedede;
         background-color: #F1F1F1;
         border-radius: 3px;
         padding: 8px;
         margin: 8px 0;
         }
         .darker {
         border-color: #ccc;
         background-color: #ffdab9;
         margin-left: 25px;
         margin-right: 3px;
         }
         .lighter {
         margin-right: 20px;
         margin-left: 3px;
         }
         .container::after {
         content: "";
         clear: both;
         display: table;
         }
      </style>
   </head>
   <body>
      <h4>Azure Communication Services</h4>
      <h1>Calling and Chat Quickstart</h1>
          <input id="teams-link-input" type="text" placeholder="Teams meeting link"
        style="margin-bottom:1em; width: 400px;" />
        <p>Call state <span style="font-weight: bold" id="call-state">-</span></p>
      <div>
        <button id="join-meeting-button" type="button">
            Join Teams Meeting
        </button>
        <button id="hang-up-button" type="button" disabled="true">
            Hang Up
        </button>
      </div>
      <div class="chat-popup" id="chat-box">
         <div id="messages-container"></div>
         <form class="form-container">
            <textarea placeholder="Type message.." name="msg" id="message-box" required></textarea>
            <button type="button" class="btn" id="send-message">Send</button>
         </form>
      </div>
      <script src="./bundle.js"></script>
   </body>
</html>

A Teams felhasználói felület vezérlőinek engedélyezése

Cserélje le a client.js fájl tartalmát a következő kódrészletre.

A kódrészleten belül cserélje le a

  • SECRET_CONNECTION_STRINGkommunikációs szolgáltatás kapcsolati sztring
import { CallClient } from "@azure/communication-calling";
import { AzureCommunicationTokenCredential } from "@azure/communication-common";
import { CommunicationIdentityClient } from "@azure/communication-identity";
import { ChatClient } from "@azure/communication-chat";

let call;
let callAgent;
let chatClient;
let chatThreadClient;

const meetingLinkInput = document.getElementById("teams-link-input");
const callButton = document.getElementById("join-meeting-button");
const hangUpButton = document.getElementById("hang-up-button");
const callStateElement = document.getElementById("call-state");

const messagesContainer = document.getElementById("messages-container");
const chatBox = document.getElementById("chat-box");
const sendMessageButton = document.getElementById("send-message");
const messageBox = document.getElementById("message-box");

var userId = "";
var messages = "";
var chatThreadId = "";

async function init() {
  const connectionString = "<SECRET_CONNECTION_STRING>";
  const endpointUrl = connectionString.split(";")[0].replace("endpoint=", "");

  const identityClient = new CommunicationIdentityClient(connectionString);

  let identityResponse = await identityClient.createUser();
  userId = identityResponse.communicationUserId;
  console.log(`\nCreated an identity with ID: ${identityResponse.communicationUserId}`);

  let tokenResponse = await identityClient.getToken(identityResponse, ["voip", "chat"]);

  const { token, expiresOn } = tokenResponse;
  console.log(`\nIssued an access token that expires at: ${expiresOn}`);
  console.log(token);

  const callClient = new CallClient();
  const tokenCredential = new AzureCommunicationTokenCredential(token);

  callAgent = await callClient.createCallAgent(tokenCredential);
  callButton.disabled = false;
  chatClient = new ChatClient(endpointUrl, new AzureCommunicationTokenCredential(token));

  console.log("Azure Communication Chat client created!");
}

init();

const joinCall = (urlString, callAgent) => {
  const url = new URL(urlString);
  console.log(url);
  if (url.pathname.startsWith("/meet")) {
    // Short teams URL, so for now call meetingID and pass code API
    return callAgent.join({
      meetingId: url.pathname.split("/").pop(),
      passcode: url.searchParams.get("p"),
    });
  } else {
    return callAgent.join({ meetingLink: urlString }, {});
  }
};

callButton.addEventListener("click", async () => {
  // join with meeting link
  try {
    call = joinCall(meetingLinkInput.value, callAgent);
  } catch {
    throw new Error("Could not join meeting - have you set your connection string?");
  }

  // Chat thread ID is provided from the call info, after connection.
  call.on("stateChanged", async () => {
    callStateElement.innerText = call.state;

    if (call.state === "Connected" && !chatThreadClient) {
      chatThreadId = call.info?.threadId;
      chatThreadClient = chatClient.getChatThreadClient(chatThreadId);

      chatBox.style.display = "block";
      messagesContainer.innerHTML = messages;

      // open notifications channel
      await chatClient.startRealtimeNotifications();

      // subscribe to new message notifications
      chatClient.on("chatMessageReceived", (e) => {
        console.log("Notification chatMessageReceived!");

        // check whether the notification is intended for the current thread
        if (chatThreadId != e.threadId) {
          return;
        }

        if (e.sender.communicationUserId != userId) {
          renderReceivedMessage(e.message);
        } else {
          renderSentMessage(e.message);
        }
      });
    }
  });

  // toggle button and chat box states
  hangUpButton.disabled = false;
  callButton.disabled = true;

  console.log(call);
});

async function renderReceivedMessage(message) {
  messages += '<div class="container lighter">' + message + "</div>";
  messagesContainer.innerHTML = messages;
}

async function renderSentMessage(message) {
  messages += '<div class="container darker">' + message + "</div>";
  messagesContainer.innerHTML = messages;
}

hangUpButton.addEventListener("click", async () => {
  // end the current call
  await call.hangUp();
  // Stop notifications
  chatClient.stopRealtimeNotifications();

  // toggle button states
  hangUpButton.disabled = true;
  callButton.disabled = false;
  callStateElement.innerText = "-";

  // toggle chat states
  chatBox.style.display = "none";
  messages = "";
  // Remove local ref
  chatThreadClient = undefined;
});

sendMessageButton.addEventListener("click", async () => {
  let message = messageBox.value;

  let sendMessageRequest = { content: message };
  let sendMessageOptions = { senderDisplayName: "Jack" };
  let sendChatMessageResult = await chatThreadClient.sendMessage(
    sendMessageRequest,
    sendMessageOptions
  );
  let messageId = sendChatMessageResult.id;

  messageBox.value = "";
  console.log(`Message sent!, message id:${messageId}`);
});

A csevegőszál résztvevőinek megjelenítendő neveit nem a Teams-ügyfél állítja be. A nevek null értékként jelennek meg az API-ban a résztvevők listázásához, az participantsAdded eseményhez és az participantsRemoved eseményhez. A csevegés résztvevőinek megjelenített nevei lekérhetők az remoteParticipantscall objektum mezőjéből. Ha értesítést kap egy névsorváltozásról, ezzel a kóddal lekérheti a hozzáadott vagy eltávolított felhasználó nevét:

var displayName = call.remoteParticipants.find(p => p.identifier.communicationUserId == '<REMOTE_USER_ID>').displayName;

A kód futtatása

A Webpack-felhasználók használhatják az webpack-dev-server alkalmazás összeállítását és futtatását. Futtassa az alábbi parancsot az alkalmazás gazdagépének helyi webkiszolgálón való kötegeléséhez:

npx webpack-dev-server --entry ./client.js --output bundle.js --debug --devtool inline-source-map

Nyissa meg a böngészőt, és keresse meg a következőt http://localhost:8080/: . Az alkalmazásnak az alábbi képernyőképen látható módon kell elindulnia:

Képernyőkép a befejezett JavaScript-alkalmazásról.

Szúrja be a Teams-értekezlet hivatkozását a szövegmezőbe. A Teams-értekezlethez való csatlakozáshoz nyomja le a Join Teams-értekezletet . Miután a Communication Services-felhasználót beengedték az értekezletbe, cseveghet a Communication Services-alkalmazásban. A csevegés megkezdéséhez lépjen a lap alján található mezőbe. Az egyszerűség kedvéért az alkalmazás csak az utolsó két üzenetet jeleníti meg a csevegésben.

Feljegyzés

Bizonyos funkciók jelenleg nem támogatottak a Teamsszel való együttműködési forgatókönyvekben. További információ a támogatott funkciókról: Teams-értekezletek képességei a Teams külső felhasználói számára

Ebben a rövid útmutatóban megtudhatja, hogyan cseveghet Teams-értekezleteken az iOS-hez készült Azure Communication Services Chat SDK használatával.

Mintakód

Ha a végére szeretne ugrani, letöltheti ezt a rövid útmutatót mintaként a GitHubon.

Előfeltételek

  • Egy Azure-fiók, aktív előfizetéssel. Fiók létrehozása ingyenesen
  • Egy Xcode-ot futtató Mac gép, valamint egy érvényes fejlesztői tanúsítvány, amely telepítve van a kulcskarikába.
  • Teams-telepítés.
  • Felhasználói hozzáférési jogkivonat az Azure Communication Service-hez. Az Azure CLI-t is használhatja, és futtathatja a parancsot a kapcsolati sztring egy felhasználó és egy hozzáférési jogkivonat létrehozásához.
az communication identity token issue --scope voip --connection-string "yourConnectionString"

További részletekért lásd: Hozzáférési jogkivonatok létrehozása és kezelése az Azure CLI használatával.

Beállítás

Az Xcode-projekt létrehozása

Az Xcode-ban hozzon létre egy új iOS-projektet, és válassza ki az egynézetes alkalmazássablont. Ez az oktatóanyag a SwiftUI keretrendszert használja, ezért a nyelvet Swiftre, a felhasználói felületet pedig SwiftUI-ra kell állítani. Ebben a rövid útmutatóban nem fog teszteket létrehozni. Nyugodtan törölje a jelölést a Belefoglalási tesztek jelölőnégyzetből.

Képernyőkép az Új projekt ablakról az Xcode-on belül.

A CocoaPods telepítése

Ebben az útmutatóban a CocoaPodsot telepítheti Mac gépére.

A csomag és a függőségek telepítése a CocoaPods használatával

  1. Ha létre szeretne hozni egy Podfile alkalmazást, nyissa meg a terminált, keresse meg a projektmappát, és futtassa a pod init parancsot.

  2. Adja hozzá a következő kódot a Podfile célcsoporthoz, és mentse.

target 'Chat Teams Interop' do
  # Comment the next line if you don't want to use dynamic frameworks
  use_frameworks!

  # Pods for Chat Teams Interop
  pod 'AzureCommunicationCalling'
  pod 'AzureCommunicationChat'
  
end
  1. Futtassa az pod install parancsot.

  2. Nyissa meg a .xcworkspace fájlt Xcode-tal.

Hozzáférés kérése a mikrofonhoz

Az eszköz mikrofonjának eléréséhez frissítenie kell az alkalmazás információs tulajdonságlistáját egy NSMicrophoneUsageDescription. A társított értéket egy olyan értékre string állítja be, amelyet a rendszer a felhasználótól való hozzáférés kéréséhez használ.

A cél alatt válassza ki a Info lapot, és adjon hozzá egy sztringet az "Adatvédelem – Mikrofonhasználat leírása" kifejezéshez

Képernyőkép a mikrofonhasználat Xcode-on belüli hozzáadásáról.

Felhasználói szkriptek védőfalának letiltása

A csatolt kódtárakban lévő szkriptek némelyike fájlokat ír a buildelési folyamat során. Ennek engedélyezéséhez tiltsa le a felhasználói szkript védőfalát az Xcode-ban. A buildelési beállítások között keresse meg sandbox és állítsa be a következőt User Script SandboxingNo: .

Képernyőkép a felhasználói szkriptek védőfalának letiltásról az Xcode-on belül.

Bekapcsolódás az értekezlet csevegésbe

A Communication Services-felhasználók névtelen felhasználóként csatlakozhatnak a Teams-értekezletekhez a Hívás SDK használatával. Miután egy felhasználó csatlakozott a Teams-értekezlethez, üzeneteket küldhet és fogadhat más értekezlet résztvevőivel. A felhasználónak nem lesz hozzáférése a csatlakozás előtt küldött csevegőüzenetekhez, és nem tud üzeneteket küldeni vagy fogadni, ha nincsenek az értekezleten. Az értekezlethez való csatlakozáshoz és a csevegés megkezdéséhez kövesse a következő lépéseket.

Az alkalmazás-keretrendszer beállítása

Importálja az Azure Communication-csomagokat ContentView.swift a következő kódrészlet hozzáadásával:

import AVFoundation
import SwiftUI

import AzureCommunicationCalling
import AzureCommunicationChat

Adja ContentView.swift hozzá a következő kódrészletet a deklaráció felett struct ContentView: View :

let endpoint = "<ADD_YOUR_ENDPOINT_URL_HERE>"
let token = "<ADD_YOUR_USER_TOKEN_HERE>"
let displayName: String = "Quickstart User"

Cserélje le <ADD_YOUR_ENDPOINT_URL_HERE> a Communication Services-erőforrás végpontját. Cserélje le <ADD_YOUR_USER_TOKEN_HERE> a fent létrehozott jogkivonatra az Azure-ügyfél parancssorán keresztül. További információ a felhasználói hozzáférési jogkivonatokról: Felhasználói hozzáférési jogkivonat

Cserélje le Quickstart User a csevegésben használni kívánt megjelenítendő névre.

Az állapot tárolásához adja hozzá a következő változókat a ContentView szerkezethez:

  @State var message: String = ""
  @State var meetingLink: String = ""
  @State var chatThreadId: String = ""

  // Calling state
  @State var callClient: CallClient?
  @State var callObserver: CallDelegate?
  @State var callAgent: CallAgent?
  @State var call: Call?

  // Chat state
  @State var chatClient: ChatClient?
  @State var chatThreadClient: ChatThreadClient?
  @State var chatMessage: String = ""
  @State var meetingMessages: [MeetingMessage] = []

Most adjuk hozzá a fő törzs varját a felhasználói felület elemeinek tárolásához. Ebben a rövid útmutatóban üzleti logikát csatolunk ezekhez a vezérlőkhöz. Adja hozzá a következő kódot a ContentView szerkezethez:

var body: some View {
    NavigationView {
      Form {
        Section {
          TextField("Teams Meeting URL", text: $meetingLink)
            .onChange(of: self.meetingLink, perform: { value in
              if let threadIdFromMeetingLink = getThreadId(from: value) {
                self.chatThreadId = threadIdFromMeetingLink
              }
            })
          TextField("Chat thread ID", text: $chatThreadId)
        }
        Section {
          HStack {
            Button(action: joinMeeting) {
              Text("Join Meeting")
            }.disabled(
              chatThreadId.isEmpty || callAgent == nil || call != nil
            )
            Spacer()
            Button(action: leaveMeeting) {
              Text("Leave Meeting")
            }.disabled(call == nil)
          }
          Text(message)
        }
        Section {
          ForEach(meetingMessages, id: \.id) { message in
            let currentUser: Bool = (message.displayName == displayName)
            let foregroundColor = currentUser ? Color.white : Color.black
            let background = currentUser ? Color.blue : Color(.systemGray6)
            let alignment = currentUser ? HorizontalAlignment.trailing : .leading
            
            HStack {
              if currentUser {
                Spacer()
              }
              VStack(alignment: alignment) {
                Text(message.displayName).font(Font.system(size: 10))
                Text(message.content)
                  .frame(maxWidth: 200)
              }

              .padding(8)
              .foregroundColor(foregroundColor)
              .background(background)
              .cornerRadius(8)

              if !currentUser {
                Spacer()
              }
            }
          }
          .frame(maxWidth: .infinity)
        }

        TextField("Enter your message...", text: $chatMessage)
        Button(action: sendMessage) {
          Text("Send Message")
        }.disabled(chatThreadClient == nil)
      }

      .navigationBarTitle("Teams Chat Interop")
    }

    .onAppear {
      // Handle initialization of the call and chat clients
    }
  }

A ChatClient inicializálása

Az üzenetértesítések példányosítása ChatClient és engedélyezése. Valós idejű értesítéseket használunk a csevegési üzenetek fogadásához.

A fő törzs beállításával adja hozzá a függvényeket a hívás- és csevegési ügyfelek beállításának kezeléséhez.

A függvényben onAppear adja hozzá a következő kódot a CallClient következő ChatClientkód inicializálásához:

  if let threadIdFromMeetingLink = getThreadId(from: self.meetingLink) {
    self.chatThreadId = threadIdFromMeetingLink
  }
  // Authenticate
  do {
    let credentials = try CommunicationTokenCredential(token: token)
    self.callClient = CallClient()
    self.callClient?.createCallAgent(
      userCredential: credentials
    ) { agent, error in
      if let e = error {
        self.message = "ERROR: It was not possible to create a call agent."
        print(e)
        return
      } else {
        self.callAgent = agent
      }
    }
  
    // Start the chat client
    self.chatClient = try ChatClient(
      endpoint: endpoint,
      credential: credentials,
      withOptions: AzureCommunicationChatClientOptions()
    )
    // Register for real-time notifications
    self.chatClient?.startRealTimeNotifications { result in
      switch result {
      case .success:
        self.chatClient?.register(
          event: .chatMessageReceived,
          handler: receiveMessage
      )
      case let .failure(error):
        self.message = "Could not register for message notifications: " + error.localizedDescription
        print(error)
      }
    }
  } catch {
    print(error)
    self.message = error.localizedDescription
  }

Értekezlet-összeillesztés függvény hozzáadása

Adja hozzá a következő függvényt a szerkezethez az ContentView értekezlethez való csatlakozás kezeléséhez.

  func joinMeeting() {
    // Ask permissions
    AVAudioSession.sharedInstance().requestRecordPermission { (granted) in
      if granted {
        let teamsMeetingLink = TeamsMeetingLinkLocator(
          meetingLink: self.meetingLink
        )
        self.callAgent?.join(
          with: teamsMeetingLink,
          joinCallOptions: JoinCallOptions()
        ) {(call, error) in
          if let e = error {
            self.message = "Failed to join call: " + e.localizedDescription
            print(e.localizedDescription)
            return
          }

          self.call = call
          self.callObserver = CallObserver(self)
          self.call?.delegate = self.callObserver
          self.message = "Teams meeting joined successfully"
        }
      } else {
        self.message = "Not authorized to use mic"
      }
    }
  }

A ChatThreadClient inicializálása

Az értekezlethez való csatlakozás után inicializáljuk ChatThreadClient a felhasználót. Ehhez ellenőrizni kell az értekezlet állapotát a meghatalmazotttól, majd inicializálni kell az ChatThreadClientthreadId értekezlethez való csatlakozáskor.

Hozza létre a függvényt connectChat() a következő kóddal:

  func connectChat() {
    do {
      self.chatThreadClient = try chatClient?.createClient(
        forThread: self.chatThreadId
      )
      self.message = "Joined meeting chat successfully"
    } catch {
      self.message = "Failed to join the chat thread: " + error.localizedDescription
    }
  }

Ha lehetséges, adja hozzá a következő segédfüggvényt a ContentViewcsevegési szál azonosítójának elemzéséhez a Csapat értekezlet hivatkozásából. Ha ez a kinyerés sikertelen, a felhasználónak manuálisan kell megadnia a csevegési szál azonosítóját a Graph API-k használatával a szálazonosító lekéréséhez.

 func getThreadId(from teamsMeetingLink: String) -> String? {
  if let range = teamsMeetingLink.range(of: "meetup-join/") {
    let thread = teamsMeetingLink[range.upperBound...]
    if let endRange = thread.range(of: "/")?.lowerBound {
      return String(thread.prefix(upTo: endRange))
    }
  }
  return nil
}

Üzenetek küldésének engedélyezése

Adja hozzá a sendMessage() függvényt a következőhöz ContentView: . Ez a függvény a ChatThreadClient felhasználótól érkező üzenetek küldésére használja.

func sendMessage() {
  let message = SendChatMessageRequest(
    content: self.chatMessage,
    senderDisplayName: displayName,
    type: .text
  )

  self.chatThreadClient?.send(message: message) { result, _ in
    switch result {
    case .success:
    print("Chat message sent")
    self.chatMessage = ""

    case let .failure(error):
    self.message = "Failed to send message: " + error.localizedDescription + "\n Has your token expired?"
    }
  }
}

Üzenetek fogadásának engedélyezése

Az üzenetek fogadásához implementáljuk az események kezelőjének kezelését ChatMessageReceived . Amikor új üzeneteket küld a szálnak, ez a kezelő hozzáadja az üzeneteket a meetingMessages változóhoz, hogy azok megjelenjenek a felhasználói felületen.

Először adja hozzá a következő strukturát a következőhöz ContentView.swift: A felhasználói felület a struktúra adataival jeleníti meg a csevegőüzeneteket.

struct MeetingMessage: Identifiable {
  let id: String
  let date: Date
  let content: String
  let displayName: String

  static func fromTrouter(event: ChatMessageReceivedEvent) -> MeetingMessage {
    let displayName: String = event.senderDisplayName ?? "Unknown User"
    let content: String = event.message.replacingOccurrences(
      of: "<[^>]+>", with: "",
      options: String.CompareOptions.regularExpression
    )
    return MeetingMessage(
      id: event.id,
      date: event.createdOn?.value ?? Date(),
      content: content,
      displayName: displayName
    )
  }
}

Ezután adja hozzá a receiveMessage() függvényt a következőhöz ContentView: Ez üzenetküldési esemény bekövetkezésekor van meghívva. Vegye figyelembe, hogy a metóduson keresztül regisztrálnia kell az utasításban switch kezelni kívánt összes eseményre chatClient?.register() .

  func receiveMessage(event: TrouterEvent) -> Void {
    switch event {
    case let .chatMessageReceivedEvent(messageEvent):
      let message = MeetingMessage.fromTrouter(event: messageEvent)
      self.meetingMessages.append(message)

      /// OTHER EVENTS
      //    case .realTimeNotificationConnected:
      //    case .realTimeNotificationDisconnected:
      //    case .typingIndicatorReceived(_):
      //    case .readReceiptReceived(_):
      //    case .chatMessageEdited(_):
      //    case .chatMessageDeleted(_):
      //    case .chatThreadCreated(_):
      //    case .chatThreadPropertiesUpdated(_):
      //    case .chatThreadDeleted(_):
      //    case .participantsAdded(_):
      //    case .participantsRemoved(_):

    default:
      break
    }
  }

Végül implementálni kell a hívásügyfél delegált kezelőjének feladatát. Ez a kezelő a hívás állapotának ellenőrzésére és a csevegőügyfél inicializálására szolgál, amikor a felhasználó csatlakozik az értekezlethez.

class CallObserver : NSObject, CallDelegate {
  private var owner: ContentView

  init(_ view: ContentView) {
    owner = view
  }

  func call(
    _ call: Call,
    didChangeState args: PropertyChangedEventArgs
  ) {
    owner.message = CallObserver.callStateToString(state: call.state)
    if call.state == .disconnected {
      owner.call = nil
      owner.message = "Left Meeting"
    } else if call.state == .inLobby {
      owner.message = "Waiting in lobby (go let them in!)"
    } else if call.state == .connected {
      owner.message = "Connected"
      owner.connectChat()
    }
  }

  private static func callStateToString(state: CallState) -> String {
    switch state {
    case .connected: return "Connected"
    case .connecting: return "Connecting"
    case .disconnected: return "Disconnected"
    case .disconnecting: return "Disconnecting"
    case .earlyMedia: return "EarlyMedia"
    case .none: return "None"
    case .ringing: return "Ringing"
    case .inLobby: return "InLobby"
    default: return "Unknown"
    }
  }
}

A csevegés elhagyása

Amikor a felhasználó elhagyja a csapat értekezletét, töröljük a csevegőüzeneteket a felhasználói felületről, és felakasztjuk a hívást. A teljes kód alább látható.

  func leaveMeeting() {
    if let call = self.call {
      self.chatClient?.unregister(event: .chatMessageReceived)
      self.chatClient?.stopRealTimeNotifications()

      call.hangUp(options: nil) { (error) in
        if let e = error {
          self.message = "Leaving Teams meeting failed: " + e.localizedDescription
        } else {
          self.message = "Leaving Teams meeting was successful"
        }
      }
      self.meetingMessages.removeAll()
    } else {
      self.message = "No active call to hangup"
    }
  }

Teams-értekezlet csevegési szálának lekérése Egy Communication Services-felhasználó számára

A Teams-értekezlet részletei a Graph dokumentációjában részletezett Graph API-k használatával kérhetők le. A Communication Services Calling SDK teljes Teams-értekezlethivatkozást vagy értekezlet-azonosítót fogad el. Az erőforrás részeként onlineMeeting lesznek visszaadva, amely a joinWebUrl tulajdonság alatt érhető el

A Graph API-kkalthreadID a . A válasz egy chatInfo objektummal rendelkezik, amely tartalmazza a threadID.

A kód futtatása

Futtassa az alkalmazást.

A Teams-értekezlethez való csatlakozáshoz adja meg a csapat értekezlethivatkozását a felhasználói felületen.

Miután csatlakozott a csapat értekezletéhez, be kell fogadnia a felhasználót az értekezletbe a csapat ügyfélprogramjában. Miután felvette a felhasználót, és csatlakozott a csevegéshez, üzeneteket küldhet és fogadhat.

Képernyőkép a kész iOS-alkalmazásról.

Feljegyzés

Bizonyos funkciók jelenleg nem támogatottak a Teamsszel való együttműködési forgatókönyvekben. További információ a támogatott funkciókról: Teams-értekezletek képességei a Teams külső felhasználói számára

Ebben a rövid útmutatóban megtudhatja, hogyan cseveghet Teams-értekezleteken az Androidhoz készült Azure Communication Services Chat SDK használatával.

Mintakód

Ha a végére szeretne ugrani, letöltheti ezt a rövid útmutatót mintaként a GitHubon.

Előfeltételek

A Teams együttműködésének engedélyezése

A Teams-értekezletekhez vendégfelhasználóként csatlakozó Communication Services-felhasználók csak akkor férhetnek hozzá az értekezlet csevegéséhez, ha csatlakoztak a Teams-értekezlethíváshoz. A Teams interop dokumentációjában megtudhatja, hogyan vehet fel Kommunikációs szolgáltatások felhasználót egy Teams-értekezlethívásba.

A funkció használatához mindkét entitás tulajdonosi szervezetének tagjának kell lennie.

Bekapcsolódás az értekezlet csevegésbe

A Teams együttműködésének engedélyezése után a Communication Services-felhasználók külső felhasználóként csatlakozhatnak a Teams-híváshoz a Hívó SDK használatával. A híváshoz való csatlakozás résztvevőként is hozzáadja őket az értekezlet csevegéséhez, ahol üzeneteket küldhetnek és fogadhatnak a hívás többi felhasználójával. A felhasználó nem fér hozzá a híváshoz való csatlakozás előtt elküldött csevegőüzenetekhez. Az értekezlethez való csatlakozáshoz és a csevegés megkezdéséhez kövesse a következő lépéseket.

Csevegés hozzáadása a Teams-hívó alkalmazáshoz

A modul szintjén build.gradleadja hozzá a csevegő SDK függőségét.

Fontos

Ismert probléma: Ha az Android Chat és a Calling SDK együttes használatát ugyanabban az alkalmazásban használja, a Csevegő SDK valós idejű értesítési funkciója nem fog működni. Függőségfeloldási problémát fog kapni. Miközben egy megoldáson dolgozunk, kikapcsolhatja a valós idejű értesítések funkciót úgy, hogy hozzáadja a következő kizárásokat az alkalmazás fájljában található Csevegés SDK-függőséghez build.gradle :

implementation ("com.azure.android:azure-communication-chat:2.0.3") {
    exclude group: 'com.microsoft', module: 'trouter-client-android'
}

A Teams felhasználói felületének elrendezésének hozzáadása

Cserélje le a activity_main.xml kódját a következő kódrészletre. Bemeneteket ad hozzá a szálazonosítóhoz és az üzenetek küldéséhez, a beírt üzenet küldésére szolgáló gombot és egy egyszerű csevegési elrendezést.

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <EditText
        android:id="@+id/teams_meeting_thread_id"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginHorizontal="20dp"
        android:layout_marginTop="128dp"
        android:ems="10"
        android:hint="Meeting Thread Id"
        android:inputType="textUri"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <EditText
        android:id="@+id/teams_meeting_link"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginHorizontal="20dp"
        android:layout_marginTop="64dp"
        android:ems="10"
        android:hint="Teams meeting link"
        android:inputType="textUri"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <LinearLayout
        android:id="@+id/button_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="30dp"
        android:gravity="center"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/teams_meeting_thread_id">

        <Button
            android:id="@+id/join_meeting_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Join Meeting" />

        <Button
            android:id="@+id/hangup_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Hangup" />

    </LinearLayout>

    <TextView
        android:id="@+id/call_status_bar"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="40dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent" />

    <TextView
        android:id="@+id/recording_status_bar"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="20dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent" />

    <ScrollView
        android:id="@+id/chat_box"
        android:layout_width="374dp"
        android:layout_height="294dp"
        android:layout_marginTop="40dp"
        android:layout_marginBottom="20dp"
        app:layout_constraintBottom_toTopOf="@+id/send_message_button"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/button_layout"
        android:orientation="vertical"
        android:gravity="bottom"
        android:layout_gravity="bottom"
        android:fillViewport="true">

        <LinearLayout
            android:id="@+id/chat_box_layout"
            android:orientation="vertical"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:gravity="bottom"
            android:layout_gravity="top"
            android:layout_alignParentBottom="true"/>
    </ScrollView>

    <EditText
        android:id="@+id/message_body"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginHorizontal="20dp"
        android:layout_marginTop="588dp"
        android:ems="10"
        android:inputType="textUri"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        tools:text="Type your message here..."
        tools:visibility="invisible" />

    <Button
        android:id="@+id/send_message_button"
        android:layout_width="138dp"
        android:layout_height="45dp"
        android:layout_marginStart="133dp"
        android:layout_marginTop="48dp"
        android:layout_marginEnd="133dp"
        android:text="Send Message"
        android:visibility="invisible"
        app:layout_constraintBottom_toTopOf="@+id/recording_status_bar"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.428"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/chat_box" />

</androidx.constraintlayout.widget.ConstraintLayout>

A Teams felhasználói felület vezérlőinek engedélyezése

Csomagok importálása és állapotváltozók definiálása

A tartalomhoz MainActivity.javaadja hozzá a következő importálásokat:

import android.graphics.Typeface;
import android.graphics.Color;
import android.text.Html;
import android.os.Handler;
import android.view.Gravity;
import android.view.View;
import android.widget.LinearLayout;
import java.util.Collections;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.List;
import com.azure.android.communication.chat.ChatThreadAsyncClient;
import com.azure.android.communication.chat.ChatThreadClientBuilder;
import com.azure.android.communication.chat.models.ChatMessage;
import com.azure.android.communication.chat.models.ChatMessageType;
import com.azure.android.communication.chat.models.ChatParticipant;
import com.azure.android.communication.chat.models.ListChatMessagesOptions;
import com.azure.android.communication.chat.models.SendChatMessageOptions;
import com.azure.android.communication.common.CommunicationIdentifier;
import com.azure.android.communication.common.CommunicationUserIdentifier;
import com.azure.android.core.rest.util.paging.PagedAsyncStream;
import com.azure.android.core.util.AsyncStreamHandler;

Adja hozzá az MainActivity osztályhoz a következő változókat:

    // InitiatorId is used to differentiate incoming messages from outgoing messages
    private static final String InitiatorId = "<USER_ID>";
    private static final String ResourceUrl = "<COMMUNICATION_SERVICES_RESOURCE_ENDPOINT>";
    private String threadId;
    private ChatThreadAsyncClient chatThreadAsyncClient;
    
    // The list of ids corresponsding to messages which have already been processed
    ArrayList<String> chatMessages = new ArrayList<>();

Cserélje le <USER_ID> a csevegést kezdeményező felhasználó azonosítójára. Cserélje le <COMMUNICATION_SERVICES_RESOURCE_ENDPOINT> a Communication Services-erőforrás végpontját.

A ChatThreadClient inicializálása

Az értekezlethez való csatlakozás után példányosítsa a ChatThreadClient csevegés összetevőit, és tegye láthatóvá a csevegési összetevőket.

Frissítse a metódus végét az MainActivity.joinTeamsMeeting() alábbi kóddal:

    private void joinTeamsMeeting() {
        ...
        EditText threadIdView = findViewById(R.id.teams_meeting_thread_id);
        threadId = threadIdView.getText().toString();
        // Initialize Chat Thread Client
        chatThreadAsyncClient = new ChatThreadClientBuilder()
                .endpoint(ResourceUrl)
                .credential(new CommunicationTokenCredential(UserToken))
                .chatThreadId(threadId)
                .buildAsyncClient();
        Button sendMessageButton = findViewById(R.id.send_message_button);
        EditText messageBody = findViewById(R.id.message_body);
        // Register the method for sending messages and toggle the visibility of chat components
        sendMessageButton.setOnClickListener(l -> sendMessage());
        sendMessageButton.setVisibility(View.VISIBLE);
        messageBody.setVisibility(View.VISIBLE);
        
        // Start the polling for chat messages immediately
        handler.post(runnable);
    }

Üzenetek küldésének engedélyezése

Adja hozzá a sendMessage() metódust a következőhöz MainActivity: ChatThreadClient A felhasználó nevében küld üzeneteket.

    private void sendMessage() {
        // Retrieve the typed message content
        EditText messageBody = findViewById(R.id.message_body);
        // Set request options and send message
        SendChatMessageOptions options = new SendChatMessageOptions();
        options.setContent(messageBody.getText().toString());
        options.setSenderDisplayName("Test User");
        chatThreadAsyncClient.sendMessage(options);
        // Clear the text box
        messageBody.setText("");
    }

Üzenetek lekérdezésének engedélyezése és megjelenítése az alkalmazásban

Fontos

Ismert probléma: Mivel a Csevegő SDK valós idejű értesítési funkciója nem működik együtt a hívó SDK-kkal, előre meghatározott időközönként le kell kérdeznünk az GetMessages API-t. A mintánkban 3 másodperces időközöket használunk.

Az API által GetMessages visszaadott üzenetlistából a következő adatokat szerezhetjük be:

  • A text szál és html az üzenetek a csatlakozás óta
  • A szálak névsorának módosítása
  • Frissítések a tématémakörhöz

MainActivity Az osztályhoz adjon hozzá egy kezelőt és egy futtatható feladatot, amely 3 másodperces időközönként lesz futtatva:

    private Handler handler = new Handler();
    private Runnable runnable = new Runnable() {
        @Override
        public void run() {
            try {
                retrieveMessages();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            // Repeat every 3 seconds
            handler.postDelayed(runnable, 3000);
        }
    };

Vegye figyelembe, hogy a tevékenység már elindult az inicializálási MainActivity.joinTeamsMeeting() lépésben frissített metódus végén.

Végül hozzáadjuk a szál összes akadálymentes üzenetének lekérdezésére szolgáló metódust, elemezzük őket üzenettípus szerint, és megjelenítjük azokat htmltext :

    private void retrieveMessages() throws InterruptedException {
        // Initialize the list of messages not yet processed
        ArrayList<ChatMessage> newChatMessages = new ArrayList<>();
        
        // Retrieve all messages accessible to the user
        PagedAsyncStream<ChatMessage> messagePagedAsyncStream
                = this.chatThreadAsyncClient.listMessages(new ListChatMessagesOptions(), null);
        // Set up a lock to wait until all returned messages have been inspected
        CountDownLatch latch = new CountDownLatch(1);
        // Traverse the returned messages
        messagePagedAsyncStream.forEach(new AsyncStreamHandler<ChatMessage>() {
            @Override
            public void onNext(ChatMessage message) {
                // Messages that should be displayed in the chat
                if ((message.getType().equals(ChatMessageType.TEXT)
                    || message.getType().equals(ChatMessageType.HTML))
                    && !chatMessages.contains(message.getId())) {
                    newChatMessages.add(message);
                    chatMessages.add(message.getId());
                }
                if (message.getType().equals(ChatMessageType.PARTICIPANT_ADDED)) {
                    // Handle participants added to chat operation
                    List<ChatParticipant> participantsAdded = message.getContent().getParticipants();
                    CommunicationIdentifier participantsAddedBy = message.getContent().getInitiatorCommunicationIdentifier();
                }
                if (message.getType().equals(ChatMessageType.PARTICIPANT_REMOVED)) {
                    // Handle participants removed from chat operation
                    List<ChatParticipant> participantsRemoved = message.getContent().getParticipants();
                    CommunicationIdentifier participantsRemovedBy = message.getContent().getInitiatorCommunicationIdentifier();
                }
                if (message.getType().equals(ChatMessageType.TOPIC_UPDATED)) {
                    // Handle topic updated
                    String newTopic = message.getContent().getTopic();
                    CommunicationIdentifier topicUpdatedBy = message.getContent().getInitiatorCommunicationIdentifier();
                }
            }
            @Override
            public void onError(Throwable throwable) {
                latch.countDown();
            }
            @Override
            public void onComplete() {
                latch.countDown();
            }
        });
        // Wait until the operation completes
        latch.await(1, TimeUnit.MINUTES);
        // Returned messages should be ordered by the createdOn field to be guaranteed a proper chronological order
        // For the purpose of this demo we will just reverse the list of returned messages
        Collections.reverse(newChatMessages);
        for (ChatMessage chatMessage : newChatMessages)
        {
            LinearLayout chatBoxLayout = findViewById(R.id.chat_box_layout);
            // For the purpose of this demo UI, we don't need to use HTML formatting for displaying messages
            // The Teams client always sends html messages in meeting chats 
            String message = Html.fromHtml(chatMessage.getContent().getMessage(), Html.FROM_HTML_MODE_LEGACY).toString().trim();
            TextView messageView = new TextView(this);
            messageView.setText(message);
            // Compare with sender identifier and align LEFT/RIGHT accordingly
            // Azure Communication Services users are of type CommunicationUserIdentifier
            CommunicationIdentifier senderId = chatMessage.getSenderCommunicationIdentifier();
            if (senderId instanceof CommunicationUserIdentifier
                && InitiatorId.equals(((CommunicationUserIdentifier) senderId).getId())) {
                messageView.setTextColor(Color.GREEN);
                messageView.setGravity(Gravity.RIGHT);
            } else {
                messageView.setTextColor(Color.BLUE);
                messageView.setGravity(Gravity.LEFT);
            }
            // Note: messages with the deletedOn property set to a timestamp, should be marked as deleted
            // Note: messages with the editedOn property set to a timestamp, should be marked as edited
            messageView.setTypeface(Typeface.SANS_SERIF, Typeface.BOLD);
            chatBoxLayout.addView(messageView);
        }
    }

A csevegőszál résztvevőinek megjelenítendő neveit nem a Teams-ügyfél állítja be. A nevek null értékként jelennek meg az API-ban a résztvevők listázásához, az participantsAdded eseményhez és az participantsRemoved eseményhez. A csevegés résztvevőinek megjelenített nevei lekérhetők az remoteParticipantscall objektum mezőjéből.

Teams-értekezlet csevegési szálának lekérése Egy Communication Services-felhasználó számára

A Teams-értekezlet részletei a Graph dokumentációjában részletezett Graph API-k használatával kérhetők le. A Communication Services Calling SDK teljes Teams-értekezlethivatkozást vagy értekezlet-azonosítót fogad el. Az erőforrás részeként onlineMeeting lesznek visszaadva, amely a joinWebUrl tulajdonság alatt érhető el

A Graph API-kkalthreadID a . A válasz egy chatInfo objektummal rendelkezik, amely tartalmazza a threadID.

A kód futtatása

Az alkalmazás most már elindítható az eszköztár "Alkalmazás futtatása" gombjával (Shift+F10).

A Teams-értekezlethez és csevegéshez való csatlakozáshoz adja meg a csapat értekezlet-hivatkozását és a szálazonosítót a felhasználói felületen.

Miután csatlakozott a csapat értekezletéhez, be kell fogadnia a felhasználót az értekezletbe a csapat ügyfélprogramjában. Miután felvette a felhasználót, és csatlakozott a csevegéshez, üzeneteket küldhet és fogadhat.

Képernyőkép a befejezett Android-alkalmazásról.

Feljegyzés

Bizonyos funkciók jelenleg nem támogatottak a Teamsszel való együttműködési forgatókönyvekben. További információ a támogatott funkciókról: Teams-értekezletek képességei a Teams külső felhasználói számára

Ebben a rövid útmutatóban megtudhatja, hogyan cseveghet Teams-értekezleteken az Azure Communication Services Chat SDK for C# használatával.

Mintakód

Keresse meg a gitHubon a rövid útmutató kódját.

Előfeltételek

Bekapcsolódás az értekezlet csevegésbe

A Communication Services-felhasználók névtelen felhasználóként csatlakozhatnak a Teams-értekezletekhez a Hívás SDK használatával. Az értekezlethez való csatlakozás résztvevőként is hozzáadja őket az értekezlet csevegéséhez, ahol üzeneteket küldhetnek és fogadhatnak az értekezlet többi felhasználójával. A felhasználónak nem lesz hozzáférése az értekezlethez való csatlakozás előtt elküldött csevegőüzenetekhez, és nem tud üzeneteket küldeni vagy fogadni az értekezlet befejezése után. Az értekezlethez való csatlakozáshoz és a csevegés megkezdéséhez kövesse a következő lépéseket.

A kód futtatása

A kódot a Visual Studióban hozhatja létre és futtathatja. Figyelje meg a támogatott megoldásplatformokat: x64,x86 és ARM64.

  1. Nyisson meg egy PowerShell-példányt, Windows Terminált, parancssort vagy azzal egyenértékűt, és keresse meg azt a könyvtárat, amelybe a mintát klónozni szeretné.
  2. git clone https://github.com/Azure-Samples/Communication-Services-dotnet-quickstarts.git
  3. Nyissa meg a ChatTeamsInteropQuickStart/ChatTeamsInteropQuickStart.csproj projektet a Visual Studióban.
  4. Telepítse a következő NuGet-csomagok (vagy újabb) verzióit:
Install-Package Azure.Communication.Calling -Version 1.0.0-beta.29
Install-Package Azure.Communication.Chat -Version 1.1.0
Install-Package Azure.Communication.Common -Version 1.0.1
Install-Package Azure.Communication.Identity -Version 1.0.1

  1. Ha a Communication Services-erőforrás előfeltételként van beszerezve, adja hozzá a kapcsolatláncot a ChatTeamsInteropQuickStart/MainPage.xaml.cs fájlhoz.
//Azure Communication Services resource connection string, i.e., = "endpoint=https://your-resource.communication.azure.net/;accesskey=your-access-key";
private const string connectionString_ = "";

Fontos

  • A kód futtatása előtt válassza ki a megfelelő platformot a Visual Studióban található "Megoldásplatformok" legördülő listából, azazx64
  • Győződjön meg arról, hogy a "Fejlesztői mód" engedélyezve van a Windows 10-ben (fejlesztői Gépház)

A következő lépések nem fognak működni, ha ez nincs megfelelően konfigurálva

  1. Nyomja le az F5 billentyűt a projekt hibakeresési módban való elindításához.
  2. Illessze be az érvényes teams-értekezlet hivatkozását a "Teams-értekezlet hivatkozása" mezőbe (lásd a következő szakaszt)
  3. A csevegés megkezdéséhez nyomja le a "Csatlakozás Teams-értekezlethez" billentyűt.

Fontos

Miután a hívó SDK kapcsolatot létesített a Teams-értekezlettel , lásd: Communication Services-hívó Windows-alkalmazás, a csevegési műveletek kezeléséhez a következő fő funkciók: StartPollingForChatMessages és SendMessageButton_Click. Mindkét kódrészlet a ChatTeamsInteropQuickStart\MainPage.xaml.cs

        /// <summary>
        /// Background task that keeps polling for chat messages while the call connection is stablished
        /// </summary>
        private async Task StartPollingForChatMessages()
        {
            CommunicationTokenCredential communicationTokenCredential = new(user_token_);
            chatClient_ = new ChatClient(EndPointFromConnectionString(), communicationTokenCredential);
            await Task.Run(async () =>
            {
                keepPolling_ = true;

                ChatThreadClient chatThreadClient = chatClient_.GetChatThreadClient(thread_Id_);
                int previousTextMessages = 0;
                while (keepPolling_)
                {
                    try
                    {
                        CommunicationUserIdentifier currentUser = new(user_Id_);
                        AsyncPageable<ChatMessage> allMessages = chatThreadClient.GetMessagesAsync();
                        SortedDictionary<long, string> messageList = new();
                        int textMessages = 0;
                        string userPrefix;
                        await foreach (ChatMessage message in allMessages)
                        {
                            if (message.Type == ChatMessageType.Html || message.Type == ChatMessageType.Text)
                            {
                                textMessages++;
                                userPrefix = message.Sender.Equals(currentUser) ? "[you]:" : "";
                                messageList.Add(long.Parse(message.SequenceId), $"{userPrefix}{StripHtml(message.Content.Message)}");
                            }
                        }

                        //Update UI just when there are new messages
                        if (textMessages > previousTextMessages)
                        {
                            previousTextMessages = textMessages;
                            await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
                            {
                                TxtChat.Text = string.Join(Environment.NewLine, messageList.Values.ToList());
                            });

                        }
                        if (!keepPolling_)
                        {
                            return;
                        }

                        await SetInCallState(true);
                        await Task.Delay(3000);
                    }
                    catch (Exception e)
                    {
                        await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
                        {
                            _ = new MessageDialog($"An error occurred while fetching messages in PollingChatMessagesAsync(). The application will shutdown. Details : {e.Message}").ShowAsync();
                            throw e;
                        });
                        await SetInCallState(false);
                    }
                }
            });
        }
        private async void SendMessageButton_Click(object sender, RoutedEventArgs e)
        {
            SendMessageButton.IsEnabled = false;
            ChatThreadClient chatThreadClient = chatClient_.GetChatThreadClient(thread_Id_);
            _ = await chatThreadClient.SendMessageAsync(TxtMessage.Text);
            
            TxtMessage.Text = "";
            SendMessageButton.IsEnabled = true;
        }

A Teams-értekezlet hivatkozása a Graph dokumentációjában részletezett Graph API-k használatával kérhető le. Ez a hivatkozás az onlineMeeting erőforrás részeként jelenik meg, amely a joinWebUrl tulajdonság alatt érhető el.

A szükséges értekezlet-hivatkozást a Teams-értekezlet-összehívásban található Bekapcsolódás értekezlet URL-címéről is lekérheti. A Teams-értekezletek hivatkozása a következőképpen néz ki: https://teams.microsoft.com/l/meetup-join/meeting_chat_thread_id/1606337455313?context=some_context_here. Ha a teams-hivatkozás formátuma eltér ehhez, le kell kérnie a szálazonosítót a Graph API használatával.

Képernyőkép a kész csharp-alkalmazásról.

Feljegyzés

Bizonyos funkciók jelenleg nem támogatottak a Teamsszel való együttműködési forgatókönyvekben. További információ a támogatott funkciókról: Teams-értekezletek képességei a Teams külső felhasználói számára

Az erőforrások eltávolítása

Ha törölni és eltávolítani szeretne egy Communication Services-előfizetést, törölheti az erőforrást vagy az erőforráscsoportot. Az erőforráscsoport törlése a hozzá társított egyéb erőforrásokat is törli. További információ az erőforrások tisztításáról.

Következő lépések

További információért tekintse át az alábbi cikkeket: