Włączanie udostępniania plików przy użyciu biblioteki interfejsu użytkownika w czacie usług Azure Communication Services za pomocą usługi Azure Blob Storage

Ważne

Ta funkcja usług Azure Communication Services jest obecnie dostępna w wersji zapoznawczej.

Interfejsy API i zestawy SDK w wersji zapoznawczej są udostępniane bez umowy dotyczącej poziomu usług. Zalecamy, aby nie używać ich w przypadku obciążeń produkcyjnych. Niektóre funkcje mogą nie być obsługiwane lub mogą mieć ograniczone możliwości.

Aby uzyskać więcej informacji, zapoznaj się z dodatkowymi warunkami użytkowania dla wersji zapoznawczych platformy Microsoft Azure.

W czacie usług Azure Communication Services możemy włączyć udostępnianie plików między użytkownikami komunikacji. Uwaga: czat usług Azure Communication Services różni się od czatu współdziałania usługi Teams ("Czat międzyoperacyjny"). Jeśli chcesz włączyć udostępnianie plików w czacie międzyoperajowym, zapoznaj się z tematem Dodawanie udostępniania plików za pomocą biblioteki interfejsu użytkownika w czacie współdziałania usługi Teams.

W tym samouczku konfigurujemy bibliotekę interfejsu użytkownika usług Azure Communication Services Chat Composite w celu włączenia udostępniania plików. Biblioteka interfejsu użytkownika Chat Composite udostępnia zestaw zaawansowanych składników i kontrolek interfejsu użytkownika, które mogą służyć do udostępniania plików. Używamy usługi Azure Blob Storage, aby umożliwić przechowywanie plików udostępnianych za pośrednictwem wątku czatu.

Ważne

Usługi Azure Communication Services nie zapewniają usługi magazynu plików. Do udostępniania plików należy użyć własnej usługi magazynu plików. Aby uzyskać informacje na ten samouczek, używamy usługi Azure Blob Storage.**

Pobieranie kodu

Uzyskaj dostęp do pełnego kodu dla tego samouczka w usłudze GitHub. Jeśli chcesz używać udostępniania plików przy użyciu składników interfejsu użytkownika, zapoznaj się z tym przykładem.

Wymagania wstępne

W tym samouczku założono, że wiesz już, jak skonfigurować i uruchomić aplikację Chat Composite. Możesz skorzystać z samouczka Chat Composite, aby dowiedzieć się, jak skonfigurować i uruchomić aplikację Chat Composite.

Omówienie

Biblioteka interfejsu użytkownika Chat Composite obsługuje udostępnianie plików, umożliwiając deweloperom przekazywanie adresu URL do pliku hostowanego, który jest wysyłany za pośrednictwem usługi czatu usług Azure Communication Services. Biblioteka interfejsu użytkownika renderuje dołączony plik i obsługuje wiele rozszerzeń w celu skonfigurowania wyglądu i działania wysyłanego pliku. W szczególności obsługuje następujące funkcje:

  1. Przycisk Dołącz plik do wybierania plików za pośrednictwem selektora plików systemu operacyjnego
  2. Konfigurowanie dozwolonych rozszerzeń plików.
  3. Włączanie/wyłączanie wielu przekazywania.
  4. Ikony plików dla różnych typów plików.
  5. Karty przekazywania/pobierania plików ze wskaźnikami postępu.
  6. Możliwość dynamicznego weryfikowania każdego przekazywania i wyświetlania błędów w interfejsie użytkownika.
  7. Możliwość anulowania przekazywania i usuwania przekazanego pliku przed jego wysłaniem.
  8. Wyświetl przekazane pliki w elemecie MessageThread, pobierz je. Umożliwia pobieranie asynchroniczne.

Diagram przedstawia typowy przepływ scenariusza udostępniania plików zarówno w przypadku przekazywania, jak i pobierania. Sekcja oznaczona jako Client Managed pokazuje bloki konstrukcyjne, w których deweloperzy muszą je zaimplementować.

Typowy przepływ udostępniania plików

Konfigurowanie magazynu plików przy użyciu usługi Azure Blob

Możesz wykonać czynności opisane w samouczku Przekazywanie pliku do usługi Azure Blob Storage za pomocą funkcji platformy Azure, aby napisać kod zaplecza wymagany do udostępniania plików.

Po zaimplementowaniu można wywołać tę funkcję platformy Azure wewnątrz handleAttachmentSelection funkcji w celu przekazania plików do usługi Azure Blob Storage. W pozostałej części samouczka przyjęto założenie, że funkcja została wygenerowana przy użyciu samouczka dotyczącego połączonej wcześniej usługi Azure Blob Storage.

Zabezpieczanie kontenera usługi Azure Blob Storage

W tym samouczku założono, że kontener usługi Azure Blob Storage umożliwia publiczny dostęp do przekazanych plików. Publiczne udostępnianie kontenerów usługi Azure Storage nie jest zalecane w przypadku rzeczywistych aplikacji produkcyjnych.

Aby pobrać pliki, przekazujesz do usługi Azure Blob Storage, możesz użyć sygnatur dostępu współdzielonego (SAS). Sygnatura dostępu współdzielonego (SAS) zapewnia bezpieczny delegowany dostęp do zasobów na koncie magazynu. Dzięki sygnaturze dostępu współdzielonego masz szczegółową kontrolę nad sposobem uzyskiwania dostępu do danych przez klienta.

Przykład z możliwością pobrania w usłudze GitHub przedstawia użycie sygnatury dostępu współdzielonego do tworzenia adresów URL sygnatur dostępu współdzielonego do zawartości usługi Azure Storage. Ponadto możesz dowiedzieć się więcej o sygnaturze dostępu współdzielonego.

Biblioteka interfejsu użytkownika wymaga skonfigurowania środowiska React. Następnie to zrobimy. Jeśli masz już aplikację React, możesz pominąć tę sekcję.

Konfigurowanie aplikacji react

Na potrzeby tego przewodnika Szybki start użyjemy szablonu create-react-app. Aby uzyskać więcej informacji, zobacz: Rozpoczynanie pracy z platformą React


npx create-react-app ui-library-quickstart-composites --template typescript

cd ui-library-quickstart-composites

Na końcu tego procesu należy mieć pełną aplikację w folderze ui-library-quickstart-composites. W tym przewodniku src Szybki start modyfikujemy pliki wewnątrz folderu.

Instalowanie pakietu

Użyj polecenia , npm install aby zainstalować wersję beta biblioteki interfejsu użytkownika usług Azure Communication Services dla języka JavaScript.


npm install @azure/communication-react@1.16.0-beta.1

@azure/communication-react Określa podstawowe usługi Azure Communication Services, peerDependencies tak aby można było najbardziej spójnie używać interfejsu API z podstawowych bibliotek w aplikacji. Należy również zainstalować te biblioteki:


npm install @azure/communication-calling@1.24.1-beta.2
npm install @azure/communication-chat@1.6.0-beta.1

Tworzenie aplikacji React

Przetestujmy instalację utwórz aplikację React, uruchamiając polecenie:


npm run start

Konfigurowanie aplikacji Chat Composite w celu włączenia udostępniania plików

Należy zastąpić wartości zmiennych dla obu wspólnych zmiennych wymaganych do zainicjowania złożonego czatu.

App.tsx

import { initializeFileTypeIcons } from '@fluentui/react-file-type-icons';
import {
  ChatComposite,
  AttachmentUploadTask,
  AttachmentUploadOptions,
  AttachmentSelectionHandler,
  fromFlatCommunicationIdentifier,
  useAzureCommunicationChatAdapter
} from '@azure/communication-react';
import React, { useMemo } from 'react';

initializeFileTypeIcons();

function App(): JSX.Element {
  // Common variables
  const endpointUrl = 'INSERT_ENDPOINT_URL';
  const userId = ' INSERT_USER_ID';
  const displayName = 'INSERT_DISPLAY_NAME';
  const token = 'INSERT_ACCESS_TOKEN';
  const threadId = 'INSERT_THREAD_ID';

  // We can't even initialize the Chat and Call adapters without a well-formed token.
  const credential = useMemo(() => {
    try {
      return new AzureCommunicationTokenCredential(token);
    } catch {
      console.error('Failed to construct token credential');
      return undefined;
    }
  }, [token]);

  // Memoize arguments to `useAzureCommunicationChatAdapter` so that
  // a new adapter is only created when an argument changes.
  const chatAdapterArgs = useMemo(
    () => ({
      endpoint: endpointUrl,
      userId: fromFlatCommunicationIdentifier(userId) as CommunicationUserIdentifier,
      displayName,
      credential,
      threadId
    }),
    [userId, displayName, credential, threadId]
  );
  const chatAdapter = useAzureCommunicationChatAdapter(chatAdapterArgs);

  if (!!chatAdapter) {
    return (
      <>
        <div style={containerStyle}>
          <ChatComposite
            adapter={chatAdapter}
            options={{
              attachmentOptions: {
                uploadOptions: uploadOptions,
                downloadOptions: downloadOptions,
              }
            }} />
        </div>
      </>
    );
  }
  if (credential === undefined) {
    return <h3>Failed to construct credential. Provided token is malformed.</h3>;
  }
  return <h3>Initializing...</h3>;
}

const uploadOptions: AttachmentUploadOptions = {
  // default is false
  disableMultipleUploads: false,
  // define mime types
  supportedMediaTypes: ["image/jpg", "image/jpeg"]
  handleAttachmentSelection: attachmentSelectionHandler,
}

const attachmentSelectionHandler: AttachmentSelectionHandler = async (uploadTasks) => {
  for (const task of uploadTasks) {
    try {
      const uniqueFileName = `${v4()}-${task.file?.name}`;
      const url = await uploadFileToAzureBlob(task);
      task.notifyUploadCompleted(uniqueFileName, url);
    } catch (error) {
      if (error instanceof Error) {
        task.notifyUploadFailed(error.message);
      }
    }
  }
}

const uploadFileToAzureBlob = async (uploadTask: AttachmentUploadTask) => {
  // You need to handle the file upload here and upload it to Azure Blob Storage.
  // This is how you can configure the upload
  // Optionally, you can also update the file upload progress.
  uploadTask.notifyUploadProgressChanged(0.2);
  return {
    url: 'https://sample.com/sample.jpg', // Download URL of the file.
  };

Konfigurowanie metody przekazywania do korzystania z usługi Azure Blob Storage

Aby włączyć przekazywanie usługi Azure Blob Storage, zmodyfikujemy uploadFileToAzureBlob metodę zadeklarowaną wcześniej przy użyciu następującego kodu. Aby przekazać pliki, musisz zastąpić informacje o funkcji platformy Azure.

App.tsx

const uploadFileToAzureBlob = async (uploadTask: AttachmentUploadTask) => {
  const file = uploadTask.file;
  if (!file) {
    throw new Error("uploadTask.file is undefined");
  }

  const filename = file.name;
  const fileExtension = file.name.split(".").pop();

  // Following is an example of calling an Azure Function to handle file upload
  // The https://learn.microsoft.com/azure/developer/javascript/how-to/with-web-app/azure-function-file-upload
  // tutorial uses 'username' parameter to specify the storage container name.
  // the container in the tutorial is private by default. To get default downloads working in
  // this sample, you need to change the container's access level to Public via Azure Portal.
  const username = "ui-library";

  // You can get function url from the Azure Portal:
  const azFunctionBaseUri = "<YOUR_AZURE_FUNCTION_URL>";
  const uri = `${azFunctionBaseUri}&username=${username}&filename=${filename}`;

  const formData = new FormData();
  formData.append(file.name, file);

  const response = await axios.request({
    method: "post",
    url: uri,
    data: formData,
    onUploadProgress: (p) => {
      // Optionally, you can update the file upload progess.
      uploadTask.notifyUploadProgressChanged(p.loaded / p.total);
    },
  });

  const storageBaseUrl = "https://<YOUR_STORAGE_ACCOUNT>.blob.core.windows.net";

  return {
    url: `${storageBaseUrl}/${username}/${filename}`,
  };
};

Obsługa błędów

Gdy przekazywanie zakończy się niepowodzeniem, biblioteka interfejsu użytkownika Chat Composite wyświetla komunikat o błędzie.

Pasek błędu przekazywania pliku

Oto przykładowy kod pokazujący, jak można zakończyć się niepowodzeniem przekazywania z powodu błędu weryfikacji rozmiaru:

App.tsx

import { AttachmentSelectionHandler } from from '@azure/communication-react';

const attachmentSelectionHandler: AttachmentSelectionHandler = async (uploadTasks) => {
  for (const task of uploadTasks) {
    if (task.file && task.file.size > 99 * 1024 * 1024) {
      // Notify ChatComposite about upload failure.
      // Allows you to provide a custom error message.
      task.notifyUploadFailed('File too big. Select a file under 99 MB.');
    }
  }
}

export const attachmentUploadOptions: AttachmentUploadOptions = {
  handleAttachmentSelection: attachmentSelectionHandler
};

Pobieranie plików — zaawansowane użycie

Domyślnie biblioteka interfejsu użytkownika otworzy nową kartę wskazującą adres URL ustawiony podczas .notifyUploadCompleted Alternatywnie możesz mieć niestandardową logikę do obsługi pobierania załączników za pośrednictwem elementu actionsForAttachment. Przyjrzyjmy się przykładowi.

App.tsx

import { AttachmentDownloadOptions } from "communication-react";

const downloadOptions: AttachmentDownloadOptions = {
  actionsForAttachment: handler
}

const handler = async (attachment: AttachmentMetadata, message?: ChatMessage) => {
   // here we are returning a static action for all attachments and all messages
   // alternately, you can provide custom menu actions based on properties in `attachment` or `message` 
   return [defaultAttachmentMenuAction];
};

const customHandler = = async (attachment: AttachmentMetadata, message?: ChatMessage) => {
   if (attachment.extension === "pdf") {
    return [
      {
        title: "Custom button",
        icon: (<i className="custom-icon"></i>),
        onClick: () => {
          return new Promise((resolve, reject) => {
              // custom logic here
              window.alert("custom button clicked");
              resolve();
              // or to reject("xxxxx") with a custom message
          })
        }
      },
      defaultAttachmentMenuAction
    ];
  } else if (message?.senderId === "user1") {
    return [
      {
        title: "Custom button 2",
        icon: (<i className="custom-icon-2"></i>),
        onClick: () => {
          return new Promise((resolve, reject) => {
            window.alert("custom button 2 clicked");
            resolve();
          })
        }
      },
      // you can also override the default action partially
      {
        ...defaultAttachmentMenuAction,
        onClick: () => {
          return new Promise((resolve, reject) => {
            window.alert("default button clicked");
            resolve();
          })
        }
      }
    ];
  }
}

Jeśli podczas pobierania wystąpiły jakiekolwiek problemy, a użytkownik musi zostać powiadomiony, możemy po prostu throw spowodować błąd z komunikatem w onClick funkcji, wówczas komunikat zostanie wyświetlony na pasku błędu w górnej części aplikacji Chat Composite.

Błąd pobierania pliku

Czyszczenie zasobów

Jeśli chcesz wyczyścić i usunąć subskrypcję usług Komunikacyjnych, możesz usunąć zasób lub grupę zasobów. Usunięcie grupy zasobów powoduje również usunięcie wszelkich innych skojarzonych z nią zasobów. Możesz dowiedzieć się więcej na temat czyszczenia zasobów usług Azure Communication Services i czyszczenia zasobów funkcji platformy Azure.

Następne kroki

Możesz również wykonać następujące czynności: