如果您希望进行任何类型的网络聊天自定义,那么我强烈建议您不要使用网络聊天频道 <iframe> 选项。如果您需要一个简单的插件组件,这很有用,但它提供的自定义选项数量远不及BotFramework-WebChat 提供的数量。
如果您将考虑使用基于 v4 react 的网络聊天产品(在上面的链接中引用),那么以下示例将为您提供您正在寻找的功能。
请注意,为简单起见,我将会话 ID 保存在会话存储中。
另外,我通过对本地运行的直线端点进行 API 调用来生成令牌。我在最后包含了代码来做同样的事情。您可以在 html 文件中针对 directline/tokens/generate 端点传递您的直接线路密码,但出于安全原因,强烈建议不要这样做。
最后,createDirectLine() 方法中使用的watermark 属性指定要显示的过去活动的数量(消息、卡片等)。
<!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>
这是生成令牌的代码。我将此附加到我的机器人中的 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');
}
});
});
希望有帮助!
重新更新 - 2021 年 8 月 6 日
从技术上讲,上面 HTML 中的脚本可以正常工作,尽管它的实现不是很清楚。我提供了这个简化代码的 sn-p。
另外,请注意下面的第一行:CDN 此后略有变化。当前的稳定版本来自latest,而不是master。
<script src="https://cdn.botframework.com/botframework-webchat/latest/webchat.js"></script>
<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>