您可以通过设置“令牌”服务器来实现此目的。在下面的示例中,我在开发/测试我的机器人时在本地运行它。
你可以使用任何你想要的包,但是我选择了“restify”,因为我将它包含在我的机器人的index.js 文件中。我只需创建一个新服务器,与机器人服务器分开,并为其分配一个自己的端口。然后,当我运行机器人时,它也会自动运行。将您的 appIds、appPasswords 和 secrets 放入 .env 文件中。
然后,在托管机器人的网页中,只需调用端点来获取令牌。您还会注意到代码会检查令牌是否已存在。如果是这样,那么它会设置一个带有计时器的间隔来刷新令牌。间隔时间为 1500000 毫秒,设置为在令牌过期之前运行(1800000 毫秒)。因此,令牌总是被刷新。 (只是突然出现在我的脑海中:如果用户导航离开,记录剩余时间和经过的时间量可能很聪明,以便将间隔设置为准确的数字,以便它在应该时刷新。否则,间隔将重置到期时间要少得多。)
另外,我包含了一些注释掉的代码。这是如果您希望您的对话在页面刷新或用户导航离开并返回之后持续存在。这样,当前的对话就不会丢失,并且令牌仍然有效。根据您的需要,可能不是必需的,但适用于上述情况。
希望有帮助!
令牌服务器
/**
* Creates token server
*/
const path = require('path');
const restify = require('restify');
const request = require('request');
const bodyParser = require('body-parser');
const ENV_FILE = path.join(__dirname, '.env');
require('dotenv').config({ path: ENV_FILE });
const corsToken = corsMiddleware({
origins: [ '*' ]
});
// Create HTTP server.
let server = restify.createServer();
server.pre(cors.preflight);
server.use(cors.actual);
server.use(bodyParser.json({
extended: false
}));
server.listen(process.env.port || process.env.PORT || 3500, function() {
console.log(`\n${ server.name } listening to ${ server.url }.`);
});
// Listen for incoming requests.
server.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) => {
// response.statusCode = 400;
if (!error && response.statusCode < 300) {
res.send(body);
console.log('Someone requested a token...');
} else if (response.statusCode === 400) {
res.send(400);
} else {
res.status(500);
res.send('Call to retrieve token from DirectLine failed');
}
});
});
// Listen for incoming requests.
server.post('/directline/refresh', (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/refresh',
headers: {
'Authorization': `Bearer ${ req.body.token }`,
'Content-Type': 'application/json'
},
json: {
user: {
ID: userId
}
}
};
request.post(options, (error, response, body) => {
if (!error && response.statusCode < 300) {
res.send(body);
console.log('Someone refreshed a token...');
} else {
res.status(500);
res.send('Call to retrieve token from DirectLine failed');
}
});
});
webchat.html
<script>
(async function () {
let { token, conversationId } = sessionStorage;
[...]
if ( !token || errorCode === "TokenExpired" ) {
let res = await fetch( 'http://localhost:3500/directline/token', { method: 'POST' } );
const { token: directLineToken, conversationId, error } = await res.json();
// sessionStorage[ 'token' ] = directLineToken;
// sessionStorage[ 'conversationId' ] = conversationId;
token = directLineToken;
}
if (token) {
await setInterval(async () => {
let res = await fetch( 'http://localhost:3500/directline/refresh', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify( { token: token } )
} );
const { token: directLineToken, conversationId } = await res.json();
// sessionStorage[ 'token' ] = directLineToken;
// sessionStorage[ 'conversationId' ] = conversationId;
token = directLineToken;
}, 1500000)
}
// if ( conversationId ) {
// let res = await fetch( `https://webchat.botframework.com/v3/directline/conversations/${ conversationId }`, {
// method: 'GET',
// headers: {
// 'Authorization': `Bearer ${ token }`,
// 'Content-Type': 'application/json'
// },
// } );
// const { conversationId: conversation_Id, error } = await res.json();
// if(error) {
// console.log(error.code)
// errorCode = error.code;
// }
// conversationId = conversation_Id;
// }
[...]
window.ReactDOM.render(
<ReactWebChat
directLine={ window.WebChat.createDirectLine({ token });
/>
),
document.getElementById( 'webchat' );
});
</script>