Mulai Cepat: Bergabung menggunakan aplikasi obrolan Anda ke rapat Teams
Mulai menggunakan Azure Communication Services dengan menyambungkan solusi obrolan Anda ke Microsoft Teams.
Dalam mulai cepat ini, Anda akan mempelajari cara melakukan obrolan dalam rapat Teams menggunakan Azure Communication Services Chat SDK untuk JavaScript.
Kode Sampel
Menemukan kode final untuk mulai cepat ini di GitHub.
Prasyarat
- Penyebaran Teams.
- Aplikasi obrolan yang berfungsi.
Bergabung dalam obrolan rapat
Pengguna Communication Services dapat bergabung dengan rapat tim sebagai pengguna anonim menggunakan SDK Panggilan. Bergabung dalam rapat menambahkan mereka sebagai peserta ke obrolan rapat juga, di mana mereka bisa mengirim dan menerima pesan dengan pengguna lain dalam rapat. Pengguna tidak akan memiliki akses ke pesan obrolan yang dikirim sebelum mereka bergabung dalam rapat dan mereka tidak akan dapat mengirim atau menerima pesan setelah rapat berakhir. Anda dapat mengikuti langkah-langkah berikut untuk bergabung dalam rapat dan memulai obrolan.
Membuat aplikasi Node.js baru
Buka terminal atau jendela perintah, buat direktori baru untuk aplikasi Anda, dan navigasi ke sana.
mkdir chat-interop-quickstart && cd chat-interop-quickstart
Jalankan npm init -y
untuk membuat file package.json dengan pengaturan default.
npm init -y
Memasang paket obrolan
Gunakan perintah npm install
untuk menginstal Communication Services SDK yang diperlukan JavaScript.
npm install @azure/communication-common --save
npm install @azure/communication-identity --save
npm install @azure/communication-chat --save
npm install @azure/communication-calling --save
Opsi --save
mencantumkan pustaka sebagai dependensi di file package.json Anda.
Menyiapkan kerangka kerja aplikasi
Mulai cepat ini menggunakan Webpack untuk memaketkan aset aplikasi. Jalankan perintah berikut untuk menginstal paket npm Webpack, webpack-cli, dan webpack-dev-server dan cantumkan sebagai dependensi pengembangan di package.json Anda:
npm install webpack@5.89.0 webpack-cli@5.1.4 webpack-dev-server@4.15.1 --save-dev
Buat file index.html di direktori akar proyek Anda. Kami menggunakan file ini untuk mengonfigurasi tata letak dasar yang akan memungkinkan pengguna bergabung dalam rapat dan mulai mengobrol.
Menambahkan kontrol UI Teams
Ganti kode di index.html dengan cuplikan berikut. Kotak teks di bagian atas halaman akan digunakan untuk memasukkan konteks rapat Teams. Tombol 'Gabung Rapat Teams' digunakan untuk bergabung dalam rapat yang ditentukan. Pop-up obrolan muncul di bagian bawah halaman. Ini dapat digunakan untuk mengirim pesan di utas rapat, dan ditampilkan secara real time setiap pesan yang dikirim di utas saat pengguna Communication Services adalah anggota.
<!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>
Mengaktifkan kontrol Teams UI
Ganti isi file client.js dengan cuplikan berikut.
Dalam cuplikan kode, ganti
SECRET_CONNECTION_STRING
dengan string koneksi Communication Service Anda
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}`);
});
Nama tampilan peserta utas obrolan tidak diatur oleh klien Teams. Nama dikembalikan sebagai null di API untuk mencantumkan peserta, dalam participantsAdded
peristiwa dan dalam participantsRemoved
peristiwa. Nama tampilan peserta obrolan dapat diambil dari bidang remoteParticipants
dari objek call
. Saat menerima pemberitahuan tentang perubahan daftar, Anda dapat menggunakan kode ini untuk mengambil nama pengguna yang telah ditambahkan atau dihapus:
var displayName = call.remoteParticipants.find(p => p.identifier.communicationUserId == '<REMOTE_USER_ID>').displayName;
Menjalankan kode
Pengguna Webpack dapat menggunakan webpack-dev-server
untuk membuat dan menjalankan aplikasi Anda. Jalankan perintah berikut untuk memaketkan host aplikasi di webserver lokal:
npx webpack-dev-server --entry ./client.js --output bundle.js --debug --devtool inline-source-map
Buka browser Anda dan buka http://localhost:8080/
. Anda akan melihat aplikasi diluncurkan seperti yang ditunjukkan pada cuplikan layar berikut:
Sisipkan tautan rapat Teams ke dalam kotak teks. Tekan Ikut Rapat Teams untuk bergabung dalam rapat Teams. Setelah pengguna Communication Services diterima dalam rapat, Anda bisa melakukan obrolan dari aplikasi Communication Services Anda. Navigasi ke kotak di bagian bawah halaman untuk memulai obrolan. Untuk kesederhanaan, aplikasi hanya menunjukkan dua pesan terakhir dalam obrolan.
Catatan
Fitur tertentu saat ini tidak didukung untuk skenario interoperabilitas dengan Teams. Pelajari selengkapnya tentang fitur yang didukung, silakan lihat Kemampuan rapat Teams untuk pengguna eksternal Teams
Dalam mulai cepat ini, Anda akan mempelajari cara mengobrol dalam rapat Teams menggunakan SDK Azure Communication Services Chat untuk iOS.
Kode Sampel
Jika Anda ingin melompati ke bagian akhir, Anda dapat mengunduh mulai cepat ini sebagai sampel di GitHub.
Prasyarat
- Akun Azure dengan langganan aktif. Membuat akun secara gratis
- Mac yang menjalankan Xcode, bersama dengan sertifikat pengembang valid yang diinstal ke rantai kunci Anda.
- Penyebaran Teams.
- Token Akses Pengguna untuk Azure Communication Service. Anda juga dapat menggunakan Azure CLI dan menjalankan perintah dengan string koneksi Anda untuk membuat pengguna dan token akses.
az communication identity token issue --scope voip --connection-string "yourConnectionString"
Untuk detailnya, lihat Menggunakan Azure CLI untuk Membuat dan Mengelola Token Akses.
Menyiapkan
Membuat proyek Xcode
Di Xcode, buat proyek iOS baru dan pilih templat Aplikasi Tampilan Tunggal. Tutorial ini menggunakan kerangka kerja SwiftUI, jadi Anda harus mengatur Bahasa ke Swift dan Antarmuka Pengguna ke SwiftUI. Anda tidak akan membuat tes selama mulai cepat ini. Jangan ragu untuk menghapus centang Sertakan Pengujian.
Menginstal CocoaPods
Gunakan panduan ini untuk menginstal CocoaPods di Mac Anda.
Memasang paket dan dependensi dengan CocoaPods
Untuk membuat
Podfile
untuk aplikasi Anda, buka terminal dan navigasikan ke folder proyek dan jalankan init pod.Tambahkan kode berikut ke
Podfile
di bawah target, dan simpan.
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
Jalankan
pod install
..xcworkspace
Buka file dengan Xcode.
Minta akses ke mikrofon
Untuk mengakses mikrofon perangkat, Anda perlu memperbarui Daftar Properti Informasi aplikasi Anda dengan NSMicrophoneUsageDescription
. Anda mengatur nilai terkait ke string
yang disertakan dalam dialog yang digunakan sistem untuk meminta akses dari pengguna.
Di bawah target, pilih tab Info
dan tambahkan string untuk 'Privasi - Deskripsi Penggunaan Mikrofon'
Menonaktifkan Sandboxing Skrip Pengguna
Beberapa skrip dalam pustaka tertaut menulis file selama proses build. Untuk mengizinkan ini, nonaktifkan Sandboxing Skrip Pengguna di Xcode.
Di bawah pengaturan build, cari sandbox
dan atur User Script Sandboxing
ke No
.
Bergabung dalam obrolan rapat
Pengguna Communication Services dapat bergabung dengan rapat tim sebagai pengguna anonim menggunakan SDK Panggilan. Setelah pengguna bergabung dalam rapat Teams, mereka dapat mengirim dan menerima pesan dengan peserta rapat lainnya. Pengguna tidak akan memiliki akses ke pesan obrolan yang dikirim sebelum bergabung, mereka juga tidak akan dapat mengirim atau menerima pesan saat mereka tidak berada dalam rapat. Anda dapat mengikuti langkah-langkah berikut untuk bergabung dalam rapat dan memulai obrolan.
Menyiapkan kerangka kerja aplikasi
Impor paket Azure Communication dengan ContentView.swift
menambahkan cuplikan berikut:
import AVFoundation
import SwiftUI
import AzureCommunicationCalling
import AzureCommunicationChat
Dalam ContentView.swift
tambahkan cuplikan berikut, tepat di struct ContentView: View
atas deklarasi:
let endpoint = "<ADD_YOUR_ENDPOINT_URL_HERE>"
let token = "<ADD_YOUR_USER_TOKEN_HERE>"
let displayName: String = "Quickstart User"
Ganti <ADD_YOUR_ENDPOINT_URL_HERE>
dengan titik akhir untuk sumber daya Communication Services Anda.
Ganti <ADD_YOUR_USER_TOKEN_HERE>
dengan token yang dihasilkan di atas, melalui baris perintah klien Azure.
Baca selengkapnya tentang token akses pengguna: Token Akses Pengguna
Ganti Quickstart User
dengan nama tampilan yang ingin Anda gunakan di Chat.
Untuk menahan status, tambahkan variabel berikut ke ContentView
struct:
@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] = []
Sekarang mari kita tambahkan var tubuh utama untuk menahan elemen UI. Kami melampirkan logika bisnis ke kontrol ini dalam mulai cepat ini. Tambahkan kode berikut ke ContentView
struct:
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
}
}
Inisialisasi ChatClient
Buat instans dan aktifkan ChatClient
pemberitahuan pesan. Kami menggunakan pemberitahuan real-time untuk menerima pesan obrolan.
Dengan penyiapan isi utama, mari kita tambahkan fungsi untuk menangani penyiapan klien panggilan dan obrolan.
onAppear
Dalam fungsi , tambahkan kode berikut untuk menginisialisasi CallClient
dan ChatClient
:
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
}
Menambahkan fungsi gabungan rapat
Tambahkan fungsi berikut ke ContentView
struct untuk menangani bergabung dalam rapat.
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"
}
}
}
Menginisialisasi ChatThreadClient
Kami akan menginisialisasi ChatThreadClient
setelah pengguna bergabung dalam rapat. Ini mengharuskan kita untuk memeriksa status rapat dari delegasi dan kemudian menginisialisasi ChatThreadClient
dengan threadId
ketika bergabung ke rapat.
connectChat()
Buat fungsi dengan kode berikut:
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
}
}
Tambahkan fungsi pembantu berikut ke ContentView
, yang digunakan untuk mengurai ID utas Obrolan dari tautan rapat Tim, jika memungkinkan. Jika ekstraksi ini gagal, pengguna harus memasukkan ID utas Obrolan secara manual menggunakan API Graph untuk mengambil ID utas.
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
}
Aktifkan pengiriman pesan
Tambahkan fungsi sendMessage()
ke ContentView
. Fungsi ini menggunakan ChatThreadClient
untuk mengirim pesan dari pengguna.
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?"
}
}
}
Aktifkan penerimaan pesan
Untuk menerima pesan, kami menerapkan handler untuk ChatMessageReceived
peristiwa. Ketika pesan baru dikirim ke utas, handler ini menambahkan pesan ke meetingMessages
variabel sehingga dapat ditampilkan di UI.
Pertama tambahkan struktur berikut ke ContentView.swift
. UI menggunakan data dalam struktur untuk menampilkan pesan Obrolan kami.
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
)
}
}
Selanjutnya tambahkan fungsi receiveMessage()
ke ContentView
. Ini disebut ketika peristiwa olahpesan terjadi. Perhatikan bahwa Anda perlu mendaftar untuk semua peristiwa yang ingin Anda tangani dalam switch
pernyataan melalui chatClient?.register()
metode .
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
}
}
Terakhir, kita perlu mengimplementasikan penangan delegasi untuk klien panggilan. Handler ini digunakan untuk memeriksa status panggilan dan menginisialisasi klien obrolan saat pengguna bergabung dalam rapat.
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"
}
}
}
Tinggalkan obrolan
Saat pengguna keluar dari rapat Tim, kami menghapus pesan Obrolan dari UI dan menutup panggilan. Kode lengkap ditampilkan di bawah ini.
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"
}
}
Mendapatkan utas obrolan rapat Teams untuk pengguna Communication Services
Detail rapat Teams dapat diambil menggunakan Graph API, yang diperinci dalam dokumentasi Graph. SDK Panggilan Communication Services menerima tautan rapat Teams lengkap atau ID rapat. Mereka dikembalikan sebagai bagian onlineMeeting
dari sumber daya, dapat diakses di joinWebUrl
bawah properti
Dengan Graph API, Anda juga bisa mendapatkan threadID
. Respons memiliki chatInfo
objek yang berisi threadID
.
Menjalankan kode
Jalankan aplikasi lagi.
Untuk bergabung dalam rapat Teams, masukkan tautan rapat Tim Anda di UI.
Setelah bergabung dalam rapat Tim, Anda perlu memasukkan pengguna ke rapat di klien Tim Anda. Setelah pengguna diterima dan telah bergabung dengan obrolan, Anda dapat mengirim dan menerima pesan.
Catatan
Fitur tertentu saat ini tidak didukung untuk skenario interoperabilitas dengan Teams. Pelajari selengkapnya tentang fitur yang didukung, silakan lihat Kemampuan rapat Teams untuk pengguna eksternal Teams
Dalam mulai cepat ini, Anda akan mempelajari cara mengobrol dalam rapat Teams menggunakan SDK Azure Communication Services Chat untuk Android.
Kode Sampel
Jika Anda ingin melompati ke bagian akhir, Anda dapat mengunduh mulai cepat ini sebagai sampel di GitHub.
Prasyarat
- Penyebaran Teams.
- Aplikasi panggilan yang berfungsi.
Aktifkan interoperabilitas Teams
Pengguna Communication Services yang bergabung dalam rapat Teams sebagai pengguna tamu hanya dapat mengakses obrolan rapat saat mereka telah bergabung dalam panggilan rapat Teams. Lihat dokumentasi interoperabilitas Teams untuk mempelajari cara menambahkan pengguna Communication Services ke panggilan rapat Teams.
Anda harus menjadi anggota organisasi pemilik dari kedua entitas untuk menggunakan fitur ini.
Bergabung dalam obrolan rapat
Setelah interoperabilitas Teams diaktifkan, pengguna Communication Services dapat bergabung dengan panggilan Teams sebagai pengguna eksternal menggunakan Calling SDK. Bergabung dengan panggilan menambahkan mereka sebagai peserta ke obrolan rapat juga, di mana mereka bisa mengirim dan menerima pesan dengan pengguna lain pada panggilan. Pengguna tidak memiliki akses ke pesan obrolan yang dikirim sebelum mereka bergabung dalam panggilan. Anda dapat mengikuti langkah-langkah berikut untuk bergabung dalam rapat dan memulai obrolan.
Menambahkan Obrolan ke dalam aplikasi panggilan Teams
Di tingkat build.gradle
modul Anda , tambahkan dependensi pada SDK obrolan.
Penting
Masalah yang diketahui: Saat menggunakan Android Chat dan Calling SDK secara bersamaan dalam aplikasi yang sama, fitur notifikasi waktu nyata Chat SDK tidak berfungsi. Anda akan mendapatkan masalah resolusi dependensi. Saat sedang mengerjakan solusi, Anda dapat menonaktifkan fitur notifikasi secara real-time dengan menambahkan pengecualian berikut ke dependensi Chat SDK dalam file build.gradle
aplikasi:
implementation ("com.azure.android:azure-communication-chat:2.0.3") {
exclude group: 'com.microsoft', module: 'trouter-client-android'
}
Menambahkan tata letak antarmuka pengguna Teams
Ganti kode di activity_main.xml dengan cuplikan kode berikut. Ini menambahkan input untuk ID utas dan untuk mengirim pesan, tombol untuk mengirim pesan yang diketik dan tata letak obrolan dasar.
<?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>
Mengaktifkan kontrol Teams UI
Mengimpor paket dan menentukan variabel status
Ke konten MainActivity.java
, tambahkan impor berikut:
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;
Tambahkan variabel berikut ke kelas MainActivity
:
// 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<>();
Ganti <USER_ID>
dengan ID pengguna yang memulai obrolan.
Ganti <COMMUNICATION_SERVICES_RESOURCE_ENDPOINT>
dengan titik akhir untuk sumber daya Communication Services Anda.
Menginisialisasi ChatThreadClient
Setelah bergabung dalam rapat, buatlah instans ChatThreadClient
dan jadikan komponen obrolan terlihat.
Perbarui akhir metode MainActivity.joinTeamsMeeting()
dengan kode di bawah ini:
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);
}
Aktifkan pengiriman pesan
Tambahkan metode sendMessage()
ke MainActivity
. Ini menggunakan ChatThreadClient
untuk mengirim pesan atas nama pengguna.
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("");
}
Aktifkan polling untuk pesan dan merender pesan dalam aplikasi
Penting
Masalah yang diketahui: Karena fitur notifikasi real-time Chat SDK tidak berfungsi bersama dengan SDK Panggilan, kita harus melakukan polling API GetMessages
pada interval yang telah ditentukan. Dalam sampel kami, kami akan menggunakan interval 3 detik.
Kami dapat memperoleh data berikut dari daftar pesan yang dikembalikan oleh API GetMessages
:
- Pesan
text
danhtml
berada pada utas sejak bergabung - Perubahan pada daftar utas
- Pembaruan pada topik utas
MainActivity
Ke kelas , tambahkan handler dan tugas yang dapat dijalankan yang akan dijalankan pada interval 3 detik:
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);
}
};
Perhatikan bahwa tugas telah dimulai di akhir metode MainActivity.joinTeamsMeeting()
yang diperbarui dalam langkah inisialisasi.
Terakhir, kami menambahkan metode untuk mengkueri semua pesan yang dapat diakses di utas, mengurainya berdasarkan jenis pesan dan menampilkan html
pesan dan text
:
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);
}
}
Nama tampilan peserta utas obrolan tidak diatur oleh klien Teams. Nama dikembalikan sebagai null di API untuk mencantumkan peserta, dalam participantsAdded
peristiwa dan dalam participantsRemoved
peristiwa. Nama tampilan peserta obrolan dapat diambil dari bidang remoteParticipants
dari objek call
.
Mendapatkan utas obrolan rapat Teams untuk pengguna Communication Services
Detail rapat Teams dapat diambil menggunakan Graph API, yang diperinci dalam dokumentasi Graph. SDK Panggilan Communication Services menerima tautan rapat Teams lengkap atau ID rapat. Mereka dikembalikan sebagai bagian onlineMeeting
dari sumber daya, dapat diakses di joinWebUrl
bawah properti
Dengan Graph API, Anda juga bisa mendapatkan threadID
. Respons memiliki chatInfo
objek yang berisi threadID
.
Menjalankan kode
Aplikasi kini dapat diluncurkan menggunakan tombol "Jalankan Aplikasi" pada toolbar (Shift+F10).
Untuk bergabung dalam rapat Teams, masukkan tautan rapat Teams Anda dan ID utas di antarmuka pengguna.
Setelah bergabung dalam rapat Tim, Anda perlu memasukkan pengguna ke rapat di klien Tim Anda. Setelah pengguna diterima dan telah bergabung dengan obrolan, Anda dapat mengirim dan menerima pesan.
Catatan
Fitur tertentu saat ini tidak didukung untuk skenario interoperabilitas dengan Teams. Pelajari selengkapnya tentang fitur yang didukung, silakan lihat Kemampuan rapat Teams untuk pengguna eksternal Teams
Dalam mulai cepat ini, Anda mempelajari cara mengobrol dalam rapat Teams menggunakan Azure Communication Services Chat SDK untuk C#.
Kode Sampel
Temukan kode untuk mulai cepat ini di GitHub.
Prasyarat
- Penyebaran Teams.
- Akun Azure dengan langganan aktif. Buat akun secara gratis.
- Pasang Visual Studio 2019 dengan beban kerja pengembangan Universal Windows Platform.
- Sumber daya Communication Services yang disebarkan. Buat sumber daya Azure Communication Services.
- Tautan Rapat Teams.
Bergabung dalam obrolan rapat
Pengguna Communication Services dapat bergabung dengan rapat tim sebagai pengguna anonim menggunakan SDK Panggilan. Bergabung dalam rapat menambahkan mereka sebagai peserta ke obrolan rapat juga, di mana mereka bisa mengirim dan menerima pesan dengan pengguna lain dalam rapat. Pengguna tidak akan memiliki akses ke pesan obrolan yang dikirim sebelum mereka bergabung dalam rapat, dan mereka tidak akan dapat mengirim atau menerima pesan setelah rapat berakhir. Anda dapat mengikuti langkah-langkah berikut untuk bergabung dalam rapat dan memulai obrolan.
Menjalankan kode
Anda dapat membangun dan menjalankan kode di Visual Studio. Perhatikan platform solusi yang kami dukung: x64
,x86
, dan ARM64
.
- Buka instans PowerShell, Terminal Windows, Prompt Perintah, atau yang setara dan navigasikan ke direktori yang ingin Anda kloning sampelnya.
git clone https://github.com/Azure-Samples/Communication-Services-dotnet-quickstarts.git
- Buka proyek ChatTeamsInteropQuickStart/ChatTeamsInteropQuickStart.csproj di Visual Studio.
- Pasang versi paket NuGet berikut (atau lebih tinggi):
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
- Dengan sumber daya Communication Services yang diakui dalam prasyarat, tambahkan connectionstring ke file ChatTeamsInteropQuickStart/MainPage.xaml.cs .
//Azure Communication Services resource connection string, i.e., = "endpoint=https://your-resource.communication.azure.net/;accesskey=your-access-key";
private const string connectionString_ = "";
Penting
- Pilih platform yang tepat dari daftar dropdown 'Platform Solusi' di Visual Studio sebelum menjalankan kode, yaitu,
x64
- Pastikan Anda mengaktifkan 'Mode Pengembang' di Windows 10 diaktifkan (Pengaturan Pengembang)
Langkah selanjutnya tidak akan berfungsi jika ini tidak dikonfigurasi dengan benar
- Tekan F5 untuk memulai proyek dalam mode debugging.
- Menempelkan tautan rapat teams yang valid pada kotak 'Tautan Rapat Teams' (lihat bagian berikutnya)
- Tekan 'Bergabung dengan rapat Teams' untuk mulai mengobrol.
Penting
Setelah SDK panggilan membuat koneksi dengan rapat teams Lihat aplikasi Windows yang memanggil Azure Communication Services, fungsi utama untuk menangani operasi obrolan adalah: StartPollingForChatMessages dan SendMessageButton_Click. Kedua cuplikan kode berada di 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;
}
Mendapatkan tautan rapat Teams
Tautan rapat Teams dapat diambil menggunakan Graph API, yang diperinci dalam dokumentasi Graph. Tautan ini dikembalikan sebagai bagian dari sumber daya onlineMeeting
, yang dapat diakses di dalam properti joinWebUrl
.
Anda juga dapat memperoleh tautan rapat yang diperlukan dari URL Bergabung ke Rapat di undangan rapat Teams itu sendiri.
Link rapat Teams terlihat seperti ini: https://teams.microsoft.com/l/meetup-join/meeting_chat_thread_id/1606337455313?context=some_context_here
.
Jika tautan tim Anda memiliki format yang berbeda dengan ini, Anda perlu mengambil ID utas menggunakan Graph API.
Catatan
Fitur tertentu saat ini tidak didukung untuk skenario interoperabilitas dengan Teams. Pelajari selengkapnya tentang fitur yang didukung, silakan lihat Kemampuan rapat Teams untuk pengguna eksternal Teams
Membersihkan sumber daya
Jika ingin membersihkan dan menghapus langganan Azure Communication Services, Anda bisa menghapus sumber daya atau grup sumber daya. Menghapus grup sumber daya juga menghapus sumber daya apa pun yang terkait dengannya. Pelajari selengkapnya tentang membersihkan sumber daya.
Langkah berikutnya
Untuk informasi lebih lanjut, baca artikel berikut:
- Lihat contoh pahlawan obrolan kami
- Pelajari selengkapnya tentang cara kerja obrolan