Zelfstudie: Ondersteuning voor inline-installatiekopieën inschakelen in uw Chat-app
De Chat SDK is ontworpen om naadloos met Microsoft Teams te werken. Met name chat-SDK biedt een oplossing voor het ontvangen van inlineafbeeldingen en het verzenden van inlineafbeeldingen naar gebruikers van Microsoft Teams.
In deze zelfstudie leert u hoe u ondersteuning voor inline-installatiekopieën inschakelt met behulp van de Azure Communication Services Chat SDK voor JavaScript.
Inline-afbeeldingen zijn afbeeldingen die rechtstreeks in het verzendvak van de Teams-client worden gekopieerd en geplakt. Voor afbeeldingen die zijn geüpload via het menu Uploaden vanaf dit apparaat of via slepen en neerzetten, zoals afbeeldingen die rechtstreeks naar het verzendvak in Teams zijn gesleept, moet u naar deze zelfstudie verwijzen als onderdeel van de functie voor het delen van bestanden. (Zie de sectie 'Afbeeldingsbijlagen verwerken'.)
Als u een afbeelding wilt kopiëren, hebben Teams-gebruikers twee opties:
- Gebruik het contextmenu van het besturingssysteem om het afbeeldingsbestand te kopiëren en plak het in het verzendvak van de Teams-client.
- Gebruik sneltoetsen.
In deze zelfstudie leert u wat u moet doen wanneer u:
Notitie
De mogelijkheid om inlineafbeeldingen te verzenden, is momenteel beschikbaar in openbare preview. Deze is alleen beschikbaar voor JavaScript. Voor het ontvangen van inlineafbeeldingen is deze momenteel algemeen beschikbaar. Het is beschikbaar voor zowel JavaScript als C# in een teams-interoperabiliteitschat.
Vereisten
- Bekijk de quickstart Deelnemen aan uw chat-app aan een Teams-vergadering.
- Maak een Azure Communication Services-resource. Zie Een Azure Communication Services-resource maken voor meer informatie. U moet uw verbindingsreeks opnemen voor deze zelfstudie.
- Stel een Teams-vergadering in met uw zakelijke account en laat de URL van de vergadering gereed zijn.
- Gebruik de Chat-SDK voor JavaScript (@azure/communication-chat) 1.4.0 of de meest recente versie. Zie de Azure Communication Chat-clientbibliotheek voor JavaScript voor meer informatie.
Voorbeeldcode
Zoek de voltooide code van deze zelfstudie op GitHub.
Ontvangen inlineafbeeldingen verwerken in een nieuwe berichtgebeurtenis
In deze sectie leert u hoe u inlineafbeeldingen kunt weergeven die zijn ingesloten in de berichtinhoud van een nieuwe ontvangen gebeurtenis.
In de quickstart hebt u een gebeurtenis-handler gemaakt voor de chatMessageReceived
gebeurtenis, die wordt geactiveerd wanneer u een nieuw bericht van de Teams-gebruiker ontvangt. U voegt ook binnenkomende berichtinhoud messageContainer
rechtstreeks toe bij het ontvangen van de gebeurtenis van de chatMessageReceived
chatClient
, zoals deze:
chatClient.on("chatMessageReceived", (e) => {
console.log("Notification chatMessageReceived!");
// Check whether the notification is intended for the current thread
if (threadIdInput.value != e.threadId) {
return;
}
if (e.sender.communicationUserId != userId) {
renderReceivedMessage(e.message);
}
else {
renderSentMessage(e.message);
}
});
async function renderReceivedMessage(message) {
messages += '<div class="container lighter">' + message + '</div>';
messagesContainer.innerHTML = messages;
}
Vanuit de binnenkomende gebeurtenis van het type ChatMessageReceivedEvent
bevat een eigenschap met de naam attachments
informatie over de inlineafbeelding. U hoeft alleen inlineafbeeldingen weer te geven in uw gebruikersinterface:
export interface ChatMessageReceivedEvent extends BaseChatMessageEvent {
/**
* Content of the message.
*/
message: string;
/**
* Metadata of the message.
*/
metadata: Record<string, string>;
/**
* Chat message attachment.
*/
attachments?: ChatAttachment[];
}
export interface ChatAttachment {
/** Id of the attachment */
id: string;
/** The type of attachment. */
attachmentType: ChatAttachmentType;
/** The name of the attachment content. */
name?: string;
/** The URL where the attachment can be downloaded */
url?: string;
/** The URL where the preview of attachment can be downloaded */
previewUrl?: string;
}
export type ChatAttachmentType = "image" | "unknown";
Ga nu terug naar de vorige code om extra logica toe te voegen, zoals de volgende codefragmenten:
chatClient.on("chatMessageReceived", (e) => {
console.log("Notification chatMessageReceived!");
// Check whether the notification is intended for the current thread
if (threadIdInput.value != e.threadId) {
return;
}
const isMyMessage = e.sender.communicationUserId === userId;
renderReceivedMessage(e, isMyMessage);
});
function renderReceivedMessage(e, isMyMessage) {
const messageContent = e.message;
const card = document.createElement('div');
card.className = isMyMessage ? "container darker" : "container lighter";
card.innerHTML = messageContent;
messagesContainer.appendChild(card);
// Filter out inline images from attachments
const imageAttachments = e.attachments.filter((e) =>
e.attachmentType.toLowerCase() === 'image');
// Fetch and render preview images
fetchPreviewImages(imageAttachments);
// Set up onclick event handler to fetch full-scale image
setImgHandler(card, imageAttachments);
}
function setImgHandler(element, imageAttachments) {
// Do nothing if there are no image attachments
if (!imageAttachments.length > 0) {
return;
}
const imgs = element.getElementsByTagName('img');
for (const img of imgs) {
img.addEventListener('click', (e) => {
// Fetch full-scale image upon click
fetchFullScaleImage(e, imageAttachments);
});
}
}
async function fetchPreviewImages(attachments) {
if (!attachments.length > 0) {
return;
}
// Since each message could contain more than one inline image
// we need to fetch them individually
const result = await Promise.all(
attachments.map(async (attachment) => {
// Fetch preview image from its 'previewURL'
const response = await fetch(attachment.previewUrl, {
method: 'GET',
headers: {
// The token here should be the same one from chat initialization
'Authorization': 'Bearer ' + tokenString,
},
});
// The response would be in an image blob, so we can render it directly
return {
id: attachment.id,
content: await response.blob(),
};
}),
);
result.forEach((imageResult) => {
const urlCreator = window.URL || window.webkitURL;
const url = urlCreator.createObjectURL(imageResult.content);
// Look up the image ID and replace its 'src' with object URL
document.getElementById(imageResult.id).src = url;
});
}
In dit voorbeeld hebt u twee helperfuncties gemaakt en fetchPreviewImages
setImgHandler
. De eerste haalt de voorbeeldafbeelding rechtstreeks op van de previewURL
opgegeven in elk ChatAttachment
object met een verificatieheader. Op dezelfde manier stelt u een onclick
gebeurtenis in voor elke afbeelding in de functie setImgHandler
. In de gebeurtenis-handler haalt u een afbeelding op volledige schaal op uit de eigenschap url
van het ChatAttachment
object met een verificatieheader.
Nu moet u het token beschikbaar maken op het globale niveau, omdat u er een verificatieheader mee moet maken. U moet de volgende code wijzigen:
// New variable for token string
var tokenString = '';
async function init() {
....
let tokenResponse = await identityClient.getToken(identityResponse, [
"voip",
"chat"
]);
const { token, expiresOn } = tokenResponse;
// Save to token string
tokenString = token;
...
}
Als u de afbeelding op volledige schaal in een overlay wilt weergeven, moet u ook een nieuw onderdeel toevoegen:
<div class="overlay" id="overlay-container">
<div class="content">
<img id="full-scale-image" src="" alt="" />
</div>
</div>
Met een aantal CSS:
/* let's make chat popup scrollable */
.chat-popup {
...
max-height: 650px;
overflow-y: scroll;
}
.overlay {
position: fixed;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, .7);
top: 0;
left: 0;
z-index: 100;
}
.overlay .content {
position: fixed;
width: 100%;
height: 100%;
text-align: center;
overflow: hidden;
z-index: 100;
margin: auto;
background-color: rgba(0, 0, 0, .7);
}
.overlay img {
position: absolute;
display: block;
max-height: 90%;
max-width: 90%;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
#overlay-container {
display: none
}
Nu u een overlay hebt ingesteld, is het tijd om aan de logica te werken om afbeeldingen op volledige schaal weer te geven. U hebt een onClick
gebeurtenis-handler gemaakt om een functie fetchFullScaleImage
aan te roepen:
const overlayContainer = document.getElementById('overlay-container');
const loadingImageOverlay = document.getElementById('full-scale-image');
function fetchFullScaleImage(e, imageAttachments) {
// Get the image ID from the clicked image element
const link = imageAttachments.filter((attachment) =>
attachment.id === e.target.id)[0].url;
loadingImageOverlay.src = '';
// Fetch the image
fetch(link, {
method: 'GET',
headers: {'Authorization': 'Bearer ' + tokenString},
}).then(async (result) => {
// Now we set image blob to our overlay element
const content = await result.blob();
const urlCreator = window.URL || window.webkitURL;
const url = urlCreator.createObjectURL(content);
loadingImageOverlay.src = url;
});
// Show overlay
overlayContainer.style.display = 'block';
}
Een laatste wat u wilt toevoegen, is de mogelijkheid om de overlay te sluiten wanneer op de afbeelding wordt geklikt:
loadingImageOverlay.addEventListener('click', () => {
overlayContainer.style.display = 'none';
});
Nu hebt u alle wijzigingen aangebracht die u nodig hebt om inlineafbeeldingen weer te geven voor berichten die afkomstig zijn van realtime meldingen.
De code uitvoeren
Webpack-gebruikers kunnen uw webpack-dev-server
app bouwen en uitvoeren. Voer de volgende opdracht uit om uw toepassingshost te bundelen op een lokale webserver:
npx webpack-dev-server --entry ./client.js --output bundle.js --debug --devtool inline-source-map
Demo
Open uw browser en ga naar http://localhost:8080/
. Voer de URL van de vergadering en de thread-id in. Verzend enkele inlineafbeeldingen van de Teams-client.
Vervolgens ziet u dat het nieuwe bericht samen met voorbeeldafbeeldingen wordt weergegeven.
Nadat de Azure Communication Services-gebruiker de voorbeeldafbeelding heeft geselecteerd, wordt er een overlay weergegeven met de volledige afbeelding die door de Teams-gebruiker wordt verzonden.
Het verzenden van inlineafbeeldingen in een nieuwe berichtaanvraag afhandelen
Belangrijk
Deze functie van Azure Communication Services is momenteel beschikbaar als preview-versie.
Preview-API's en SDK's worden aangeboden zonder een service level agreement. U wordt aangeraden deze niet te gebruiken voor productieworkloads. Sommige functies worden mogelijk niet ondersteund of hebben mogelijk beperkte mogelijkheden.
Raadpleeg aanvullende gebruiksvoorwaarden voor Microsoft Azure Previews voor meer informatie.
Naast het verwerken van berichten met inlineafbeeldingen biedt de Chat SDK voor JavaScript ook een oplossing waarmee de communicatiegebruiker inlineafbeeldingen naar de Microsoft Teams-gebruiker kan verzenden in een interoperabiliteitschat.
Bekijk de nieuwe API vanuit ChatThreadClient
:
var imageAttachment = await chatThreadClient.uploadImage(blob, file.name, {
"onUploadProgress": reportProgressCallback
});
De API maakt gebruik van een afbeeldingsblob, bestandsnaamtekenreeks en een functie-callback die de voortgang van het uploaden rapporteert.
Als u een afbeelding naar een andere chatdeelnemer wilt verzenden, moet u het volgende doen:
- Upload de afbeelding via de
uploadImage
API vanChatThreadClient
en sla het geretourneerde object op. - Stel de inhoud van het bericht samen en stel een bijlage in op het geretourneerde object dat u in de vorige stap hebt opgeslagen.
- Verzend het nieuwe bericht via de
sendMessage
API vanChatThreadClient
.
Maak een nieuwe bestandskiezer die afbeeldingen accepteert:
<label for="myfile">Attach images:</label>
<input id="upload" type="file" id="myfile" name="myfile" accept="image/*" multiple>
<input style="display: none;" id="upload-result"></input>
Stel nu een gebeurtenislistener in voor wanneer er een statuswijziging is:
document.getElementById("upload").addEventListener("change", uploadImages);
U moet een nieuwe functie maken voor wanneer de status verandert:
var uploadedImageModels = [];
async function uploadImages(e) {
const files = e.target.files;
if (files.length === 0) {
return;
}
for (let key in files) {
if (files.hasOwnProperty(key)) {
await uploadImage(files[key]);
}
}
}
async function uploadImage(file) {
const buffer = await file.arrayBuffer();
const blob = new Blob([new Uint8Array(buffer)], {type: file.type });
const url = window.URL.createObjectURL(blob);
document.getElementById("upload-result").innerHTML += `<img src="${url}" height="auto" width="100" />`;
let uploadedImageModel = await chatThreadClient.uploadImage(blob, file.name, {
imageBytesLength: file.size
});
uploadedImageModels.push(uploadedImageModel);
}
In dit voorbeeld hebt u een FileReader
gemaakt om elke afbeelding te lezen als base64
-gecodeerde afbeeldingen en vervolgens een Blob
afbeelding te maken voordat u de ChatSDK-API aanroept om deze te uploaden. U hebt een globaal uploadedImageModels
bestand gemaakt om de gegevensmodellen van geüploade afbeeldingen op te slaan vanuit de Chat SDK.
Ten slotte moet u de sendMessageButton
gebeurtenislistener wijzigen die u eerder hebt gemaakt om de afbeeldingen die u hebt geüpload, toe te voegen.
sendMessageButton.addEventListener("click", async () => {
let message = messagebox.value;
let attachments = uploadedImageModels;
// Inject image tags for images we have selected
// so they can be treated as inline images
// Alternatively, we can use some third-party libraries
// to have a rich text editor with inline image support
message += attachments.map((attachment) => `<img id="${attachment.id}" />`).join("");
let sendMessageRequest = {
content: message,
attachments: attachments,
};
let sendMessageOptions = {
senderDisplayName: "Jack",
type: "html"
};
let sendChatMessageResult = await chatThreadClient.sendMessage(
sendMessageRequest,
sendMessageOptions
);
let messageId = sendChatMessageResult.id;
uploadedImageModels = [];
messagebox.value = "";
document.getElementById("upload").value = "";
console.log(`Message sent!, message id:${messageId}`);
});
Dat is alles. Voer nu de code uit om deze in actie te zien.
De code uitvoeren
Webpack-gebruikers kunnen uw webpack-dev-server
app bouwen en uitvoeren. Voer de volgende opdracht uit om uw toepassingshost te bundelen op een lokale webserver:
npx webpack-dev-server --entry ./client.js --output bundle.js --debug --devtool inline-source-map
Demo
Open uw browser en ga naar http://localhost:8080/
. U hebt een nieuwe sectie in het vak Verzenden om afbeeldingen toe te voegen.
Vervolgens kunt u de afbeeldingen selecteren die u wilt bijvoegen.
De Teams-gebruiker moet nu de afbeelding ontvangen die u zojuist hebt verzonden wanneer ze Verzenden selecteren.
In deze zelfstudie leert u hoe u ondersteuning voor inline-installatiekopieën inschakelt met behulp van de Azure Communication Services Chat SDK voor C#.
In deze zelfstudie leert u het volgende:
- Inlineafbeeldingen verwerken voor nieuwe berichten.
Vereisten
- Bekijk de quickstart Deelnemen aan uw chat-app aan een Teams-vergadering.
- Maak een Azure Communication Services-resource. Zie Een Azure Communication Services-resource maken voor meer informatie. U moet uw verbindingsreeks opnemen voor deze zelfstudie.
- Stel een Teams-vergadering in met uw zakelijke account en laat de URL van de vergadering gereed zijn.
- Gebruik chat-SDK voor C# (Azure.Communication.Chat) 1.3.0 of de nieuwste versie. Zie de Azure Communication Chat-clientbibliotheek voor .NET voor meer informatie.
Goal
- Pak de
previewUri
eigenschap voor inlineafbeeldingsbijlagen.
Inlineafbeeldingen voor nieuwe berichten verwerken
In de quickstart peilt u berichten en voegt u nieuwe berichten toe aan de messageList
eigenschap. U bouwt later voort op deze functionaliteit om het parseren en ophalen van de inlineafbeeldingen op te nemen.
CommunicationUserIdentifier currentUser = new(user_Id_);
AsyncPageable<ChatMessage> allMessages = chatThreadClient.GetMessagesAsync();
SortedDictionary<long, string> messageList = [];
int textMessages = 0;
await foreach (ChatMessage message in allMessages)
{
if (message.Type == ChatMessageType.Html || message.Type == ChatMessageType.Text)
{
textMessages++;
var userPrefix = message.Sender.Equals(currentUser) ? "[you]:" : "";
var strippedMessage = StripHtml(message.Content.Message);
messageList.Add(long.Parse(message.SequenceId), $"{userPrefix}{strippedMessage}");
}
}
Vanuit de binnenkomende gebeurtenis van het type ChatMessageReceivedEvent
bevat de eigenschap met de naam attachments
informatie over de inlineafbeelding. Het is alles wat u nodig hebt om inlineafbeeldingen weer te geven in uw gebruikersinterface.
public class ChatAttachment
{
public ChatAttachment(string id, ChatAttachmentType attachmentType)
public ChatAttachmentType AttachmentType { get }
public string Id { get }
public string Name { get }
public System.Uri PreviewUrl { get }
public System.Uri Url { get }
}
public struct ChatAttachmentType : System.IEquatable<AttachmentType>
{
public ChatAttachmentType(string value)
public static File { get }
public static Image { get }
}
De volgende JSON is een voorbeeld van hoe ChatAttachment
het eruit kan zien voor een afbeeldingsbijlage:
"attachments": [
{
"id": "9d89acb2-c4e4-4cab-b94a-7c12a61afe30",
"attachmentType": "image",
"name": "Screenshot.png",
"url": "https://contoso.communication.azure.com/chat/threads/19:9d89acb29d89acb2@thread.v2/images/9d89acb2-c4e4-4cab-b94a-7c12a61afe30/views/original?api-version=2023-11-03",
"previewUrl": "https://contoso.communication.azure.com/chat/threads/19:9d89acb29d89acb2@thread.v2/images/9d89acb2-c4e4-4cab-b94a-7c12a61afe30/views/small?api-version=2023-11-03"
}
]
Ga nu terug en vervang de code om extra logica toe te voegen om de afbeeldingsbijlagen te parseren en op te halen:
CommunicationUserIdentifier currentUser = new(user_Id_);
AsyncPageable<ChatMessage> allMessages = chatThreadClient.GetMessagesAsync();
SortedDictionary<long, string> messageList = [];
int textMessages = 0;
await foreach (ChatMessage message in allMessages)
{
// Get message attachments that are of type 'image'
IEnumerable<ChatAttachment> imageAttachments = message.Content.Attachments.Where(x => x.AttachmentType == ChatAttachmentType.Image);
// Fetch image and render
var chatAttachmentImageUris = new List<Uri>();
foreach (ChatAttachment imageAttachment in imageAttachments)
{
client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", communicationTokenCredential.GetToken().Token);
var response = await client.GetAsync(imageAttachment.PreviewUri);
var randomAccessStream = await response.Content.ReadAsStreamAsync();
await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () =>
{
var bitmapImage = new BitmapImage();
await bitmapImage.SetSourceAsync(randomAccessStream.AsRandomAccessStream());
InlineImage.Source = bitmapImage;
});
chatAttachmentImageUris.Add(imageAttachment.PreviewUri);
}
// Build message list
if (message.Type == ChatMessageType.Html || message.Type == ChatMessageType.Text)
{
textMessages++;
var userPrefix = message.Sender.Equals(currentUser) ? "[you]:" : "";
var strippedMessage = StripHtml(message.Content.Message);
var chatAttachments = chatAttachmentImageUris.Count > 0 ? "[Attachments]:\n" + string.Join(",\n", chatAttachmentImageUris) : "";
messageList.Add(long.Parse(message.SequenceId), $"{userPrefix}{strippedMessage}\n{chatAttachments}");
}
In dit voorbeeld pakt u alle bijlagen uit het bericht van het type Image
en haalt u vervolgens elk van de afbeeldingen op. U moet uw Token
in het Bearer
gedeelte van de aanvraagheader gebruiken voor autorisatiedoeleinden. Nadat de afbeelding is gedownload, kunt u deze toewijzen aan het InlineImage
element van de weergave.
U voegt ook een lijst met de bijlage-URI's toe die samen met het bericht in de berichtenlijst moeten worden weergegeven.
Demo
- Voer de toepassing uit vanuit de integrated development environment (IDE).
- Voer een koppeling naar een Teams-vergadering in.
- Neem deel aan de vergadering.
- Geef de gebruiker toe aan de kant van Teams.
- Verzend een bericht aan de kant van Teams met een afbeelding.
De URL die is opgenomen in het bericht, wordt weergegeven in de berichtenlijst. De laatst ontvangen afbeelding wordt onderaan het venster weergegeven.
Volgende stappen
- Meer informatie over andere ondersteunde interoperabiliteitsfuncties.
- Bekijk ons voorbeeld van chatheld.
- Meer informatie over hoe Chat werkt.