다음을 통해 공유


라이브 또는 데모 웹 사이트에 에이전트 게시

에이전트를 웹에 게시할 때 사전 구축된 데모 웹 사이트에 게시할 수 있습니다(이 데모 웹 사이트를 사용하여 팀원 및 이해 관계자와 에이전트를 공유할 수 있습니다). 자신의 라이브 웹 사이트에 게시할 수도 있습니다.

데모 웹 사이트는 언제 사용해야 하며, 내 웹 사이트는 언제 사용해야 합니까?
데모 웹 사이트를 사용하여 에이전트를 시험해보고 에이전트를 시험해 보기를 윈하는 팀원이나 다른 이해 관계자와 공유해야 합니다. 예를 들어, 프로덕션 용도로는 사용되지 않으며 고객과 직접 사용해서는 안됩니다.
고객과 상호 작용할 수 있는 도움말 웹 페이지의 도움말 에이전트와 같은 프로덕션 시나리오를 위해 실제 웹 사이트에서 에이전트를 게시하고 사용해야 합니다.

중요

이 문서는 Microsoft Copilot Studio 프리뷰 설명서를 포함하며 변경될 수 있습니다.

프리뷰 기능은 생산용으로 만들어진 것이 아니므로 기능이 제한될 수 있습니다. 이러한 기능은 공식 릴리스 이전에 제공되므로 사용자가 조기에 액세스하고 피드백을 제공할 수 있습니다.

프로덕션이 가능한 에이전트를 빌드하는 경우 Microsoft Copilot Studio 개요를 참조하세요.

미리 빌드된 데모 웹사이트는 에이전트를 게시할 때 자동으로 생성됩니다. 팀원과 이해 관계자는 데모 웹 사이트를 사용하여 에이전트를 빌드하는 동안 사용해 볼 수 있습니다. 팀 동료의 테스트 노력을 안내하기 위해 데모 사이트를 사용자 지정할 수 있습니다. 고객이 사용할 준비가 되면 에이전트를 라이브 웹 사이트에 게시합니다.

언제 데모 웹 사이트를 사용해야 하고 언제 자체 웹 사이트를 사용해야 합니까?

데모 웹 사이트는 에이전트를 시험 사용하거나, 시험 사용에 관심 있는 팀원 및 이해 관계자와 공유하는 용도로만 사용해야 합니다. 실제 운영 환경에서의 사용은 허용되지 않습니다. 고객에게 URL을 제공해서는 안됩니다. 고객이 사용할 수 있도록 라이브 웹 사이트에 에이전트를 게시합니다.

데모 웹 사이트 사용자 지정

데모 웹 사이트의 환영 메시지와 트리거 문구를 원하는 만큼 편집할 수 있습니다. 환영 메시지는 테스트의 목적을 설명하고 팀원에게 에이전트에게 무엇을 물어봐야 하는지 알려줄 수 있습니다.

  1. 에이전트를 열고 상단 메뉴 표시줄에서 설정을 선택합니다.

  2. 측면 탐색 패널에서 보안을 선택합니다.

  3. 인증을 선택한 다음 인증 없음을 선택하고 저장을 선택합니다.

  4. 설정을 종료하고 상단 메뉴 표시줄에서 채널을 선택하세요.

  5. 채널에서 데모 웹 사이트를 선택합니다.

  6. 데모 웹 사이트 패널의 시작 메시지에서 팀원이 볼 메시지를 입력합니다.

  7. 대화 스타터 아래에 트리거 문구 목록을 입력합니다.

    트리거 문구는 특정 토픽을 시작하는 것이므로 팀원이 테스트하기를 원하는 주제에 대한 트리거 문구를 입력할 수 있습니다.

  8. 저장을 선택합니다.

  9. 데모 웹 사이트 URL을 복사하여 팀원들과 공유하세요.

웹 사이트에 에이전트 추가

에이전트가 고객을 맞이할 준비가 되면 웹사이트에 iframe 코드 조각으로 추가합니다. 라이브 웹 사이트는 SharePoint 사이트와 같이 외부 또는 내부일 수 있습니다. Power Platform 관리 센터에 에이전트를 추가할 수도 있습니다.

  1. 다음 HTML 코드를 복사하여 이름이 지정된 index.html파일에 저장합니다. 또는 코드를 복사하여 w3schools.com HTML try it 편집기에 붙여넣습니다.

    
    <!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>
    
    
  2. 에이전트의 토큰 엔드포인트를 검색합니다.

  3. index.htmlconst tokenEndpoint = "<YOUR TOKEN ENDPOINT>"; 줄에서 플자리 표시자를 에이전트의 토큰 엔드포인트로 바꿉니다.

  4. index.html 최신 브라우저(예: Microsoft Edge)를 사용하여 열어 사용자 지정 캔버스에서 에이전트를 엽니다.

  5. 에이전트를 테스트하여 응답이 수신되고 올바르게 작동하는지 확인합니다.

  6. 웹 개발자에게 코드 조각(index.html)을 제공하여 웹 사이트에 에이전트를 추가합니다.