Notes
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Le Kit de développement logiciel (SDK) Chat est conçu pour fonctionner en toute transparence avec Microsoft Teams. Plus précisément, le Kit de développement logiciel (SDK) Chat fournit une solution permettant de recevoir des images inline et d’envoyer des images inline aux utilisateurs de Microsoft Teams.
Dans ce tutoriel, vous apprendrez comment activer la prise en charge des images en ligne en utilisant le SDK (Kit de développement logiciel) Azure Communication Services Chat pour JavaScript.
Les images incorporées sont des images copiées et collées directement dans la boîte d’envoi du client Teams. Pour les images chargées via le chargement à partir de ce menu d’appareil ou par glisser-déplacer, telles que les images déplacées directement vers la zone d’envoi dans Teams, vous devez faire référence à ce didacticiel dans le cadre de la fonctionnalité de partage de fichiers. (Consultez la section « Gérer les pièces jointes d’image . »)
Pour copier une image, les utilisateurs de Teams ont deux options :
- Utilisez le menu contextuel de leur système d’exploitation pour copier le fichier image, puis collez-le dans la zone d’envoi de son client Teams.
- Utilisez des raccourcis clavier.
Dans ce tutoriel, vous allez découvrir ce que vous devez faire lorsque vous procédez comme suit :
Remarque
La possibilité d’envoyer des images inline est actuellement disponible en préversion publique. Il est disponible uniquement pour JavaScript. Pour recevoir des images incorporées, il est actuellement en disponibilité générale. Il est disponible pour JavaScript et C# dans une conversation d’interopérabilité Teams.
Conditions préalables
- Passez en revue le guide de démarrage rapide Joindre votre application de conversation à une réunion Teams.
- Créez une ressource Azure Communication Services. Pour plus d’informations, consultez Créer une ressource Azure Communication Services. Vous devez enregistrer votre chaîne de connexion pour ce tutoriel.
- Configurez une réunion Teams à l’aide de votre compte professionnel, et préparez l’URL de la réunion.
- Utilisez le Kit de développement logiciel (SDK) Chat pour JavaScript (@azure/communication-chat) 1.4.0 ou la dernière version. Pour plus d’informations, consultez Bibliothèque de client Azure Communication Chat pour JavaScript.
Exemple de code
Vous trouverez le code finalisé de ce tutoriel sur GitHub.
Gérer les images inline reçues dans un nouvel événement de message
Dans cette section, vous allez apprendre à afficher des images inline incorporées dans le contenu du message d’un nouvel événement reçu.
Dans le guide de démarrage rapide, vous avez créé un gestionnaire d’événements pour l’événement chatMessageReceived
, qui est déclenché lorsque vous recevez un nouveau message de l’utilisateur Teams. Vous ajoutez également le contenu du message entrant au messageContainer
directement lors de la réception de l’événement chatMessageReceived
provenant de chatClient
, comme ceci :
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;
}
À partir de l’événement entrant de type ChatMessageReceivedEvent
, une propriété nommée attachments
contient des informations sur l’image inline. Il vous suffit d’afficher des images inline dans votre interface utilisateur :
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";
Revenez maintenant au code précédent pour ajouter une logique supplémentaire, comme les extraits de code suivants :
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;
});
}
Dans cet exemple, vous avez créé deux fonctions d’assistance, fetchPreviewImages
et setImgHandler
. La première méthode obtient l’image d’aperçu directement depuis l'objet previewURL
fourni dans chaque ChatAttachment
en utilisant un en-tête d'authentification. De même, vous configurez un onclick
événement pour chaque image dans la fonction setImgHandler
. Dans le gestionnaire d’événements, vous récupérez une image à l’échelle complète à partir de la propriété url
à partir de l’objet ChatAttachment
avec un en-tête d’authentification.
Vous devez maintenant exposer le jeton au niveau global, car vous devez construire un en-tête d’authentification avec celui-ci. Vous devez modifier le code suivant :
// 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;
...
}
Pour afficher l’image à grande échelle dans une superposition, vous devez également ajouter un nouveau composant :
<div class="overlay" id="overlay-container">
<div class="content">
<img id="full-scale-image" src="" alt="" />
</div>
</div>
Avec du 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
}
Maintenant que vous disposez d’une superposition configurée, il est temps de travailler sur la logique pour afficher des images à grande échelle. Rappelez-vous que vous avez créé un gestionnaire d’événements onClick
pour appeler une fonction fetchFullScaleImage
:
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';
}
Une dernière chose que vous souhaitez ajouter est la possibilité de ignorer la superposition lorsque l’image est cliqué :
loadingImageOverlay.addEventListener('click', () => {
overlayContainer.style.display = 'none';
});
Vous avez maintenant apporté toutes les modifications dont vous avez besoin pour afficher des images inline pour les messages provenant de notifications en temps réel.
Exécuter le code
Les utilisateurs Webpack peuvent utiliser webpack-dev-server
pour générer et exécuter votre application. Exécutez la commande suivante pour empaqueter l'hôte de votre application sur un serveur web local :
npx webpack-dev-server --entry ./client.js --output bundle.js --debug --devtool inline-source-map
Démonstration
Ouvrez votre navigateur et accédez à http://localhost:8080/
. Saisissez l’URL de la réunion et l’ID du thread. Envoyez des images inline à partir du client Teams.
Ensuite, vous devez voir le nouveau message affiché avec les images d’aperçu.
Une fois que l’utilisateur Azure Communication Services sélectionne l’image d’aperçu, une superposition s’affiche avec l’image à grande échelle envoyée par l’utilisateur Teams.
Gérer l’envoi d’images inline dans une nouvelle demande de message
Important
Cette fonctionnalité d’Azure Communication Services est actuellement en préversion. Les fonctionnalités en préversion sont disponibles publiquement et peuvent être utilisées par tous les clients Microsoft nouveaux et existants.
Ces interfaces de programmation d’applications et kits de développement logiciel (SDK) en préversion sont fournis sans contrat au niveau du service. Nous vous recommandons de ne pas les utiliser pour les charges de travail de production. Certaines fonctionnalités peuvent ne pas être prises en charge ou les fonctionnalités peuvent être limitées.
Pour plus d’informations, consultez Conditions d’Utilisation Supplémentaires relatives aux Évaluations Microsoft Azure.
Outre la gestion des messages avec des images inline, le Kit de développement logiciel (SDK) Chat pour JavaScript fournit également une solution permettant à l’utilisateur de communication d’envoyer des images inline à l’utilisateur Microsoft Teams dans une conversation d’interopérabilité.
Examinez la nouvelle API à partir de ChatThreadClient
:
var imageAttachment = await chatThreadClient.uploadImage(blob, file.name, {
"onUploadProgress": reportProgressCallback
});
L’API prend en charge un blob d'image, une chaîne de nom de fichier et une fonction de rappel qui signale la progression du chargement.
Pour envoyer une image à un autre participant de conversation, vous devez :
- Chargez l’image via l’API
uploadImage
à partir deChatThreadClient
, puis enregistrez l’objet retourné. - Composez le contenu du message et définissez une pièce jointe sur l’objet retourné que vous avez enregistré à l’étape précédente.
- Envoyez le nouveau message via l’API
sendMessage
à partir deChatThreadClient
.
Créez un sélecteur de fichiers qui accepte des images :
<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>
À présent, configurez un écouteur d’événements pour le moment où un changement d’état se produit :
document.getElementById("upload").addEventListener("change", uploadImages);
Vous devez créer une fonction pour le moment où l’état change :
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);
}
Dans cet exemple, vous avez créé un FileReader
pour lire chaque image en tant qu’images base64
encodées, puis créer un Blob
avant d’appeler l’API ChatSDK pour les charger. Vous avez créé un global uploadedImageModels
pour enregistrer les modèles de données des images chargées à partir du Kit de développement logiciel (SDK) Chat.
Enfin, vous devez modifier l'écouteur d'événement sendMessageButton
que vous avez créé précédemment pour attacher les images que vous avez chargées.
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}`);
});
C’est terminé. Exécutez maintenant le code pour le voir en action.
Exécuter le code
Les utilisateurs Webpack peuvent utiliser webpack-dev-server
pour générer et exécuter votre application. Exécutez la commande suivante pour empaqueter l'hôte de votre application sur un serveur web local :
npx webpack-dev-server --entry ./client.js --output bundle.js --debug --devtool inline-source-map
Démonstration
Ouvrez votre navigateur et accédez à http://localhost:8080/
. Vous disposez d’une nouvelle section dans la zone d’envoi pour joindre des images.
Ensuite, vous pouvez sélectionner les images que vous souhaitez attacher.
L’utilisateur Teams doit maintenant recevoir l’image que vous venez d’envoyer quand il sélectionne Envoyer.
Ce tutoriel vous montre comment activer la prise en charge des images intégrées à l’aide du SDK de chat d'Azure Communication Services pour C#.
Dans ce tutoriel, vous allez apprendre à :
- Gérez les images incorporées pour les nouveaux messages.
Conditions préalables
- Passez en revue le guide de démarrage rapide Joindre votre application de conversation à une réunion Teams.
- Créez une ressource Azure Communication Services. Pour plus d’informations, consultez Créer une ressource Azure Communication Services. Vous devez enregistrer votre chaîne de connexion pour ce tutoriel.
- Configurez une réunion Teams à l’aide de votre compte professionnel, et préparez l’URL de la réunion.
- Utilisez le Kit de développement logiciel (SDK) Chat pour C# (Azure.Communication.Chat) 1.3.0 ou la dernière version. Pour plus d’informations, consultez la bibliothèque de client Azure Communication Chat pour .NET.
Objectif
- Saisissez la propriété
previewUri
pour les pièces jointes d’images incorporées.
Gérer les images inline pour les nouveaux messages
Dans le guide de démarrage rapide, vous interrogez les messages et ajoutez de nouveaux messages à la messageList
propriété. Vous développez cette fonctionnalité ultérieurement pour inclure l’analyse et l’extraction des images inline.
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}");
}
}
À partir de l’événement entrant de type ChatMessageReceivedEvent
, la propriété nommée attachments
contient des informations sur l’image inline. Il vous suffit d’afficher des images inline dans votre interface utilisateur.
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 }
}
Le JSON suivant est un exemple de l'apparence de ChatAttachment
pour une pièce jointe d'image :
"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"
}
]
Revenez en arrière et remplacez le code pour ajouter une logique supplémentaire pour analyser et extraire les pièces jointes de l’image :
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}");
}
Dans cet exemple, vous récupérez toutes les pièces jointes du message de type Image
, puis récupérez chacune des images. Vous devez utiliser votre Token
dans la partie Bearer
de l'en-tête de la requête à des fins d'autorisation. Une fois l’image téléchargée, vous pouvez l’affecter à l’élément InlineImage
de la vue.
Vous incluez également une liste des URI de pièce jointe à afficher avec le message dans la liste de messages texte.
Démonstration
- Exécutez l’application à partir de l’environnement de développement intégré (IDE).
- Entrez un lien de réunion Teams.
- Rejoindre la conversation d’une réunion.
- Acceptez l’utilisateur côté Teams.
- Envoyez un message du côté Teams avec une image.
L’URL incluse dans le message apparaît dans la liste des messages. La dernière image reçue est affichée en bas de la fenêtre.
Étapes suivantes
- Découvrez plus en détail les autres fonctionnalités d’interopérabilité prises en charge.
- Consultez notre exemple de conversation de référence.
- Découvrez plus en détail le fonctionnement de la conversation.