YARP
Yet Another Robot Platform
 
Loading...
Searching...
No Matches
GoogleDialogFlowCxChatBot.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2023 Istituto Italiano di Tecnologia (IIT)
3 * SPDX-License-Identifier: BSD-3-Clause
4 */
5
6#ifndef _USE_MATH_DEFINES
7#define _USE_MATH_DEFINES
8#endif
9
11
12#include <yarp/sig/SoundFile.h>
13
15#include <yarp/os/LogStream.h>
16#include <fstream>
17
18#include <thread>
19#include <chrono>
20
21#include <cmath>
22
23using namespace yarp::os;
24using namespace yarp::dev;
25using namespace std::chrono_literals;
26
27namespace dialogFlow_cx_v3 = ::google::cloud::dialogflow::cx::v3;
28
30
31std::string GoogleDialogFlowCxChatBot::_getRandSession_() {
32 std::string session;
33 srand(time(NULL));
34 for(int i = 0; i<16; i++) {
35 session += std::to_string(rand() % 10);
36 }
37 return session;
38}
39
41{
42 yCDebug(GOOGLEDIALOGFLOWCXBOT) << "Configuration: \n" << config.toString().c_str();
43
44 parseParams(config);
45
46#ifdef USE_DISPLAY_NAME
47 if(!config.check("display_name"))
48 {
49 yCError(GOOGLEDIALOGFLOWCXBOT) << "display_name parameter must be specified";
50 return false;
51 }
52
53 std::string displayName = config.find("display_name").asString();
54
55 google::cloud::dialogflow_cx::AgentsClient agentsClient(google::cloud::dialogflow_cx::MakeAgentsConnection(m_location));
56
57 dialogFlow_cx_v3::ListAgentsRequest request;
58
59 std::string parent = "projects/"+m_project;
60 request.set_parent(parent);
61
62 double oldTime = yarp::os::Time::now();
63 yCWarning(GOOGLEDIALOGFLOWCXBOT) << "Time" << oldTime;
64 //auto agentsList = agentsClient.ListAgents(parent);
65 google::cloud::Options opt;
66 auto agentsList = agentsClient.ListAgents(request,opt);
67 yCWarning(GOOGLEDIALOGFLOWCXBOT) << "Time" << yarp::os::Time::now() - oldTime;
68
69 for (const auto& agent : agentsList) {
70 std::this_thread::sleep_for(30s);
71 if (agent->display_name() == displayName) {
72 m_agentId = agent->name();
73 break;
74 }
75 }
76#else
77 m_agentId = "projects/" + m_project + "/locations/" + m_location + "/agents/" + m_agent_name;
78#endif
79 m_sessionId = m_agentId + "/sessions/" + _getRandSession_();
80 m_channel = grpc::CreateChannel("dialogflow.googleapis.com", grpc::GoogleDefaultCredentials());
81 m_sessionStub = dialogFlow_cx_v3::Sessions::NewStub(m_channel);
82
83 // Get the currently active agent page
84 std::string message{"*"};
85 std::string resp;
86 bool isItATest = (m_agent_name == "test_agent") && (m_project == "test_project");
87 if(!interact(message,resp) && !isItATest)
88 {
89 yCError(GOOGLEDIALOGFLOWCXBOT) << "Could not retrieve the current chatbot status";
90
91 return false;
92 }
93
94 return true;
95}
96
98{
99 return true;
100}
101
102yarp::dev::ReturnValue GoogleDialogFlowCxChatBot::interact(const std::string& messageIn, std::string& messageOut)
103{
104 dialogFlow_cx_v3::DetectIntentRequest req;
105
106 // Create a query input
107 dialogFlow_cx_v3::QueryInput query_input;
108 auto parameters = query_input.mutable_language_code();
109 *parameters = m_language_code;
110 dialogFlow_cx_v3::TextInput* text_input = query_input.mutable_text();
111 text_input->set_text(messageIn);
112
113 // Create a DetectIntent request
114 dialogFlow_cx_v3::DetectIntentRequest detect_intent_request;
115 detect_intent_request.set_session(m_sessionId);
116 *detect_intent_request.mutable_query_input() = query_input;
117
118 // Send the request to Dialogflow CX
119 grpc::ClientContext context;
120 dialogFlow_cx_v3::DetectIntentResponse response;
121
122 grpc::Status status = m_sessionStub->DetectIntent(&context, detect_intent_request, &response);
123
124 // Handle the response
125 if (status.ok()) {
126 if (response.has_query_result()) {
127 m_currentPage = response.query_result().current_page().display_name();
128 const dialogFlow_cx_v3::QueryResult& query_result = response.query_result();
129 if(query_result.response_messages_size() <= 0)
130 {
131 yCDebug(GOOGLEDIALOGFLOWCXBOT) << "An empty fulfillment was returned. Check the chatbot structure for safety";
132 messageOut = "";
133 return ReturnValue_ok;
134 }
135 messageOut = query_result.response_messages().Get(0).text().text().Get(0);
136 } else {
137 yCError(GOOGLEDIALOGFLOWCXBOT) << "No query result in the response.";
138
140 }
141 } else {
142 yCError(GOOGLEDIALOGFLOWCXBOT) << "Failed to detect intent. Error: " << status.error_message();
144 }
145
146 return ReturnValue_ok;
147}
148
150{
151 m_language_code = language;
152 return ReturnValue_ok;
153}
154
156{
157 language = m_language_code;
158 return ReturnValue_ok;
159}
160
162{
163 status = m_currentPage;
164
165 return ReturnValue_ok;
166}
167
169{
170 m_sessionId = m_agentId + "/sessions/" + _getRandSession_();
171 return ReturnValue_ok;
172}
const yarp::os::LogComponent & GOOGLEDIALOGFLOWCXBOT()
#define ReturnValue_ok
Definition ReturnValue.h:77
bool parseParams(const yarp::os::Searchable &config) override
Parse the DeviceDriver parameters.
bool open(yarp::os::Searchable &config) override
Open the DeviceDriver.
yarp::dev::ReturnValue interact(const std::string &messageIn, std::string &messageOut) override
Sends a message to the chatbot.
yarp::dev::ReturnValue getLanguage(std::string &language) override
Gets the current chatbot language.
yarp::dev::ReturnValue getStatus(std::string &status) override
Gets the current status of the bot.
yarp::dev::ReturnValue resetBot() override
Resets the chatbot.
bool close() override
Close the DeviceDriver.
yarp::dev::ReturnValue setLanguage(const std::string &language) override
Sets the chat bot language.
@ return_value_error_generic
Method was successfully executed.
A mini-server for performing network communication in the background.
@ TraceType
Definition Log.h:92
A base class for nested structures that can be searched.
Definition Searchable.h:31
virtual bool check(const std::string &key) const =0
Check if there exists a property of the given name.
virtual std::string toString() const =0
Return a standard text representation of the content of the object.
virtual Value & find(const std::string &key) const =0
Gets a value corresponding to a given keyword.
#define yCError(component,...)
#define yCWarning(component,...)
#define yCDebug(component,...)
#define YARP_LOG_COMPONENT(name,...)
For streams capable of holding different kinds of content, check what they actually have.
double now()
Return the current time in seconds, relative to an arbitrary starting point.
Definition Time.cpp:121
An interface to the operating system, including Port based communication.