Personalizar a aparência de um agente

Note

Este artigo descreve as funcionalidades usadas em agentes ou fluxos de agentes alimentados pelo arnês padrão.

O quadro do agente controla como o agente aparece para os utilizadores. Pode personalizar a tela de duas formas:

Também pode combinar a tela personalizada com a configuração de um início automático de conversa.

Podes mudar o nome e o ícone do agente no portal.

Depois de publicar um agente, os utilizadores podem interagir com ele através do Webchat canvas.

Important

Você pode instalar e usar o código de exemplo incluído neste artigo apenas para uso com o Copilot Studio. O código de exemplo é licenciado "no estado em que se encontra" e é excluído de quaisquer contratos de nível de serviço ou serviços de suporte. Você assume o risco de usá-lo.

A Microsoft não dá garantias expressas, garantias ou condições e exclui todas as garantias implícitas, incluindo comercialização, adequação a uma finalidade específica e não violação.

Alterar o nome e o ícone do agente

Important

  • Depois de atualizar o ícone de um agente, pode levar até 24 horas para que o novo ícone apareça em todos os lugares.
  • Se o seu agente estiver ligado ao Omnicanal para Atendimento ao Cliente, a propriedade Nome de exibição no portal de registo do portal de Azure define o seu nome.
  • Se o seu agente está destinado a ser publicado no Teams, revise os requisitos para ícones na documentação do Microsoft Teams para programadores.
  1. Vá para a página Visão geral do seu agente.

  2. Selecione Editar ao lado de Detalhes.

  3. Altere o nome e o ícone do agente conforme desejado.

  4. Selecione Guardar.

Personalizar o quadro padrão (simples)

Usa JavaScript e CSS para ajustar a tela padrão.

Primeiro, configure onde está a implementar o seu agent canvas.

  1. Crie e publique um agente.

  2. Copie o código HTML de exemplo para um ficheiro chamado index.html. Também pode usar o editor de teste em HTML.

    
    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <meta name="description" content="Contoso Web Chat Assistant" />
        <title>Contoso Sample Web Chat Test</title>
        <script src="https://cdn.botframework.com/botframework-webchat/latest/webchat.js"></script>
        <script>
          let webChatInstance = null;
          let directLineUrl = null;
    
          // Replace with your token endpoint
          const tokenEndpoint = "<YOUR TOKEN ENDPOINT>";
          const styleOptions = {
            "accent": "#0078D4",
            "autoScrollSnapOnPage": true,
            "autoScrollSnapOnPageOffset": 0,
            "avatarBorderRadius": "7%",
            "avatarSize": 31,
            "backgroundColor": "#e8e9eb",
            "botAvatarBackgroundColor": "#ffffff00",
            "botAvatarImage": "https://powercatexternal.blob.core.windows.net/creatorkit/Assets/ChatbotLogoBlue.png",
            "botAvatarInitials": "B",
            "bubbleAttachmentMaxWidth": 480,
            "bubbleAttachmentMinWidth": 250,
            "bubbleBackground": "#f0eded",
            "bubbleBorderColor": "#f5f5f5",
            "bubbleBorderRadius": 41,
            "bubbleBorderStyle": "solid",
            "bubbleBorderWidth": 1,
            "bubbleFromUserBackground": "#ebefff",
            "bubbleFromUserBorderColor": "#f5f5f5",
            "bubbleFromUserBorderRadius": 41,
            "bubbleFromUserBorderStyle": "solid",
            "bubbleFromUserBorderWidth": 1,
            "bubbleFromUserNubOffset": 0,
            "bubbleFromUserNubSize": 0,
            "bubbleFromUserTextColor": "#242424",
            "bubbleImageHeight": 10,
            "bubbleImageMaxHeight": 240,
            "bubbleImageMinHeight": 240,
            "bubbleMessageMaxWidth": 480,
            "bubbleMessageMinWidth": 120,
            "bubbleMinHeight": 50,
            "bubbleNubOffset": 0,
            "bubbleTextColor": "#242424",
            "emojiSet": true,
            "fontSizeSmall": "70%",
            "hideUploadButton": false,
            "messageActivityWordBreak": "break-word",
            "monospaceFont": "Consolas",
            "paddingRegular": 10,
            "paddingWide": 10,
            "primaryFont": null,
            "sendBoxBackground": "#e8e9eb",
            "sendBoxBorderTop": "solid 1px #808080",
            "sendBoxButtonColor": "#0078d4",
            "sendBoxButtonColorOnHover": "#006cbe",
            "sendBoxButtonShadeBorderRadius": 40,
            "sendBoxButtonShadeColorOnHover": "",
            "sendBoxHeight": 60,
            "sendBoxPlaceholderColor": "#171616",
            "sendBoxTextColor": "#2e2d2d",
            "showAvatarInGroup": "status",
            "spinnerAnimationHeight": 16,
            "spinnerAnimationPadding": 12,
            "spinnerAnimationWidth": 16,
            "subtleColor": "#000000FF",
            "suggestedActionBackgroundColor": "#006FC4FF",
            "suggestedActionBackgroundColorOnHover": "#0078D4",
            "suggestedActionBorderColor": "",
            "suggestedActionBorderRadius": 10,
            "suggestedActionBorderWidth": 1,
            "suggestedActionLayout": "flow",
            "suggestedActionTextColor": "#FFFFFFFF",
            "typingAnimationBackgroundImage": "url('https://wpamelia.com/wp-content/uploads/2018/11/ezgif-2-6d0b072c3d3f.gif')",
            "typingAnimationDuration": 5000,
            "typingAnimationHeight": 20,
            "typingAnimationWidth": 64,
            "userAvatarBackgroundColor": "#222222",
            "userAvatarImage": "https://avatars.githubusercontent.com/u/8174072?v=4&size=64",
            "userAvatarInitials": "U"
          };
          const backgroundImage = "";
    
          document.addEventListener('DOMContentLoaded', () => {
            const root = document.documentElement;
            root.style.setProperty('--primary-color', createGradient(styleOptions.accent));
            root.style.setProperty('--header-textColor', styleOptions.suggestedActionTextColor);
    
            if (backgroundImage) {
              const webchatElement = document.getElementById('webchat');
              webchatElement.style.backgroundImage = `url(${backgroundImage})`;
              webchatElement.style.backgroundSize = 'cover';
              webchatElement.style.backgroundPosition = 'center';
              webchatElement.style.backgroundRepeat = 'no-repeat';
    
              const overlay = document.createElement('div');
              overlay.className = 'webchat-overlay';
              webchatElement.appendChild(overlay);
            }
          });
    
          function createGradient(baseColor) {
            const r = parseInt(baseColor.slice(1, 3), 16);
            const g = parseInt(baseColor.slice(3, 5), 16);
            const b = parseInt(baseColor.slice(5, 7), 16);
            const lighterColor = `#${Math.min(255, r + 30).toString(16).padStart(2, '0')}${Math.min(255, g + 30).toString(16).padStart(2, '0')}${Math.min(255, b + 30).toString(16).padStart(2, '0')}`;
            const darkerColor = `#${Math.max(0, r - 30).toString(16).padStart(2, '0')}${Math.max(0, g - 30).toString(16).padStart(2, '0')}${Math.max(0, b - 30).toString(16).padStart(2, '0')}`;
            return `linear-gradient(135deg, ${lighterColor}, ${baseColor}, ${darkerColor})`;
          }
    
          const environmentEndPoint = tokenEndpoint.slice(
            0,
            tokenEndpoint.indexOf("/powervirtualagents")
          );
          const apiVersion = tokenEndpoint
            .slice(tokenEndpoint.indexOf("api-version"))
            .split("=")[1];
          const regionalChannelSettingsURL = `${environmentEndPoint}/powervirtualagents/regionalchannelsettings?api-version=${apiVersion}`;
    
          function showChat() {
            const popup = document.getElementById("chatbot-popup");
            const openButton = document.getElementById("open-chat");
            popup.classList.add("visible");
            openButton.classList.add("hidden");
          }
    
          function hideChat() {
            const popup = document.getElementById("chatbot-popup");
            const openButton = document.getElementById("open-chat");
            popup.classList.remove("visible");
            openButton.classList.remove("hidden");
          }
    
          function createCustomStore() {
            return window.WebChat.createStore(
              {},
              ({ dispatch }) =>
                (next) =>
                (action) => {
                  if (action.type === "DIRECT_LINE/CONNECT_FULFILLED") {
                    dispatch({
                      type: "DIRECT_LINE/POST_ACTIVITY",
                      meta: { method: "keyboard" },
                      payload: {
                        activity: {
                          channelData: { postBack: true },
                          name: "startConversation",
                          type: "event",
                        },
                      },
                    });
                  }
                  return next(action);
                }
            );
          }
    
          async function restartConversation() {
            try {
              if (!directLineUrl) {
                console.error("DirectLine URL not initialized");
                return;
              }
    
              const response = await fetch(tokenEndpoint);
              const conversationInfo = await response.json();
    
              if (!conversationInfo.token) {
                throw new Error("Failed to get conversation token");
              }
    
              const newDirectLine = window.WebChat.createDirectLine({
                domain: `${directLineUrl}v3/directline`,
                token: conversationInfo.token,
              });
    
              const webchatElement = document.getElementById("webchat");
              webChatInstance = window.WebChat.renderWebChat(
                {
                  directLine: newDirectLine,
                  styleOptions,
                  store: createCustomStore(),
                },
                webchatElement
              );
            } catch (err) {
              console.error("Failed to restart conversation:", err);
            }
          }
    
          async function initializeChat() {
            try {
              const response = await fetch(regionalChannelSettingsURL);
              const data = await response.json();
              directLineUrl = data.channelUrlsById.directline;
    
              if (!directLineUrl) {
                throw new Error("Failed to get DirectLine URL");
              }
    
              const conversationResponse = await fetch(tokenEndpoint);
              const conversationInfo = await conversationResponse.json();
    
              if (!conversationInfo.token) {
                throw new Error("Failed to get conversation token");
              }
    
              const directLine = window.WebChat.createDirectLine({
                domain: `${directLineUrl}v3/directline`,
                token: conversationInfo.token,
              });
    
              webChatInstance = window.WebChat.renderWebChat(
                {
                  directLine,
                  styleOptions,
                  store: createCustomStore(),
                },
                document.getElementById("webchat")
              );
            } catch (err) {
              console.error("Failed to initialize chat:", err);
            }
          }
    
          initializeChat();
      </script>
      <style>
        :root {
          --primary-gradient: var(--primary-color);
          --chat-width: 450px;
          --chat-height: 520px;
          --header-height: 56px;
          --border-radius: 16px;
          --transition-speed: 0.3s;
        }
        * {
          margin: 0;
          padding: 0;
          box-sizing: border-box;
          font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI",
            Roboto, sans-serif;
        }
        body {
          min-height: 100vh;
          background-color: #f3f4f6;
        }
        #chatbot-popup {
          display: none;
          position: fixed;
          bottom: 32px;
          right: 32px;
          width: var(--chat-width);
          height: var(--chat-height);
          background: white;
          border-radius: var(--border-radius);
          box-shadow: 0 18px 40px -5px rgba(0, 0, 0, 0.2),
            0 15px 20px -5px rgba(0, 0, 0, 0.1);
          overflow: hidden;
          opacity: 0;
          transform-origin: bottom right;
          transform: scale(0.95);
          transition: all var(--transition-speed) ease-in-out;
          z-index: 999;
        }
        #chatbot-popup.visible {
          display: block;
          opacity: 1;
          transform: scale(1);
        }
        #chatbot-header {
          background: var(--primary-color);
          padding: 16px 20px;
          height: var(--header-height);
          display: flex;
          justify-content: space-between;
          align-items: center;
          color: var(--header-textColor);
        }
        .header-title {
          display: flex;
          align-items: center;
          gap: 12px;
          font-size: 16px;
          font-weight: 500;
        }
        .header-buttons {
          display: flex;
          gap: 12px;
          align-items: center;
        }
        .icon-button {
          background: none;
          border: none;
          color: var(--header-textColor);
          cursor: pointer;
          padding: 8px;
          border-radius: 8px;
          display: flex;
          align-items: center;
          justify-content: center;
          transition: all 0.2s ease;
        }
        .icon-button:hover {
          color: var(--header-textColor);
          background: rgba(255, 255, 255, 0.1);
        }
        .icon-button:focus {
          outline: 2px solid rgba(255, 255, 255, 0.5);
          outline-offset: 2px;
        }
        #webchat {
          height: calc(100% - var(--header-height));
          background-color: #f9fafb;
          position: relative;
        }
        .webchat-overlay {
          position: absolute;
          top: 0;
          left: 0;
          right: 0;
          bottom: 0;
          background: rgba(255, 255, 255, 0.85);
          pointer-events: none;
          z-index: 1;
        }
        #webchat > div {
          position: relative;
          z-index: 2;
        }
        #webchat .webchat__basic-transcript__content {
          white-space: pre-wrap !important;
          word-break: break-word !important;
        }
        #webchat .webchat__bubble__content {
          padding: 8px 12px !important;
        }
        #webchat .webchat__bubble {
          max-width: 85% !important;
          margin: 8px !important;
        }
        #webchat .webchat__basic-transcript__content ul,
        #webchat .webchat__basic-transcript__content ol,
        #webchat .webchat__bubble__content ul,
        #webchat .webchat__bubble__content ol {
          padding-left: 24px !important;
          margin: 8px 0 !important;
          list-style-position: outside !important;
        }
        #webchat .webchat__basic-transcript__content li,
        #webchat .webchat__bubble__content li {
          margin: 4px 0 !important;
          padding-left: 4px !important;
        }
        #open-chat {
          position: fixed;
          bottom: 32px;
          right: 32px;
          width: 64px;
          height: 64px;
          border-radius: 50%;
          background: var(--primary-gradient);
          border: none;
          cursor: pointer;
          display: flex;
          align-items: center;
          justify-content: center;
          box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
          transition: all var(--transition-speed) ease-in-out;
          z-index: 998;
        }
        #open-chat.hidden {
          opacity: 0;
          transform: scale(0.95) translateY(10px);
          pointer-events: none;
        }
        #open-chat:hover {
          transform: translateY(-4px);
          box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1);
        }
        #open-chat:focus {
          outline: 3px solid rgba(79, 70, 229, 0.5);
          outline-offset: 2px;
        }
        #open-chat svg {
          width: 28px;
          height: 28px;
          color: white;
          transition: transform 0.2s ease;
        }
        .main-content {
          max-width: 1200px;
          margin: 0 auto;
          padding: 48px 24px;
        }
        .main-content h1 {
          font-size: 36px;
          color: #111827;
          text-align: center;
        }
        .main-content p {
          font-size: 18px;
          color: #4b5563;
          line-height: 1.6;
          margin-bottom: 48px;
          text-align: center;
          max-width: 800px;
          margin-left: auto;
          margin-right: auto;
        }
        .content-grid {
          display: grid;
          grid-template-columns: repeat(2, 1fr);
          gap: 32px;
          margin-bottom: 32px;
        }
        .content-box {
          background: linear-gradient(135deg, #e6e6e6, #c4c4c4, #9f9f9f);
          padding: 32px;
          border-radius: 12px;
          box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1),
                      0 2px 4px -1px rgba(0, 0, 0, 0.06);
          min-height: 300px;
          display: flex;
          flex-direction: column;
          justify-content: center;
          align-items: center;
          text-align: center;
          position: relative;
          overflow: hidden;
        }
        .content-box::before {
          content: '';
          position: absolute;
          top: 0;
          left: 0;
          right: 0;
          height: 4px;
        }
        .content-box.featured {
          grid-column: span 2;
          min-height: 350px;
          background: linear-gradient(135deg, #e6e6e6, #c4c4c4, #9f9f9f);
          color: #000000;
        }
        .content-box h2 {
          font-size: 24px;
          margin-bottom: 16px;
          position: relative;
        }
        .content-box p {
          font-size: 16px;
          color: #6b7280;
          margin-bottom: 0;
        }
        .content-box.featured p {
          color: #000000;
        }
        @media (max-width: 768px) {
          .content-grid {
            grid-template-columns: 1fr;
          }
          .content-box.featured {
            grid-column: span 1;
          }
          .main-content {
            padding: 24px 16px;
          }
          .main-content h1 {
            font-size: 28px;
          }
          #chatbot-popup {
            width: 100%;
            height: 100%;
            bottom: 0;
            right: 0;
            border-radius: 0;
          }
        }
      </style>
    </head>
    <body>
      <div class="main-content">
        <h1>Header</h1>
        <p>Lorem ipsum dolor sit amet consectetur adipiscing elit. Quisque faucibus ex sapien vitae pellentesque sem placerat.</p>
        <div class="content-grid">
          <div class="content-box featured">
            <h2>Featured Content</h2>
            <p>Primary content area with custom styling and gradient background</p>
          </div>
          <div class="content-box">
            <h2>Section One</h2>
            <p>Content box with minimal design</p>
          </div>
          <div class="content-box">
            <h2>Section Two</h2>
            <p>Another content section with consistent styling</p>
          </div>
        </div>
      </div>
      <div id="chatbot-popup" role="complementary" aria-label="Chat Assistant">
        <div id="chatbot-header">
          <div class="header-title">
            <svg
              class="chat-icon"
              width="24"
              height="24"
              viewBox="0 0 24 24"
              fill="none"
              stroke="currentColor"
              stroke-width="2"
              stroke-linecap="round"
              stroke-linejoin="round"
              aria-hidden="true"
            >
              <path
                d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"
              ></path>
            </svg>
            <span>Contoso Assistant</span>
          </div>
          <div class="header-buttons">
            <button
              class="icon-button"
              id="restart-button"
              onclick="restartConversation()"
              aria-label="Restart Conversation"
            >
              <svg
                width="20"
                height="20"
                viewBox="0 0 24 24"
                fill="none"
                stroke="currentColor"
                stroke-width="2"
                stroke-linecap="round"
                stroke-linejoin="round"
                aria-hidden="true"
              >
                <path
                  d="M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8"
                ></path>
                <path d="M3 3v5h5"></path>
              </svg>
            </button>
            <button
              class="icon-button"
              id="close-button"
              onclick="hideChat()"
              aria-label="Close Chat"
            >
              <svg
                width="20"
                height="20"
                viewBox="0 0 24 24"
                fill="none"
                stroke="currentColor"
                stroke-width="2"
                stroke-linecap="round"
                stroke-linejoin="round"
                aria-hidden="true"
              >
                <line x1="18" y1="6" x2="6" y2="18"></line>
                <line x1="6" y1="6" x2="18" y2="18"></line>
              </svg>
            </button>
          </div>
        </div>
        <div id="webchat" role="main"></div>
      </div>
      <button
        id="open-chat"
        onclick="showChat()"
        aria-label="Open Chat Assistant"
      >
        <svg
          viewBox="0 0 24 24"
          fill="none"
          stroke="currentColor"
          stroke-width="2"
          stroke-linecap="round"
          stroke-linejoin="round"
          aria-hidden="true"
        >
          <path
            d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"
          ></path>
        </svg>
      </button>
    </body>
    </html>
    
    
  3. Recuperar o endpoint do token.

  4. Em index.html, substituir:

    const tokenEndpoint = "<YOUR TOKEN ENDPOINT>";
    

    com o seu endpoint de token.

  5. Abrir index.html num navegador moderno, como Microsoft Edge.

  6. Teste o agente.

Se o agente não responder:

  • Certifique-se de que o agente está publicado.
  • Verifica o valor do endpoint do token.
  • Confirme que o endpoint do token aparece após =, rodeado por aspas duplas ".

Obter o ponto final de token para o seu agente

Para personalizar a sua tela, seja a tela predefinida ou uma tela personalizada a que se liga, precisa do ponto final de token para o seu agente.

  1. Nas Definições, selecione Canais.

  2. Selecione E-mail.

  3. Ao lado de Ponto Final de Token, selecione Copiar.

Personalizar o ícone do agente, a cor do plano de fundo e o nome

Use o styleOptions objeto para configurar estilos pré-definidos.

Para mais informações sobre o que pode personalizar e ligações para o ficheiro defaultStyleOptions.js, veja Personalização do Webchat.

Alterar o ícone do agente

  1. Atualize o index.html arquivo com o seguinte código de exemplo:

    const styleOptions = {
      "accent": "#00809d",
      "botAvatarBackgroundColor": "#FFFFFF",
      "botAvatarImage": "https://learn.microsoft.com/azure/bot-service/v4sdk/media/logo_bot.svg",
      "botAvatarInitials": "BT",
      "userAvatarImage": "https://avatars.githubusercontent.com/u/661465",
      "userAvatarInitials": "U"
    };
    
  2. Substitua ambas as imagens de avatar pelas imagens da sua empresa. Se não tiver uma URL de imagem, use antes uma cadeia de imagem codificada em Base64.

Alterar a cor do plano de fundo

  1. No index.html adicione um elemento backgroundColor à sua definição styleOptions.

    const styleOptions = {
      "backgroundColor": "lightgray",
      // ...
    };
    
  2. Muda backgroundColor para a cor que quiseres. Use nomes padrão de cor CSS, valores RGB ou HEX.

Alterar o nome do agente

  1. Atualize o texto do cabeçalho no ficheiro <h1> com o seguinte código:

    <body>
      <div id="banner">
        <h1><img src="contoso-agent.png"> Contoso agent name</h1>
      </div>
      <!-- ... -->
    
  2. Altere o texto para o que pretender para chamar o agente. Também pode inserir uma imagem, mas pode ser necessário estilizá-la para que se encaixe na secção do título.

Personalize e hospede sua tela de bate-papo (avançado)

Pode ligar o seu agente do Copilot Studio a uma tela personalizada que aloja como uma aplicação web autónoma. Esta opção funciona melhor se precisar de incorporar um iFrame personalizado em várias páginas web.

Note

Hospedar uma tela personalizada requer desenvolvimento de software. Esta orientação destina-se a profissionais de TI experientes, como administradores ou programadores de TI que tenham um bom conhecimento de ferramentas, utilitários e ambientes de desenvolvimento integrados (IDEs) para programadores.

Comece com um destes exemplos personalizados para funcionar com o Copilot Studio:

  • Full bundle é uma tela personalizada capaz de mostrar todo o conteúdo rico do Copilot Studio. Por exemplo:

    Pacote completo de tela personalizada.

  • Localização e upload de arquivos é uma tela personalizada capaz de obter a localização de um usuário e enviá-la para um agente do Copilot Studio. Por exemplo:

    Localização e upload de arquivo de tela personalizada.

Em alternativa, experimente algumas outras amostras de interfaces de chat na web do Bot Framework.

Tal como no canvas padrão, podes usar styleSetOptions para ajustar o canvas personalizado. Todas as propriedades personalizáveis estão listadas em defaultStyleOptions.js. Para mais informações sobre o que pode customizar, veja Customização do Webchat.

Suportar a configuração da ligação num canvas

Quando um agente suportado pelo harness padrão precisa de uma ligação do utilizador, o canvas do chat recebe um Adaptive Card de ligação necessária. O seu canvas personalizado deve gerir a ação do card Action.OpenUrlDialog. Sem este tratamento, ao selecionar Ligar, não se abre a janela da ligação em foco.

Abra a janela de conexão

  1. Registe Action.OpenUrlDialog no seu Cartões Adaptativos renderer e leia a sua url propriedade. Aceita apenas um URL absoluto http:// ou https://.
  2. Decida se a origem do destino é confiável antes de a abrir. Confie apenas nas origens que controla ou que a sua equipa de segurança analisou e incluiu na lista de permissões.
  3. Abra o URL diretamente a partir da seleção do utilizador com window.open(url, "_blank", "popup"). Abrir a janela a partir de uma ação do utilizador reduz a probabilidade de o navegador a bloquear.
  4. Para um destino de confiança, no argumento windowFeatures de window.open, omite noopener e noreferrer assim a janela de ligação pode devolver um resultado a window.opener. Para qualquer outro destino, use noopener,noreferrer e não aceite uma mensagem de resposta.
  5. Manter a referência devolvida Window e o ID de atividade do cartão que requer ligação. Se o popup for bloqueado, ou se o utilizador o fechar sem um resultado válido, mantenha Continuar ou outra ação de recuperação disponível. Não interpretes o fecho da janela como um estabelecimento bem-sucedido da ligação.

O Cartões Adaptativos JavaScript SDK não implementa Action.OpenUrlDialog por defeito. Regista a ação através de SerializationContext.actionRegistry, ou trata a ação diretamente num renderizador que controla. Um Action.OpenUrl fallback pode abrir o destino em clientes que não suportam a ação de diálogo, mas o fallback não pode devolver um resultado de popup.

Important

Uma janela de ligação com acesso a window.opener pode navegar ou afetar a página do chat. Revise o destino e os seus redirecionamentos com a sua equipa de segurança web. Não permita que um destino confiável redirecione para um site não confiável enquanto mantém o acesso ao opener.

Se incorporares o Bot Framework Webchat, o seu processamento de Action.OpenUrlDialog abre a janela de ligação. Janelas da mesma origem são confiáveis por defeito. Para um destino de origem cruzada aprovado, defina styleOptions.callURLActionTrustedOrigin para a origem exata permitida. Separe múltiplas origens com vírgulas. Também pode definir callURLActionPopupWindowHeight e callURLActionPopupWindowWidth. Não adicione uma origem que ainda não analisou.

Continuar após a configuração bem-sucedida da ligação (versão preliminar)

[Esta secção é documentação de pré-lançamento e está sujeita a alterações.]

Important

Este artigo contém documentação de pré-visualização do Microsoft Copilot Studio e está sujeito a alterações.

As funcionalidades de pré-visualização não se destinam a ser utilizadas em ambiente de produção e podem ter funcionalidades restritas. Esses recursos estão disponíveis antes de um lançamento oficial para que você possa obter acesso antecipado e fornecer feedback.

Se você estiver criando um agente pronto para produção, consulte Visão geral do Microsoft Copilot Studio.

A janela de ligação de confiança pode enviar um resultado de conclusão para a página do chat com window.opener.postMessage. Use a origem exata da página de chat como origem de destino, não *.

Na página de chat:

  1. Se window.open devolver null, não aceite uma mensagem para essa tentativa. Caso contrário, aceite uma mensagem apenas quando event.source corresponder à referência do popup retida e event.origin corresponder à origem esperada.

  2. Valide que os dados da mensagem contêm type: "postback" e têm um valor na forma esperada pelo seu agente ou runtime.

    O exemplo seguinte envia uma mensagem com texto "hello-world" ao agente. Não é visível na interface do chat.

    { "type": "postback", "value": { hello: "World!" } }
    

    O exemplo seguinte envia uma mensagem em JSON { hello: "World!" } ao agente.

    { "type": "postback", "value": { hello: "World!" } }
    
  3. Envie o valor aceite através do mecanismo de postback do Bot Framework. Use o ID de atividade retida como replyToId; não aceite um ID de atividade de resposta no popup.

  4. Aceite no máximo um resultado para cada popup. Remova o ouvinte de eventos e limpe o seu temporizador após aceitar um resultado, rejeitar uma mensagem mal formada do popup confiável, detetar que o popup fechou ou atingir o limite de tempo. O Webchat utiliza um limite de cinco minutos.

  5. Coordena com o agente ou runtime para correlacionar o postback com a interação original que exigia conexão e retoma esse turno exatamente uma vez.

As mensagens no navegador são efetuadas na medida do possível. Bloqueadores de popups, navegação, política de opener de origem cruzada ou uma janela fechada podem impedir a continuação automática. Mantenha o Continue ou outro caminho de recuperação disponível, e não interprete uma mensagem em falta como sucesso.

Implante sua tela personalizada

Para hospedar sua tela personalizada, implante todos os arquivos em um aplicativo Web.