Kurz: Povolení podpory vložených obrázků v chatovací aplikaci
Sada SDK chatu je navržená tak, aby bez problémů fungovala s Microsoft Teams. Konkrétně sada SDK chatu poskytuje řešení pro příjem vložených obrázků a odesílání vložených obrázků uživatelům z Microsoft Teams.
V tomto kurzu se dozvíte, jak povolit podporu vložených imagí pomocí sady SDK chatu služby Azure Communication Services pro JavaScript.
Vložené obrázky jsou obrázky, které se zkopírují a vloží přímo do pole pro odeslání klienta Teams. U obrázků nahraných prostřednictvím nabídky Nahrát z této nabídky zařízení nebo přetažení, jako jsou například obrázky přetažené přímo do pole pro odeslání v Aplikaci Teams, je potřeba použít tento kurz jako součást funkce sdílení souborů. (Viz část Popisovat přílohy obrázků.)
Pokud chcete obrázek zkopírovat, mají uživatelé Teams dvě možnosti:
- Pomocí místní nabídky operačního systému zkopírujte soubor image a vložte ho do pole pro odeslání klienta Teams.
- Používejte klávesové zkratky.
V tomto kurzu se dozvíte, co potřebujete udělat, když:
Poznámka:
Možnost odesílat vložené obrázky je aktuálně dostupná ve verzi Public Preview. Je k dispozici pouze pro JavaScript. Pro příjem vložených obrázků je aktuálně obecně dostupná. Je k dispozici pro JavaScript i C# v chatu s interoperabilitou Teams.
Požadavky
- Projděte si rychlý start Připojení k chatovací aplikaci ke schůzce Teams.
- Vytvořte zdroj Azure Communication Services. Další informace najdete v tématu Vytvoření prostředku Azure Communication Services. Musíte zaznamenat připojovací řetězec pro účely tohoto kurzu.
- Nastavte schůzku Teams pomocí svého firemního účtu a připravte adresu URL schůzky.
- Použijte sadu SDK chatu pro JavaScript (@azure/communication-chat) 1.4.0 nebo nejnovější. Další informace najdete v klientské knihovně Azure Communication Chat pro JavaScript.
Ukázkový kód
Najděte finalizovaný kód tohoto kurzu na GitHubu.
Zpracování přijatých vložených obrázků v nové události zprávy
V této části se dozvíte, jak můžete vykreslit vložené obrázky vložené do obsahu zprávy nové přijaté události.
V rychlém startu jste vytvořili obslužnou rutinu události pro chatMessageReceived
událost, která se aktivuje při přijetí nové zprávy od uživatele Teams. Obsah příchozí zprávy také připojíte přímo při messageContainer
přijetí chatMessageReceived
události z objektu chatClient
, například takto:
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;
}
Z příchozí události typu ChatMessageReceivedEvent
, vlastnost pojmenovaná attachments
obsahuje informace o vloženém obrázku. Stačí vykreslit vložené obrázky v uživatelském rozhraní:
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";
Teď se vraťte k předchozímu kódu a přidejte další logiku, například následující fragmenty kódu:
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;
});
}
V tomto příkladu jste vytvořili dvě pomocné funkce fetchPreviewImages
a setImgHandler
. První načte obrázek náhledu přímo ze zadaného objektu previewURL
ChatAttachment
s hlavičkou ověřování. Podobně nastavíte onclick
událost pro každý obrázek ve funkci setImgHandler
. V obslužné rutině události načtete obrázek v plném měřítku z vlastnosti url
z objektu ChatAttachment
s hlavičkou ověřování.
Teď musíte token zveřejnit na globální úrovni, protože s ním potřebujete vytvořit hlavičku ověřování. Musíte upravit následující kód:
// 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;
...
}
Pokud chcete zobrazit celý obrázek v překryvu, musíte také přidat novou komponentu:
<div class="overlay" id="overlay-container">
<div class="content">
<img id="full-scale-image" src="" alt="" />
</div>
</div>
S některými šablonami stylů 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
}
Teď, když máte nastavenou překryvnou vrstvu, je čas pracovat na logice pro vykreslení plně škálovatelných obrázků. Vzpomeňte si, že jste vytvořili obslužnou rutinu onClick
události pro volání funkce 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';
}
Jednou z posledních věcí, kterou chcete přidat, je možnost zavřít překryv při kliknutí na obrázek:
loadingImageOverlay.addEventListener('click', () => {
overlayContainer.style.display = 'none';
});
Teď jste provedli všechny změny, které potřebujete k vykreslení vložených obrázků pro zprávy, které pocházejí z oznámení v reálném čase.
Spuštění kódu
Uživatelé webpacku můžou použít webpack-dev-server
k sestavení a spuštění aplikace. Spuštěním následujícího příkazu sbalte hostitele aplikace na místním webovém serveru:
npx webpack-dev-server --entry ./client.js --output bundle.js --debug --devtool inline-source-map
Ukázka
Otevřete prohlížeč a přejděte na http://localhost:8080/
. Zadejte adresu URL schůzky a ID vlákna. Odešlete některé vložené obrázky z klienta Teams.
Pak by se měla zobrazit nová zpráva vykreslená společně s obrázky náhledu.
Jakmile uživatel Azure Communication Services vybere obrázek náhledu, zobrazí se překryvný obrázek s plně škálovatelným obrázkem odeslaným uživatelem Teams.
Zpracování odesílání vložených obrázků v nové žádosti o zprávu
Důležité
Tato funkce služeb Azure Communication Services je aktuálně ve verzi Preview.
Rozhraní API a sady SDK verze Preview jsou poskytovány bez smlouvy o úrovni služeb. Doporučujeme je nepoužívat pro produkční úlohy. Některé funkce nemusí být podporované nebo můžou mít omezené možnosti.
Další informace najdete v dodatečných podmínkách použití pro verze Preview Microsoft Azure.
Kromě zpracování zpráv s vloženými obrázky poskytuje sada SDK chatu pro JavaScript také řešení, které umožňuje komunikačnímu uživateli posílat vložené obrázky uživateli Microsoft Teams v chatu interoperability.
Podívejte se na nové rozhraní API z ChatThreadClient
:
var imageAttachment = await chatThreadClient.uploadImage(blob, file.name, {
"onUploadProgress": reportProgressCallback
});
Rozhraní API přebírá objekt blob obrázku, řetězec názvu souboru a zpětné volání funkce, které hlásí průběh nahrávání.
Pokud chcete poslat obrázek jinému účastníkovi chatu, musíte:
- Nahrajte obrázek přes
uploadImage
rozhraní API aChatThreadClient
uložte vrácený objekt. - Vytvořte obsah zprávy a nastavte přílohu na vrácený objekt, který jste uložili v předchozím kroku.
- Odešlete novou zprávu prostřednictvím
sendMessage
rozhraní API zChatThreadClient
.
Vytvořte nový výběr souborů, který přijímá obrázky:
<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>
Teď nastavte naslouchací proces událostí, když dojde ke změně stavu:
document.getElementById("upload").addEventListener("change", uploadImages);
Pokud se změní stav, musíte vytvořit novou funkci:
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);
}
V tomto příkladu jste vytvořili obrázek, který FileReader
bude číst jako base64
obrázky s kódováním, a pak vytvoříte před Blob
voláním rozhraní API ChatSDK, které je nahraje. Vytvořili jste globální uploadedImageModels
objekt pro ukládání datových modelů nahraných obrázků ze sady SDK chatu.
Nakonec musíte upravit naslouchací sendMessageButton
proces události, který jste vytvořili dříve, a připojit obrázky, které jste nahráli.
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}`);
});
Hotovo. Teď spusťte kód, abyste ho viděli v akci.
Spuštění kódu
Uživatelé webpacku můžou použít webpack-dev-server
k sestavení a spuštění aplikace. Spuštěním následujícího příkazu sbalte hostitele aplikace na místním webovém serveru:
npx webpack-dev-server --entry ./client.js --output bundle.js --debug --devtool inline-source-map
Ukázka
Otevřete prohlížeč a přejděte na http://localhost:8080/
. V poli pro odeslání máte nový oddíl pro připojení obrázků.
Dále můžete vybrat obrázky, které chcete připojit.
Uživatel Teams by teď měl dostat obrázek, který jste právě odeslali, když vyberou Možnost Odeslat.
V tomto kurzu se dozvíte, jak povolit podporu vložených imagí pomocí sady SDK chatu služeb Azure Communication Services pro jazyk C#.
V tomto kurzu se naučíte:
- Zpracování vložených obrázků pro nové zprávy
Požadavky
- Projděte si rychlý start , připojte se ke své chatovací aplikaci ke schůzce Teams.
- Vytvořte zdroj Azure Communication Services. Další informace najdete v tématu Vytvoření prostředku Azure Communication Services. Musíte zaznamenat připojovací řetězec pro účely tohoto kurzu.
- Nastavte schůzku Teams pomocí svého firemního účtu a připravte adresu URL schůzky.
- Použijte sadu SDK chatu pro C# (Azure.Communication.Chat) 1.3.0 nebo nejnovější. Další informace najdete v klientské knihovně azure Communication Chat pro .NET.
Goal
previewUri
Uchopte vlastnost pro vložené přílohy obrázků.
Zpracování vložených obrázků pro nové zprávy
V rychlém startu se budete dotazovat na zprávy a přidávat do vlastnosti nové zprávymessageList
. Na této funkci se později stavíte, abyste zahrnuli analýzu a načítání vložených imagí.
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}");
}
}
Z příchozí události typu ChatMessageReceivedEvent
, vlastnost pojmenovaná attachments
obsahuje informace o vloženém obrázku. Stačí vykreslit vložené obrázky v uživatelském rozhraní.
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 }
}
Následující JSON je příkladem toho, co ChatAttachment
by mohlo vypadat jako u přílohy obrázku:
"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"
}
]
Vraťte se zpět a nahraďte kód, který přidá další logiku pro parsování a načtení příloh obrázků:
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}");
}
V tomto příkladu vezmete všechny přílohy ze zprávy typu Image
a pak načtete každý z obrázků. K autorizačním účelům musíte použít svoji Token
část Bearer
hlavičky požadavku. Po stažení obrázku ho můžete přiřadit k InlineImage
prvku zobrazení.
Zahrnete také seznam identifikátorů URI přílohy, které se zobrazí spolu se zprávou v seznamu textových zpráv.
Ukázka
- Spusťte aplikaci z integrovaného vývojového prostředí (IDE).
- Zadejte odkaz na schůzku v Teams.
- Připojte se ke schůzce.
- Povolte uživatele na straně Teams.
- Odešlete zprávu ze strany Teams s obrázkem.
Adresa URL, která je součástí zprávy, se zobrazí v seznamu zpráv. Poslední přijatý obrázek se vykreslí v dolní části okna.
Další kroky
- Přečtěte si další informace o dalších podporovaných funkcích interoperability.
- Podívejte se na ukázku našeho hrdiny chatu.
- Přečtěte si další informace o tom, jak chat funguje.