cam*_*er_ 5 azure botframework
我试图在页面重新加载和导航到机器人链接到的网站上的其他页面期间保留用户与机器人的对话。
目前,这些操作会关闭机器人窗口并完全重新启动对话,从而再次触发机器人的欢迎消息。
按照文档中的说明将有问题的机器人嵌入到网页中: https: //learn.microsoft.com/bs-latn-ba/azure/bot-service/bot-service-channel-connect-webchat ?view= azure-bot-service-4.0
我读过其他文章,其中使用对话 ID 来维护页面加载之间的聊天历史记录,尽管这是针对 DirectLine 通道的。以及其他一些文章建议将对话保存在数据库中并将消息传递回聊天窗口。尽管这似乎不是最好的方法。
我尝试将对话 ID 传递到 iframe 中,但没有成功。有没有办法通过将对话 ID 传递到 iframe 来保持对话?
这是在 iframe 中显示聊天机器人的代码:
<iframe src='https://webchat.botframework.com/embed/THECHATBOT?s=YOUR_SECRET_HERE' style='min-width: 400px; width: 100%; min-height: 500px;'></iframe>
这是我尝试将对话 ID 作为参数传递:
<iframe src='https://webchat.botframework.com/embed/THECHATBOT?s=YOUR_SECRET_HERE&conversationId?=THE_CONVERSATIONID_VALUE' style='min-width: 400px; width: 100%; min-height: 500px;'></iframe>
我希望聊天窗口中填充用户之前进行的对话,我得到的是对话重置并且不保留任何历史记录。
如果您希望进行任何类型的网络聊天自定义,那么我强烈建议您不要使用网络聊天渠道<iframe>选项。如果您需要一个简单的插件组件,它会很有用,但它提供的自定义选项数量远不及BotFramework-WebChat提供的数量。
如果您考虑使用基于 v4 React 的 Web 聊天产品(在上面的链接中引用),那么以下示例将为您提供您正在寻求的功能。
请注意,为简单起见,我将对话 ID 保存在会话存储中。
此外,我还通过对本地运行的直接线路端点进行 API 调用来生成令牌。我在最后添加了执行相同操作的代码。您可以directline/tokens/generate针对html 文件中的端点传递直接线路机密,但出于安全原因,强烈建议不要这样做。
最后,watermarkcreateDirectLine() 方法中使用的属性指定要显示的过去活动的数量(消息、卡片等)。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>WebChat</title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
html,
body {
height: 100%;
width: 100%;
margin: 0;
}
#webchat {
height: 100%;
width: 40%;
}
#webchat>* {
height: 100%;
width: 100%;
}
</style>
</head>
<body>
<div id="webchat" role="main"></div>
<script type="text/javascript"
src="https://unpkg.com/markdown-it/dist/markdown-it.min.js"></script>
<script
src="https://cdn.botframework.com/botframework-webchat/master/webchat.js"></script>
<script>
( async function () {
let { token, conversationId } = sessionStorage;
if (!token) {
const res = await fetch( 'http://localhost:3500/directline/token', { method: 'POST' } );
const { token: directLineToken } = await res.json();
sessionStorage['token'] = directLineToken;
token = directLineToken;
}
if (conversationId) {
const res = await fetch(`https://directline.botframework.com/v3/directline/conversations/${ conversationId }`, {
method: 'GET',
headers: {
'Authorization': `Bearer ${ token }`,
},
});
let { conversationId } = await res.json();
sessionStorage['conversationId'] = conversationId;
}
const directLine = createDirectLine({
token,
webSockets: true,
watermark: 10
});
window.WebChat.renderWebChat( {
directLine: directLine,
}, document.getElementById( 'webchat' ) );
document.querySelector( '#webchat > *' ).focus();
} )().catch( err => console.error( err ) );
</script>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
这是生成令牌的代码。我将其附加到我的机器人中的 index.js 文件的末尾。您也可以将其作为单独的项目运行。
当我在本地运行我的机器人时,端点变得可用。如果您运行的是 C# 机器人,您应该能够执行类似的操作。这里使用的端口应该与上面directline/token调用中引用的端口相同。
是directLineSecret通过 .env 文件存储和访问的。
/**
* Creates token server
*/
const bodyParser = require('body-parser');
const request = require('request');
const corsMiddleware = require('restify-cors-middleware');
const cors = corsMiddleware({
origins: ['*']
});
// Create server.
let tokenServer = restify.createServer();
tokenServer.pre(cors.preflight);
tokenServer.use(cors.actual);
tokenServer.use(bodyParser.json({
extended: false
}));
tokenServer.dl_name = 'DirectLine';
tokenServer.listen(process.env.port || process.env.PORT || 3500, function() {
console.log(`\n${ tokenServer.dl_name } listening to ${ tokenServer.url }.`);
});
// Listen for incoming requests.
tokenServer.post('/directline/token', (req, res) => {
// userId must start with `dl_`
const userId = (req.body && req.body.id) ? req.body.id : `dl_${ Date.now() + Math.random().toString(36) }`;
const options = {
method: 'POST',
uri: 'https://directline.botframework.com/v3/directline/tokens/generate',
headers: {
'Authorization': `Bearer ${ process.env.directLineSecret }`
},
json: {
User: {
Id: userId
}
}
};
request.post(options, (error, response, body) => {
if (!error && response.statusCode < 300) {
res.send({
token: body.token
});
} else {
res.status(500);
res.send('Call to retrieve token from DirectLine failed');
}
});
});
Run Code Online (Sandbox Code Playgroud)
希望得到帮助!
重新更新 - 8/6/2021
上面 HTML 中的脚本从技术上来说是可以工作的,尽管它的实现并不是很清楚。我提供了这个简化代码的片段。
另请注意下面的第一行:此后 CDN 发生了轻微变化。当前的稳定版本来自latest,而不是master。
<script src="https://cdn.botframework.com/botframework-webchat/latest/webchat.js"></script>
Run Code Online (Sandbox Code Playgroud)
<script>
( async function () {
let { token, conversation_Id } = sessionStorage;
if ( !token ) {
const res = await fetch( 'http://localhost:3500/directline/conversations', { method: 'POST' } );
const { token: directLineToken, conversationId } = await res.json();
sessionStorage[ 'token' ] = directLineToken;
sessionStorage[ 'conversation_Id' ] = conversationId
token = directLineToken;
}
const directLine = createDirectLine( {
token
} );
window.WebChat.renderWebChat( {
directLine: directLine,
}, document.getElementById( 'webchat' ) );
document.querySelector( '#webchat > *' ).focus();
} )().catch( err => console.error( err ) );
</script>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3853 次 |
| 最近记录: |