Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[dialogflow_intent_client] The package for access to dialogflow intent settings #399

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions dialogflow_task_executive/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,19 @@ find_package(catkin REQUIRED COMPONENTS
add_message_files(
FILES
DialogResponse.msg
IntentInfo.msg
)

add_action_files(
FILES
DialogText.action
RegisterIntent.action
ListIntent.action
)

generate_messages(
DEPENDENCIES
std_msgs
actionlib_msgs
)

Expand Down
35 changes: 35 additions & 0 deletions dialogflow_task_executive/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ Please read [app_manager](https://github.com/PR2/app_manager/) for more detailed

## Create new Intent in Dialogflow

### Web console

For your new task, create new Intent as below.

`Action` section, you can set full name (`<package name>/<app name>`), app name or camel-cased name of your `app_manager` app.
Expand All @@ -78,6 +80,39 @@ If your app is registered as `your_package/your_demo`, you need to set `your_pac

In order to fulfill other forms, please read [dialogflow doc](https://dialogflow.com/docs/intents) for more detailed information abount Intent.

### ROS node using API

You can add new intent with actionlib. First, you launch

```shell
roslaunch dialogflow_task_executive dialogflow_intent_client.launch credential:=<YOUR GOOGLE CLOUD JSON KEY>
```
or make `launch_intent_client` arg true in `dialogflow_ros.launch` .

To check registered intent, call the action `~list_intent_action` .

To register the intent, call the action `~register_intent_action` . For example, if you want to add the intent, named `hello`, invoked with the word `hi`, you call the action on shell like

```shell
rostopic pub /dialogflow_intent_client/register_intent_action/goal dialogflow_task_executive/RegisterIntentActionGoal "header:
seq: 0
stamp:
secs: 0
nsecs: 0
frame_id: ''
goal_id:
stamp:
secs: 0
nsecs: 0
id: ''
goal:
intent:
intent: 'hello'
concat_training_phrases:
- ''
message_texts:
- 'hi'"
```

## Usage

Expand Down
6 changes: 6 additions & 0 deletions dialogflow_task_executive/action/ListIntent.action
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
std_msgs/Empty request
---
dialogflow_task_executive/IntentInfo[] intents
bool done
---
string status
5 changes: 5 additions & 0 deletions dialogflow_task_executive/action/RegisterIntent.action
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
dialogflow_task_executive/IntentInfo intent
---
bool done
---
string status
11 changes: 11 additions & 0 deletions dialogflow_task_executive/launch/dialogflow_intent_client.launch
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<launch>
<arg name="credential" />
<node name="dialogflow_intent_client"
pkg="dialogflow_task_executive" type="dialogflow_intent_node.py"
output="screen">
<rosparam subst_value="true">
google_cloud_credentials_json: $(arg credential)
</rosparam>
</node>
</launch>
7 changes: 7 additions & 0 deletions dialogflow_task_executive/launch/dialogflow_ros.launch
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
<arg name="override_project_id" default="false" doc="Specify true if the project_id argument takes priority over the project_id section of the credential file." />
<arg name="enable_hotword" default="true" />
<arg name="always_publish_result" default="false" doc="Always publish dialog_response topic even the node gets actionlib request." />
<arg name="launch_intent_client" default="false" />

<node name="dialogflow_client"
pkg="dialogflow_task_executive" type="dialogflow_client.py"
Expand All @@ -30,4 +31,10 @@
file="$(find dialogflow_task_executive)/config/dialogflow_hotword.yaml"/>
</node>

<group if="$(arg launch_intent_client)">
<include file="$(find dialogflow_task_executive)/launch/dialogflow_intent_client.launch">
<arg name="credential" value="$(arg credential)" />
</include>
</group>

</launch>
3 changes: 3 additions & 0 deletions dialogflow_task_executive/msg/IntentInfo.msg
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
string intent
string[] concat_training_phrases
string[] message_texts
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ def make_dialog_msg(self, result):
# check if ROS_PYTHON_VERSION exists in indigo
if (self.language == 'ja-JP'
and ("ROS_PYTHON_VERSION" not in os.environ
or os.environ["ROS_PYTHON_VERSION"] == "2")):
or sys.version_info.major <= 2)):
msg.query = result.query_text.encode("utf-8")
msg.response = result.fulfillment_text.encode("utf-8")
else:
Expand Down
110 changes: 110 additions & 0 deletions dialogflow_task_executive/node_scripts/dialogflow_intent_node.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
#!/usr/bin/env python

import actionlib
from dialogflow_task_executive.msg import RegisterIntentAction, RegisterIntentGoal, RegisterIntentResult, RegisterIntentFeedback
from dialogflow_task_executive.msg import ListIntentAction, ListIntentGoal, ListIntentResult, ListIntentFeedback
from dialogflow_task_executive.msg import IntentInfo
import google.cloud.dialogflow as df
from google.oauth2.service_account import Credentials
import rospy

class DialogflowIntentClient(object):
def __init__(self):
credentials_json = rospy.get_param(
'~google_cloud_credentials_json', None)
credentials = Credentials.from_service_account_file(credentials_json)
self.intents_client = df.IntentsClient(credentials=credentials)
self.project_id = credentials.project_id
self._intent_create_as = actionlib.SimpleActionServer("~register_intent_action",
RegisterIntentAction,
execute_cb=self.register_cb,
auto_start=False)
self._intent_list_as = actionlib.SimpleActionServer("~list_intent_action",
ListIntentAction,
execute_cb=self.list_cb,
auto_start=False)
self._intent_create_as.start()
self._intent_list_as.start()

def register_df_intent(self, intent_name, training_phrases, message_texts):
parent = df.AgentsClient.agent_path(self.project_id)
phrases = []
for phrase in training_phrases:
part = df.Intent.TrainingPhrase.Part(text=phrase)
training_phrase = df.Intent.TrainingPhrase(parts=[part])
phrases.append(training_phrase)
text = df.Intent.Message.Text(text=message_texts)
message = df.Intent.Message(text=text)
intent = df.Intent(
display_name=intent_name, training_phrases=phrases, messages=[message])
response = self.intents_client.create_intent(
request={"parent": parent, "intent": intent}
)
return response

def list_df_intent(self):
parent = df.AgentsClient.agent_path(self.project_id)
req = df.ListIntentsRequest(parent=parent,
intent_view=df.IntentView.INTENT_VIEW_FULL)
intents = self.intents_client.list_intents(request=req)
msgs = []
for intent in intents:
msg = IntentInfo()
msg.intent = intent.display_name
for training_phrase in intent.training_phrases: # training phrases
phrase = ""
for part in training_phrase.parts:
phrase += str(part.text)
msg.concat_training_phrases.append(str(phrase))
for message in intent.messages:
msg.message_texts.append(str(message.text))
msgs.append(msg)
return msgs

def register_cb(self, goal):
feedback = RegisterIntentFeedback()
result = RegisterIntentResult()
success = False
try:
res = self.register_df_intent(goal.intent.intent,
goal.intent.concat_training_phrases,
goal.intent.message_texts)
feedback.status = str(res)
success = True
rospy.loginfo("Succeeded in registering the intent: {}".format(goal.intent.intent))
except Exception as e:
rospy.logerr(str(e))
feedback.status = str(e)
success = False
finally:
self._intent_create_as.publish_feedback(feedback)
result.done = success
self._intent_create_as.set_succeeded(result)

def list_cb(self, goal):
feedback = ListIntentFeedback()
result = ListIntentResult()
success = False
try:
msgs = self.list_df_intent()
intents_info = ""
for msg in msgs:
result.intents.append(msg)
intents_info += "{}, ".format(msg.intent)
success = True
rospy.loginfo("Listed intents: {}".format(intents_info))
# from IPython.terminal import embed; ipshell=embed.InteractiveShellEmbed(config=embed.load_default_config())(local_ns=locals())
except Exception as e:
rospy.logerr(str(e))
feedback.status = str(e)
success = False
finally:
self._intent_list_as.publish_feedback(feedback)
result.done = success
self._intent_list_as.set_succeeded(result)


if __name__ == "__main__":
rospy.init_node("dialogflow_intent_manager")
node = DialogflowIntentClient()
rospy.spin()
2 changes: 2 additions & 0 deletions dialogflow_task_executive/requirements.in
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
dialogflow==1.1.1
google-auth==2.9.0
google-cloud-dialogflow==2.14.1
2 changes: 2 additions & 0 deletions dialogflow_task_executive/requirements.in.noetic
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@ grpcio-status==1.48.1
googleapis-common-protos[grpc]==1.56.2
protobuf==3.20.1 # fix Could not find a version that matches protobuf<4.0.0dev,<5.0.0dev,>=3.15.0,>=3.20.1,>=4.21.3 (from google-api-core[grpc]==1.33.1->dialogflow==1.1.1->-r requirements.in (line 1))
grpcio==1.54.0 # via google-api-core, googleapis-common-protos, grpcio-status
google-auth==2.9.0
google-cloud-dialogflow==2.14.1
8 changes: 3 additions & 5 deletions google_chat_ros/scripts/google_chat_ros_node.py
Original file line number Diff line number Diff line change
Expand Up @@ -222,13 +222,11 @@ def event_cb(self, event, publish_topic=True):
action = event.get('action')
msg.action.action_method_name = action.get('actionMethodName')
if action.get('parameters'):
parameters = []
for param in action.get('parameters'):
action_parameter = ActionParameter()
action_parameter.key = param.get('key')
action_parameter.value = param.get('value')
parameters.append(action_parameter)
msg.action.parameters = parameters
action_parameter.key = param.get("key") if param.get("key") else ""
action_parameter.value = param.get("value") if param.get("value") else ""
msg.action.parameters.append(action_parameter)
if publish_topic:
self._card_activity_pub.publish(msg)
return msg
Expand Down
2 changes: 1 addition & 1 deletion google_chat_ros/src/google_chat_ros/google_chat.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ def _pubsub_cb(self, message):
except Exception as e:
rospy.logerr("Failed to handle the request from Cloud PubSub.")
rospy.logerr("It might be caused because of invalid type message from GCP")
rospy.logerr("{}".str(e))
rospy.logerr(e)
finally:
message.ack()

Expand Down
Loading