I am passing getResponse() function in the useEffect with userInput as dependency array. Everytime a user sends input this function is triggered and I get new directline object created everytime. Problem I am facing is that I am creating bot everytime I send a request to bot. How can I create an object only once on initial render and then use the object to connect with bot.
Please help!
Here's the botframework documentation I am following
Here's the code I wrote to communicate with bot in ReactJS.
import React, { useEffect, useState } from "react";
import "./App.css"
import { DirectLine } from "botframework-directlinejs";
import { browserName, browserVersion, osName } from "react-device-detect";
import { ConnectionStatus } from 'botframework-directlinejs';
import Header from "./Components/Header";
import MainBody from "./Components/MainBody";
import BottomWrapper from "./Components/BottomWrapper";
function App() {
useEffect(() => {
const userIpDetails = fetchIp();
setUserIp(userIpDetails);
}, []);
// to fetch user IP
const fetchIp = async () => {
const response = await fetch("https://api.ipify.org/?format=json");
const ip = await response.json();
const userIP = ip.ip;
return userIP;
};
const [loaded, setLoaded] = useState(false);
const [message, setMessage] = useState("");
const [userInput, setUserInput] = useState([]);
const [messages, setMessages] = useState([]);
const [userIp, setUserIp] = useState("");
var client;
useEffect(() => {
setLoaded(true);
getResponse();
}, [userInput]);
// to get DirectLine Streaming Token
const getDirectLineStreamingToken = async function () {
const res = await fetch(
https://directline.botframework.com/v3/directline/tokens/generate,
{
method: "POST",
headers: {
Authorization:
`Bearer TOKEN`,
},
}
);
const { token } = await res.json();
return token;
};
// send request via message box
const sendRequest = () => {
console.log("request sent");
client
?.postActivity({
from: {
id: "my_id",
name: "Software Company",
avatarUrl:
"https://demos.telerik.com/kendo-ui/content/chat/VacationBot.png",
},
type: "message",
text: message,
channelData: {
iP: userIp,
platform: `${osName}`,
Browser: `${browserName} ${browserVersion}`,
},
})
?.subscribe(
(id) => console.log("Posted activity, assigned ID ", id),
(error) => console.log("Error posting activity", error)
);
};
// receive response from server
const getResponse = function () {
getDirectLineStreamingToken().then(function (token) {
client = new DirectLine({
domain: "https://directline.botframework.com/v3/directline",
token: token,
});
client.activity$.subscribe((activity) => {
onResponse(activity);
});
client.connectionStatus$
.subscribe(connectionStatus => {
switch(connectionStatus) {
case ConnectionStatus.Uninitialized: // the status when the DirectLine object is first created/constructed
case ConnectionStatus.Connecting: // currently trying to connect to the conversation
case ConnectionStatus.Online: // successfully connected to the converstaion. Connection is healthy so far as we know.
case ConnectionStatus.ExpiredToken: // last operation errored out with an expired token. Your app should supply a new one.
case ConnectionStatus.FailedToConnect: // the initial attempt to connect to the conversation failed. No recovery possible.
case ConnectionStatus.Ended: // the bot ended the conversation
}
console.log("connection status ", connectionStatus)
});
})
.catch((e) => console.log("bot error", e));;
};
// handle response received from server
const onResponse = function (activity) {
console.log("activity is ", activity);
let receivedResponse = activity.text;
if (activity.inputHint === "acceptingInput") {
setMessages([
...messages,
{ messageKey: receivedResponse, isbotmessage: true },
]);
}
};
const handleChange = function (event) {
setMessage(event.target.value);
console.log(event.target.value);
};
const handleKeyPress = function (event) {
if (event.key === "Enter") {
sendRequest();
setMessages([...messages, { messageKey: message, isbotmessage: false }]);
setUserInput([
...messages,
{ messageKey: userInput, isbotmessage: false },
]);
}
};
const handleClick = function (event) {
sendRequest();
setMessages([...messages, { messageKey: message, isbotmessage: false }]);
setUserInput([...messages, { messageKey: userInput, isbotmessage: false }]);
};
return loaded ? (
<div className="App">
<div className="chat-window">
<Header />
<MainBody messages={messages}/>
<BottomWrapper message={message} handleChange={handleChange} handleKeyPress={handleKeyPress} handleClick={handleClick}/>
</div>
</div>
) : (
<p>Loading...</p>
);
}
export default App;