Вот так у меня есть похожая настройка проекта, которая работает довольно хорошо.
Сначала добавьте конечную точку, генерирующую токен, в файл index.js бота. Следующий код может быть добавлен непосредственно в конец файла или вы можете организовать по своему усмотрению. Пока ваш бот работает, эта конечная точка также будет доступна.
Вы можете , конечно, настроить конечную точку в другом месте. Это буквально может быть где угодно. Первоначально у меня было нижеприведенное в отдельном проекте, сначала в Azure, затем локально работавшем параллельно с моим проектом React, но я понял, что могу просто запустить его в боте. Важной частью является получение токена (см. Далее ниже).
В этом случае у меня есть секрет прямой линии (process.env.directLineSecret
) в файле .env. Я также запускаю его на порт 3500 (FYI).
/**
* Creates token server
*/
const bodyParser = require('body-parser');
const request = require('request');
const corsMiddleware = require('restify-cors-middleware');
const cors = corsMiddleware({
origins: ['*']
});
// Create HTTP tokenServer.
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');
}
});
});
Далее создайте компонент веб-чата. Здесь вы позвоните, чтобы получить токен. Обязательно используйте ту же конечную точку / порт, который вы указали в файле index.js вашего бота (или любую конечную точку, которую вы создали). Токен будет сгенерирован со страницей через componentDidMount()
. Настройки соединения directLine
будут сохранены в состояние и впоследствии будут доступны после начала сеанса веб-чата методом render()
.
import React from 'react';
import ReactWebChat, { createDirectLine } from 'botframework-webchat';
export default class WebChat extends React.Component {
constructor(props) {
super(props);
componentDidMount() {
this.fetchToken();
}
async fetchToken() {
const res = await fetch( 'http://localhost:3500/directline/token', { method: 'POST' } );
const { token } = await res.json();
this.setState(() => ({
directLine: createDirectLine({ token })
}));
}
render() {
return (
this.state.directLine ?
<ReactWebChat
directLine={ this.state.directLine }
styleSet={ this.state.styleSet }
tableIndex="-1"
{ ...this.props }
>
</ReactWebChat>
:
<div>Connecting to bot…</div>
)
}
}
Наконец, у меня есть бот, встроенный в отдельный компонент. Я делаю некоторые другие вещи, которые я вырезал из этого кода, так что вы, вероятно, можете передать WebChat
непосредственно в ваш класс приложения или куда бы вы его ни внедрили.
import React, { Component } from 'react';
import WebChat from './webchat';
class WebChatView extends Component {
render() {
return (
<div>
<WebChat id="webchat" role="main" />
</div>
)
}
}
Я взломал это, чтобы упростить для вас. Если что-то не работает, дайте мне знать, и я вернусь к этому. В противном случае, вам должно быть хорошо идти.
Надежда на помощь!