可以将代理配置为开始与用户对话。 您还可以将自定义问候语与自定义代理外观结合起来。
Important
让智能体启动对话将在分析中显示该对话,并增加会话计数。
如果代理的用户没有与代理互动(例如,他们加载了页面但没有向代理提出任何问题),会话就会标记为未互动会话。 此行为可能会影响分析。
- 网络应用
- Teams
默认情况下,使用 Copilot Studio 创建并发布到网站的智能体加载时无问候,会被动等待用户开始对话。
不过,您可以使用自定义 CSS 和 JavaScript 代码,让智能体在加载时自动开始对话。 例如,您可以让代理在加载后立即说“您好,我是虚拟代理 Botty”。
首先,您需要部署一个自定义区域,其中包含用于触发问候的变量。 默认情况下,自定义画布会调用预定义的问候主题。 但是,您可以创建一个新主题用作问候语。 您将默认的问候主题重定向到此新主题。
Important
可以安装和使用本文中包含的示例代码,仅用于 Copilot Studio。 此示例代码“按原样”许可,所有服务级别协议或支持服务中均已排除。 使用本文档时的风险自负。
Microsoft 不提供任何明示担保、保证或条件,并且不提供任何默示担保,包括适销性、特定用途适用性以及不侵犯他人权利的默示担保。
自定义默认画布
使用一些简单的 CSS 和 JavaScript 样式选项配置聊天区域的外观。
首先,需要配置要部署机器人区域的位置。
复制以下 HTML 代码并将其保存到名为
index.html的文件。 或者,将代码复制并粘贴到w3schools.com 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>在
index.html中,在第const tokenEndpoint = "<YOUR TOKEN ENDPOINT>";行,用您的智能体的令牌端点替换占位符。使用新式浏览器(例如,Microsoft Edge)打开
index.html,以在自定义画布中打开代理。测试代理,以确保收到来自它的响应,并且它正常工作。
如果遇到问题,请确保已发布智能体,并且令牌终结点位于正确的位置。 标记终结点应该位于行
const tokenEndpoint = "<YOUR TOKEN ENDPOINT>";中的等号 (=) 后,并且两侧有双引号 (")。
检索智能体的令牌终结点
无论您使用的是默认画布还是连接的自定义画布,都需要智能体的令牌端点。
在导航菜单中的设置下面,选择渠道。
选择电子邮件。 此时会显示此通道的配置面板。
在令牌终结点旁边,选择复制。
更改代理的默认问候语
文件 index.html 中的代码会导致在加载代理时自动调用某个主题。 默认情况下,该代码调用问候主题。 还可以创建新主题并将默认问候主题转移到该新主题。
在这两种情况下,都可以更改要正常调用的主题。
如果您修改了问候主题或创建了新的主题,您应明确告知用户正在与智能体(或“虚拟智能体”)进行对话。 此类指示可帮助用户了解自己是在与机器而非人类交谈。
我们建议您修改预设的问候主题,这样您无需编辑 index.html 代码。
修改预定义问候语主题(建议)
现在,您可以访问部署代理自定义画布的网页来测试代理。 您将看到机器人通过自动显示问候主题来启动对话。
创建新的自定义主题
转到智能体的主题页面。
选择“从空白>”。
输入新主题的名称。
添加消息节点并配置所需消息。
编辑完成后选择保存。
再次进入主题页面,选择问候主题。
从 Greeting 主题中删除所有消息节点。
要自动将智能体转至新主题,添加重定向节点,并将新主题设为目标。
选择保存,并发布您的智能体。
现在,您可以访问部署代理自定义画布的网页来测试代理。 您可以看到代理通过自动显示新主题开始对话。