Hızlı Başlangıç: Sohbet uygulamanızı Teams toplantısına ekleme
Sohbet çözümünüzü Microsoft Teams'e bağlayarak Azure İletişim Hizmetleri kullanmaya başlayın.
Bu hızlı başlangıçta, JavaScript için Azure İletişim Hizmetleri Sohbet SDK'sını kullanarak Teams toplantısında sohbet etmeyi öğreneceksiniz.
Örnek Kod
GitHub'da bu hızlı başlangıcın son halini alan kodu bulun.
Önkoşullar
- Teams dağıtımı.
- Çalışan bir sohbet uygulaması.
Toplantı sohbete katılma
İletişim Hizmetleri kullanıcısı, Arama SDK'sını kullanarak teams toplantısına anonim kullanıcı olarak katılabilir. Toplantıya katılmak, toplantıdaki diğer kullanıcılarla ileti gönderip alabilecekleri toplantı sohbetine de katılımcı olarak ekler. Kullanıcı, toplantıya katılmadan önce gönderilen sohbet iletilerine erişemez ve toplantı sona erdikten sonra ileti gönderemez veya alamaz. Toplantıya katılmak ve sohbet etmeye başlamak için sonraki adımları izleyebilirsiniz.
Yeni bir Node.js uygulaması oluşturma
Terminalinizi veya komut pencerenizi açın, uygulamanız için yeni bir dizin oluşturun ve bu dizine gidin.
mkdir chat-interop-quickstart && cd chat-interop-quickstart
Varsayılan ayarlarla bir package.json dosyası oluşturmak için komutunu çalıştırınnpm init -y
.
npm init -y
Sohbet paketlerini yükleme
npm install
JavaScript için gerekli İletişim Hizmetleri SDK'larını yüklemek için komutunu kullanın.
npm install @azure/communication-common --save
npm install @azure/communication-identity --save
npm install @azure/communication-chat --save
npm install @azure/communication-calling --save
seçeneği--save
, kitaplığı package.json dosyanızda bağımlılık olarak listeler.
Uygulama çerçevesini ayarlama
Bu hızlı başlangıçta uygulama varlıklarını paketlemek için Webpack kullanılır. Webpack, webpack-cli ve webpack-dev-server npm paketlerini yüklemek ve bunları package.json geliştirme bağımlılıkları olarak listelemek için aşağıdaki komutu çalıştırın:
npm install webpack@5.89.0 webpack-cli@5.1.4 webpack-dev-server@4.15.1 --save-dev
Projenizin kök dizininde bir index.html dosyası oluşturun. Bu dosyayı, kullanıcının toplantıya katılmasına ve sohbet etmeye başlamasına olanak sağlayacak temel bir düzen yapılandırmak için kullanırız.
Teams kullanıcı arabirimi denetimlerini ekleme
index.html içindeki kodu aşağıdaki kod parçacığıyla değiştirin. Sayfanın üst kısmındaki metin kutusu, Teams toplantı bağlamını girmek için kullanılır. Belirtilen toplantıya katılmak için 'Teams Toplantısına Katıl' düğmesi kullanılır. Sayfanın en altında bir sohbet açılır penceresi görüntülenir. Toplantı iş parçacığında ileti göndermek için kullanılabilir ve İletişim Hizmetleri kullanıcısı üyeyken yazışmada gönderilen tüm iletiler gerçek zamanlı olarak görüntülenir.
<!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>
Teams kullanıcı arabirimi denetimlerini etkinleştirme
client.js dosyasının içeriğini aşağıdaki kod parçacığıyla değiştirin.
Kod parçacığının içinde
SECRET_CONNECTION_STRING
İletişim Hizmetinizin bağlantı dizesi
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}`);
});
Sohbet yazışması katılımcılarının görünen adları Teams istemcisi tarafından ayarlanmamıştır. Adlar, etkinlikte ve etkinlikte katılımcıları listelemek için API'de participantsAdded
participantsRemoved
null olarak döndürülür. Sohbet katılımcılarının görünen adları nesnenin remoteParticipants
alanından call
alınabilir. Liste değişikliğiyle ilgili bir bildirim aldıktan sonra, eklenen veya kaldırılan kullanıcının adını almak için bu kodu kullanabilirsiniz:
var displayName = call.remoteParticipants.find(p => p.identifier.communicationUserId == '<REMOTE_USER_ID>').displayName;
Kodu çalıştırma
Webpack kullanıcıları uygulamanızı derlemek ve çalıştırmak için uygulamasını webpack-dev-server
kullanabilir. Uygulama konağınızı yerel bir web sunucusunda paketlemek için aşağıdaki komutu çalıştırın:
npx webpack-dev-server --entry ./client.js --output bundle.js --debug --devtool inline-source-map
Tarayıcınızı açın ve adresine http://localhost:8080/
gidin. Aşağıdaki ekran görüntüsünde gösterildiği gibi uygulamanın başlatıldığını görmeniz gerekir:
Teams toplantı bağlantısını metin kutusuna ekleyin. Teams toplantısına katılmak için Teams Toplantısına Katıl'a basın. İletişim Hizmetleri kullanıcısı toplantıya kabul edildikten sonra İletişim Hizmetleri uygulamanızın içinden sohbet edebilirsiniz. Sohbete başlamak için sayfanın alt kısmındaki kutuya gidin. Kolaylık olması için uygulama yalnızca sohbetteki son iki iletiyi gösterir.
Not
Teams ile birlikte çalışabilirlik senaryolarında şu anda bazı özellikler desteklenmemektedir. Desteklenen özellikler hakkında daha fazla bilgi edinmek için bkz . Teams dış kullanıcıları için Teams toplantı özellikleri
Bu hızlı başlangıçta, iOS için Azure İletişim Hizmetleri Sohbet SDK'sını kullanarak Teams toplantısında sohbet etmeyi öğreneceksiniz.
Örnek Kod
Sonuna atlamak isterseniz bu hızlı başlangıcı GitHub'da örnek olarak indirebilirsiniz.
Önkoşullar
- Etkin aboneliği olan bir Azure hesabı. Ücretsiz hesap oluşturma
- Anahtar zincirinize yüklenmiş geçerli bir geliştirici sertifikasının yanı sıra Xcode çalıştıran bir Mac.
- Teams dağıtımı.
- Azure İletişim Hizmetiniz için Kullanıcı Erişim Belirteci. Ayrıca Azure CLI'yi kullanabilir ve komutunu bağlantı dizesi ile çalıştırarak bir kullanıcı ve erişim belirteci oluşturabilirsiniz.
az communication identity token issue --scope voip --connection-string "yourConnectionString"
Ayrıntılar için bkz . Erişim Belirteçleri Oluşturmak ve Yönetmek için Azure CLI kullanma.
Ayarlama
Xcode projesi oluşturma
Xcode'da yeni bir iOS projesi oluşturun ve Tek Görünüm Uygulaması şablonunu seçin. Bu öğreticide SwiftUI çerçevesi kullanılır, bu nedenle Dili Swift olarak ve Kullanıcı Arabirimini SwiftUI olarak ayarlamanız gerekir. Bu hızlı başlangıç sırasında test oluşturmayacaksınız. Testleri Dahil Et seçeneğinin işaretini kaldırabilirsiniz.
CocoaPods'u yükleme
Mac bilgisayarınıza CocoaPods yüklemek için bu kılavuzu kullanın.
CocoaPods ile paketi ve bağımlılıkları yükleme
Uygulamanız için bir
Podfile
oluşturmak için terminali açın ve proje klasörüne gidin ve pod init komutunu çalıştırın.Aşağıdaki kodu hedefin
Podfile
altına ekleyin ve kaydedin.
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
pod install
'i çalıştırın..xcworkspace
Dosyayı Xcode ile açın.
Mikrofona erişim isteme
Cihazın mikrofona erişmek için uygulamanızın Bilgi Özellik Listesi'ni ile NSMicrophoneUsageDescription
güncelleştirmeniz gerekir. İlişkili değeri, sistemin kullanıcıdan erişim istemek için kullandığı iletişim kutusuna eklenmiş bir string
değere ayarlarsınız.
Hedefin altında, sekmeyi Info
seçin ve 'Gizlilik - Mikrofon Kullanımı Açıklaması' için bir dize ekleyin
Kullanıcı Betiği Korumalı Alanını Devre Dışı Bırakma
Bağlantılı kitaplıklar içindeki betiklerden bazıları derleme işlemi sırasında dosya yazar. Buna izin vermek için Xcode'da Kullanıcı Betiği Korumalı Alanını devre dışı bırakın.
Derleme ayarları altında öğesini arayın sandbox
ve olarak No
ayarlayınUser Script Sandboxing
.
Toplantı sohbete katılma
İletişim Hizmetleri kullanıcısı, Arama SDK'sını kullanarak teams toplantısına anonim kullanıcı olarak katılabilir. Bir kullanıcı Teams toplantısına katıldıktan sonra diğer toplantı katılımcılarına ileti gönderebilir ve alabilir. Kullanıcı, katılmadan önce gönderilen sohbet iletilerine erişemez veya toplantıda olmadığında ileti gönderip alamaz. Toplantıya katılmak ve sohbet etmeye başlamak için sonraki adımları izleyebilirsiniz.
Uygulama çerçevesini ayarlama
Aşağıdaki kod parçacığını ekleyerek Azure İletişim paketlerini içeri ContentView.swift
aktarın:
import AVFoundation
import SwiftUI
import AzureCommunicationCalling
import AzureCommunicationChat
içinde ContentView.swift
bildiriminin hemen üstüne aşağıdaki kod parçacığını struct ContentView: View
ekleyin:
let endpoint = "<ADD_YOUR_ENDPOINT_URL_HERE>"
let token = "<ADD_YOUR_USER_TOKEN_HERE>"
let displayName: String = "Quickstart User"
değerini İletişim Hizmetleri kaynağınızın uç noktasıyla değiştirin <ADD_YOUR_ENDPOINT_URL_HERE>
.
değerini, Azure istemcisi komut satırı aracılığıyla yukarıda oluşturulan belirteçle değiştirin <ADD_YOUR_USER_TOKEN_HERE>
.
Kullanıcı erişim belirteçleri hakkında daha fazla bilgi edinin: Kullanıcı Erişim Belirteci
öğesini Sohbet'te kullanmak istediğiniz görünen adla değiştirin Quickstart User
.
Durumu tutmak için yapıya ContentView
aşağıdaki değişkenleri ekleyin:
@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] = []
Şimdi kullanıcı arabirimi öğelerini tutmak için ana gövde var'ını ekleyelim. Bu hızlı başlangıçta bu denetimlere iş mantığı ekleyeceğiz. Yapıya ContentView
aşağıdaki kodu ekleyin:
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
}
}
ChatClient'ı başlatma
İleti bildirimlerinin örneğini ChatClient
oluşturma ve etkinleştirme. Sohbet iletilerini almak için gerçek zamanlı bildirimler kullanıyoruz.
Ana gövde ayarlandıysa, çağrı ve sohbet istemcilerinin kurulumunu işlemek için işlevleri ekleyelim.
işlevinde onAppear
ve ChatClient
öğesini başlatmak CallClient
için aşağıdaki kodu ekleyin:
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
}
Toplantıya katılma işlevi ekleme
Toplantıya katılmayı ContentView
işlemek için yapıya aşağıdaki işlevi ekleyin.
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"
}
}
}
ChatThreadClient'ı başlatma
Kullanıcı toplantıya katıldıktan sonra öğesini başlatacağız ChatThreadClient
. Bunun için temsilciden toplantı durumunu denetlememiz ve toplantıya katıldığında ile threadId
uygulamasını başlatmamız ChatThreadClient
gerekir.
İşlevi connectChat()
aşağıdaki kodla oluşturun:
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
}
}
Mümkünse, Ekibinizin toplantı bağlantısından Sohbet yazışması kimliğini ayrıştırmak için kullanılan aşağıdaki yardımcı işlevini ContentView
öğesine ekleyin. Bu ayıklamanın başarısız olması durumunda, kullanıcının iş parçacığı kimliğini almak için Graph API'lerini kullanarak Sohbet iş parçacığı kimliğini el ile girmesi gerekir.
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
}
İleti göndermeyi etkinleştirme
işlevini öğesine sendMessage()
ContentView
ekleyin. Bu işlev, kullanıcıdan ileti göndermek için öğesini ChatThreadClient
kullanır.
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?"
}
}
}
İleti almayı etkinleştirme
İletileri almak için olaylar için ChatMessageReceived
işleyiciyi uygularız. İş parçacığına yeni iletiler gönderildiğinde, bu işleyici iletileri değişkene meetingMessages
ekler, böylece bunlar kullanıcı arabiriminde görüntülenebilir.
İlk olarak aşağıdaki yapıyı öğesine ContentView.swift
ekleyin. Kullanıcı arabirimi, Sohbet iletilerimizi görüntülemek için yapıdaki verileri kullanır.
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
)
}
}
Ardından işlevini öğesine ContentView
ekleyinreceiveMessage()
. Bu, bir mesajlaşma olayı gerçekleştiğinde çağrılır. yöntemi aracılığıyla chatClient?.register()
deyiminde switch
işlemek istediğiniz tüm olaylara kaydolmanız gerektiğini unutmayın.
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
}
}
Son olarak, çağrı istemcisi için temsilci işleyicisini uygulamamız gerekir. Bu işleyici, kullanıcı toplantıya katıldığında çağrı durumunu denetlemek ve sohbet istemcisini başlatmak için kullanılır.
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"
}
}
}
Sohbeti bırakma
Kullanıcı Ekip toplantısından ayrıldığında kullanıcı arabiriminden Sohbet iletilerini temizler ve aramayı kapatırız. Kodun tamamı aşağıda gösterilmiştir.
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"
}
}
İletişim Hizmetleri kullanıcısı için Teams toplantı sohbet yazışması alma
Teams toplantı ayrıntıları, Graph belgelerinde ayrıntılı olarak açıklanan Graph API'leri kullanılarak alınabilir. İletişim Hizmetleri Arama SDK'sı, tam bir Teams toplantı bağlantısını veya toplantı kimliğini kabul eder. Bunlar kaynağın onlineMeeting
bir parçası olarak döndürülür ve özelliği altında joinWebUrl
erişilebilir
Graph API'leri ile de elde threadID
edebilirsiniz. Yanıt, öğesini içeren bir chatInfo
nesnesine threadID
sahiptir.
Kodu çalıştırma
Uygulamayı çalıştırın.
Teams toplantısına katılmak için kullanıcı arabirimine Ekibinizin toplantı bağlantısını girin.
Ekibin toplantısına katıldıktan sonra, kullanıcıyı Ekibinizin istemcisinde toplantıya kabul etmeniz gerekir. Kullanıcı kabul ettikten ve sohbete katıldıktan sonra ileti gönderip alabilirsiniz.
Not
Teams ile birlikte çalışabilirlik senaryolarında şu anda bazı özellikler desteklenmemektedir. Desteklenen özellikler hakkında daha fazla bilgi edinmek için bkz . Teams dış kullanıcıları için Teams toplantı özellikleri
Bu hızlı başlangıçta, Android için Azure İletişim Hizmetleri Sohbet SDK'sını kullanarak Teams toplantısında sohbet etmeyi öğreneceksiniz.
Örnek Kod
Sonuna atlamak isterseniz bu hızlı başlangıcı GitHub'da örnek olarak indirebilirsiniz.
Önkoşullar
- Teams dağıtımı.
- Çalışan bir arama uygulaması.
Teams birlikte çalışabilirliğini etkinleştirme
Teams toplantısına konuk kullanıcı olarak katılan bir İletişim Hizmetleri kullanıcısı, toplantının sohbete yalnızca Teams toplantı çağrısına katıldığında erişebilir. Teams toplantı aramasına İletişim Hizmetleri kullanıcısı eklemeyi öğrenmek için Teams birlikte çalışma belgelerine bakın.
Bu özelliği kullanabilmek için her iki varlığın da sahibi olan kuruluşun üyesi olmanız gerekir.
Toplantı sohbete katılma
Teams birlikte çalışabilirliği etkinleştirildikten sonra, bir İletişim Hizmetleri kullanıcısı Arama SDK'sını kullanarak Teams çağrısına dış kullanıcı olarak katılabilir. Aramaya katılmak, bu kişileri toplantı sohbetine de katılımcı olarak ekler; burada aramada diğer kullanıcılarla ileti gönderip alabilirler. Kullanıcının aramaya katılmadan önce gönderilen sohbet iletilerine erişimi yoktur. Toplantıya katılmak ve sohbet etmeye başlamak için sonraki adımları izleyebilirsiniz.
Teams arama uygulamasına Sohbet ekleme
Modül düzeyinizde build.gradle
, sohbet SDK'sı bağımlılığını ekleyin.
Önemli
Bilinen sorun: Android Sohbet ve Arama SDK'sını aynı uygulamada birlikte kullanırken Sohbet SDK'sının gerçek zamanlı bildirimler özelliği çalışmaz. Bağımlılık çözümleme sorunuyla karşınıza çıkar. Bir çözüm üzerinde çalışırken uygulamanın dosyasındaki Sohbet SDK'sı build.gradle
bağımlılığına aşağıdaki dışlamaları ekleyerek gerçek zamanlı bildirimler özelliğini kapatabilirsiniz:
implementation ("com.azure.android:azure-communication-chat:2.0.3") {
exclude group: 'com.microsoft', module: 'trouter-client-android'
}
Teams kullanıcı arabirimi düzenini ekleme
activity_main.xml içindeki kodu aşağıdaki kod parçacığıyla değiştirin. İş parçacığı kimliği ve ileti göndermek için girişler, yazılan iletiyi göndermek için bir düğme ve temel bir sohbet düzeni ekler.
<?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>
Teams kullanıcı arabirimi denetimlerini etkinleştirme
Paketleri içeri aktarma ve durum değişkenlerini tanımlama
içeriğine MainActivity.java
aşağıdaki içeri aktarmaları ekleyin:
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;
sınıfına MainActivity
aşağıdaki değişkenleri ekleyin:
// 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<>();
değerini sohbeti başlatan kullanıcının kimliğiyle değiştirin <USER_ID>
.
değerini İletişim Hizmetleri kaynağınızın uç noktasıyla değiştirin <COMMUNICATION_SERVICES_RESOURCE_ENDPOINT>
.
ChatThreadClient'ı başlatma
Toplantıya katıldıktan sonra öğesinin örneğini ChatThreadClient
açın ve sohbet bileşenlerini görünür hale getirin.
Yönteminin MainActivity.joinTeamsMeeting()
sonunu aşağıdaki kodla güncelleştirin:
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);
}
İleti göndermeyi etkinleştirme
sendMessage()
yöntemini öğesine MainActivity
ekleyin. kullanıcı adına ileti göndermek için kullanır ChatThreadClient
.
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("");
}
İletiler için yoklamayı etkinleştirme ve bunları uygulamada işleme
Önemli
Bilinen sorun: Sohbet SDK'sının gerçek zamanlı bildirimler özelliği Arama SDK'ları ile birlikte çalışmadığından API'yi önceden tanımlanmış aralıklarla yoklamamız GetMessages
gerekir. Örneğimizde 3 saniyelik aralıklar kullanacağız.
API tarafından GetMessages
döndürülen ileti listesinden aşağıdaki verileri elde edebiliriz:
- Katıldıktan
text
sonra iş parçacığındaki vehtml
iletileri - İş parçacığı listesinde yapılan değişiklikler
- İş parçacığı konusuna Güncelleştirmeler
sınıfına MainActivity
, 3 saniyelik aralıklarla çalıştırılacak bir işleyici ve çalıştırılabilir bir görev ekleyin:
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);
}
};
Başlatma adımında güncelleştirilen yöntemin MainActivity.joinTeamsMeeting()
sonunda görevin zaten başlatıldığını unutmayın.
Son olarak, iş parçacığındaki tüm erişilebilir iletileri sorgulamak, bunları ileti türüne göre ayrıştırmak ve ve text
değerlerini görüntülemek html
için yöntemini ekleyeceğiz:
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);
}
}
Sohbet yazışması katılımcılarının görünen adları Teams istemcisi tarafından ayarlanmamıştır. Adlar, etkinlikte ve etkinlikte katılımcıları listelemek için API'de participantsAdded
participantsRemoved
null olarak döndürülür. Sohbet katılımcılarının görünen adları nesnenin remoteParticipants
alanından call
alınabilir.
İletişim Hizmetleri kullanıcısı için Teams toplantı sohbet yazışması alma
Teams toplantı ayrıntıları, Graph belgelerinde ayrıntılı olarak açıklanan Graph API'leri kullanılarak alınabilir. İletişim Hizmetleri Arama SDK'sı, tam bir Teams toplantı bağlantısını veya toplantı kimliğini kabul eder. Bunlar kaynağın onlineMeeting
bir parçası olarak döndürülür ve özelliği altında joinWebUrl
erişilebilir
Graph API'leri ile de elde threadID
edebilirsiniz. Yanıt, öğesini içeren bir chatInfo
nesnesine threadID
sahiptir.
Kodu çalıştırma
Uygulama artık araç çubuğundaki "Uygulamayı Çalıştır" düğmesi kullanılarak başlatılabilir (Shift+F10).
Teams toplantısına ve sohbetine katılmak için Ekibinizin toplantı bağlantısını ve yazışma kimliğini kullanıcı arabirimine girin.
Ekibin toplantısına katıldıktan sonra, kullanıcıyı Ekibinizin istemcisinde toplantıya kabul etmeniz gerekir. Kullanıcı kabul ettikten ve sohbete katıldıktan sonra ileti gönderip alabilirsiniz.
Not
Teams ile birlikte çalışabilirlik senaryolarında şu anda bazı özellikler desteklenmemektedir. Desteklenen özellikler hakkında daha fazla bilgi edinmek için bkz . Teams dış kullanıcıları için Teams toplantı özellikleri
Bu hızlı başlangıçta, C# için Azure İletişim Hizmetleri Sohbet SDK'sını kullanarak Teams toplantısında sohbet etmeyi öğreneceksiniz.
Örnek kod
GitHub'da bu hızlı başlangıcın kodunu bulun.
Önkoşullar
- Teams dağıtımı.
- Etkin aboneliği olan bir Azure hesabı. Ücretsiz hesap oluşturun.
- Evrensel Windows Platformu geliştirme iş yüküyle Visual Studio 2019'u yükleyin.
- Dağıtılan bir İletişim Hizmetleri kaynağı. İletişim Hizmetleri kaynağı oluşturun.
- Teams Toplantı Bağlantısı.
Toplantı sohbete katılma
İletişim Hizmetleri kullanıcısı, Arama SDK'sını kullanarak teams toplantısına anonim kullanıcı olarak katılabilir. Toplantıya katılmak, toplantıdaki diğer kullanıcılarla ileti gönderip alabilecekleri toplantı sohbetine de katılımcı olarak ekler. Kullanıcı, toplantıya katılmadan önce gönderilen sohbet iletilerine erişemez ve toplantı sona erdikten sonra ileti gönderemez veya alamaz. Toplantıya katılmak ve sohbet etmeye başlamak için sonraki adımları izleyebilirsiniz.
Kodu çalıştırma
Kodu Visual Studio'da derleyebilir ve çalıştırabilirsiniz. Desteklediğimiz çözüm platformlarını not edin: x64
,x86
, ve ARM64
.
- PowerShell, Windows Terminali, Komut İstemi veya eşdeğer bir örneği açın ve örneği kopyalamak istediğiniz dizine gidin.
git clone https://github.com/Azure-Samples/Communication-Services-dotnet-quickstarts.git
- Visual Studio'da ChatTeamsInteropQuickStart/ChatTeamsInteropQuickStart.csproj projesini açın.
- Aşağıdaki NuGet paketleri sürümlerini (veya üzerini) yükleyin:
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
- İletişim Hizmetleri kaynağı önkoşullarda temin edildiyse, connectionstring'i ChatTeamsInteropQuickStart/MainPage.xaml.cs dosyasına ekleyin.
//Azure Communication Services resource connection string, i.e., = "endpoint=https://your-resource.communication.azure.net/;accesskey=your-access-key";
private const string connectionString_ = "";
Önemli
- Kodu çalıştırmadan önce Visual Studio'daki 'Çözüm Platformları' açılan listesinden uygun platformu seçin; örneğin,
x64
- Windows 10'da 'Geliştirici Modu'nun etkinleştirildiğinden emin olun (Geliştirici Ayarlar)
Bu doğru yapılandırılmazsa sonraki adımlar çalışmaz
- Projeyi hata ayıklama modunda başlatmak için F5 tuşuna basın.
- 'Teams Toplantı Bağlantısı' kutusuna geçerli bir Teams toplantı bağlantısı yapıştırın (sonraki bölüme bakın)
- Sohbete başlamak için 'Teams toplantısına katıl' tuşuna basın.
Önemli
Arama SDK'sı teams toplantısıyla bağlantı kurduktan sonra Bkz. İletişim Hizmetleri windows uygulamasını çağırırken, sohbet işlemlerini işlemeye yönelik temel işlevler şunlardır: StartPollingForChatMessages ve SendMessageButton_Click. Her iki kod parçacığı da 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;
}
Teams toplantı bağlantısı alma
Teams toplantı bağlantısı, Graph belgelerinde ayrıntılı olarak açıklanan Graph API'leri kullanılarak alınabilir. Bu bağlantı kaynağın onlineMeeting
bir parçası olarak döndürülür ve özelliğinden joinWebUrl
erişilebilir.
Ayrıca, Teams toplantı davetinin kendisindeki Toplantıya Katıl URL'sinden de gerekli toplantı bağlantısını alabilirsiniz.
Teams toplantı bağlantısı şöyle görünür: https://teams.microsoft.com/l/meetup-join/meeting_chat_thread_id/1606337455313?context=some_context_here
.
Teams bağlantınız bu bağlantıyla farklı bir biçime sahipse, Graph API'sini kullanarak iş parçacığı kimliğini almanız gerekir.
Not
Teams ile birlikte çalışabilirlik senaryolarında şu anda bazı özellikler desteklenmemektedir. Desteklenen özellikler hakkında daha fazla bilgi edinmek için bkz . Teams dış kullanıcıları için Teams toplantı özellikleri
Kaynakları temizleme
İletişim Hizmetleri aboneliğini temizlemek ve kaldırmak istiyorsanız, kaynağı veya kaynak grubunu silebilirsiniz. Kaynak grubunun silinmesi, kaynak grubuyla ilişkili diğer tüm kaynakları da siler. Kaynakları temizleme hakkında daha fazla bilgi edinin.
Sonraki adımlar
Daha fazla bilgi için aşağıdaki makaleleri inceleyin:
- Sohbet hero örneğimize göz atın
- Sohbetin nasıl çalıştığı hakkında daha fazla bilgi edinin