-
Notifications
You must be signed in to change notification settings - Fork 28
samples: add sample code for updating AnswerRecord #906
Changes from all commits
577aa3d
3fca35c
8c65320
d609b6c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,78 @@ | ||
| /* | ||
| * Copyright 2022 Google LLC | ||
| * | ||
| * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| * you may not use this file except in compliance with the License. | ||
| * You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
|
|
||
| package com.example.dialogflow; | ||
|
|
||
| // [START dialogflow_update_answer_record] | ||
| import com.google.api.gax.rpc.ApiException; | ||
| import com.google.cloud.dialogflow.v2.AnswerFeedback; | ||
| import com.google.cloud.dialogflow.v2.AnswerRecord; | ||
| import com.google.cloud.dialogflow.v2.AnswerRecordName; | ||
| import com.google.cloud.dialogflow.v2.AnswerRecordsClient; | ||
| import com.google.cloud.dialogflow.v2.UpdateAnswerRecordRequest; | ||
| import com.google.protobuf.FieldMask; | ||
| import java.io.IOException; | ||
|
|
||
| public class AnswerRecordManagement { | ||
|
|
||
| public static void main(String[] args) throws IOException { | ||
| // TODO(developer): Replace these variables before running the sample. | ||
| String projectId = "my-project-id"; | ||
| String location = "my-location"; | ||
|
|
||
| // Set id of the answer record to be updated. | ||
| // Answer records are created when a suggestion for the human agent assistant is generated. | ||
| // See details about how to generate an answer record by getting article suggestion here: | ||
| // https://cloud.google.com/agent-assist/docs/article-suggestion. | ||
| String answerRecordId = "my-answer-record-id"; | ||
|
|
||
| // Set the value to be updated for answer_feedback.clicked field. | ||
| boolean isClicked = true; | ||
| updateAnswerRecord(projectId, location, answerRecordId, isClicked); | ||
| } | ||
|
|
||
| // Update whether the answer record was clicked. | ||
| public static void updateAnswerRecord( | ||
| String projectId, String location, String answerRecordId, boolean clicked) | ||
| throws ApiException, IOException { | ||
| // Initialize a client for managing AnswerRecords. This client only needs to be created | ||
| // once, and can be reused for multiple requests. | ||
| try (AnswerRecordsClient answerRecordsClient = AnswerRecordsClient.create()) { | ||
| AnswerRecordName answerRecordName = | ||
| AnswerRecordName.ofProjectLocationAnswerRecordName(projectId, location, answerRecordId); | ||
| AnswerFeedback answerFeedback = AnswerFeedback.newBuilder().setClicked(clicked).build(); | ||
| AnswerRecord answerRecord = | ||
| AnswerRecord.newBuilder() | ||
| .setName(answerRecordName.toString()) | ||
| .setAnswerFeedback(answerFeedback) | ||
| .build(); | ||
| // Add a mask to control which field gets updated. | ||
| FieldMask fieldMask = FieldMask.newBuilder().addPaths("answer_feedback").build(); | ||
Shabirmean marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| UpdateAnswerRecordRequest request = | ||
| UpdateAnswerRecordRequest.newBuilder() | ||
| .setAnswerRecord(answerRecord) | ||
| .setUpdateMask(fieldMask) | ||
| .build(); | ||
| AnswerRecord response = answerRecordsClient.updateAnswerRecord(request); | ||
| System.out.println("===================="); | ||
| System.out.format("AnswerRecord updated:\n"); | ||
| System.out.format("Name: %s\n", response.getName()); | ||
| System.out.format("Clicked: %s\n", response.getAnswerFeedback().getClicked()); | ||
| } | ||
| } | ||
| } | ||
| // [END dialogflow_update_answer_record] | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,117 @@ | ||
| /* | ||
| * Copyright 2022 Google LLC | ||
| * | ||
| * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| * you may not use this file except in compliance with the License. | ||
| * You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
|
|
||
| package com.example.dialogflow; | ||
|
|
||
| import static org.junit.Assert.assertEquals; | ||
| import static org.junit.Assert.assertNotNull; | ||
| import static org.junit.Assert.assertTrue; | ||
|
|
||
| import com.google.cloud.dialogflow.v2.AnswerRecord; | ||
| import com.google.cloud.dialogflow.v2.AnswerRecordName; | ||
| import com.google.cloud.dialogflow.v2.AnswerRecordsClient; | ||
| import com.google.cloud.dialogflow.v2.LocationName; | ||
| import java.io.ByteArrayOutputStream; | ||
| import java.io.IOException; | ||
| import java.io.PrintStream; | ||
| import java.util.Optional; | ||
| import org.junit.After; | ||
| import org.junit.Before; | ||
| import org.junit.BeforeClass; | ||
| import org.junit.Test; | ||
| import org.junit.runner.RunWith; | ||
| import org.junit.runners.JUnit4; | ||
|
|
||
| @RunWith(JUnit4.class) | ||
| @SuppressWarnings("checkstyle:abbreviationaswordinname") | ||
| public class UpdateAnswerRecordTest { | ||
|
|
||
| private static final String PROJECT_ID = System.getenv("GOOGLE_CLOUD_PROJECT"); | ||
| private static final String LOCATION = "global"; | ||
| private static final String FIELD_PREFIX_IN_OUTPUT = "Clicked: "; | ||
| private ByteArrayOutputStream bout; | ||
| private PrintStream newOutputStream; | ||
| private PrintStream originalOutputStream; | ||
|
|
||
| private static void requireEnvVar(String varName) { | ||
| assertNotNull(System.getenv(varName)); | ||
| } | ||
|
|
||
| // Get one existing answer record from current project | ||
| private static Optional<AnswerRecord> getOneAnswerRecord() throws IOException { | ||
| try (AnswerRecordsClient answerRecordsClient = AnswerRecordsClient.create()) { | ||
| LocationName locationName = LocationName.of(PROJECT_ID, LOCATION); | ||
| for (AnswerRecord answerRecord : | ||
| answerRecordsClient.listAnswerRecords(locationName).iterateAll()) { | ||
| return Optional.of(answerRecord); | ||
| } | ||
| return Optional.empty(); | ||
| } | ||
| } | ||
|
|
||
| // Extract the value of an updated field from latest "Clicked: %s\n" in sample code output | ||
| private static String getFieldValueFromOutputString(String output) { | ||
| return output.substring( | ||
| output.lastIndexOf(FIELD_PREFIX_IN_OUTPUT) + FIELD_PREFIX_IN_OUTPUT.length(), | ||
| output.length() - 1); | ||
Shabirmean marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
|
|
||
| @BeforeClass | ||
| public static void checkRequirements() { | ||
| requireEnvVar("GOOGLE_APPLICATION_CREDENTIALS"); | ||
| requireEnvVar("GOOGLE_CLOUD_PROJECT"); | ||
| } | ||
|
|
||
| @Before | ||
| public void setUp() { | ||
| originalOutputStream = System.out; | ||
| bout = new ByteArrayOutputStream(); | ||
| newOutputStream = new PrintStream(bout); | ||
| System.setOut(newOutputStream); | ||
| } | ||
|
|
||
| @After | ||
| public void tearDown() throws IOException { | ||
| System.setOut(originalOutputStream); | ||
| } | ||
|
|
||
| @Test | ||
| public void testUpdateAnswerRecord() throws IOException { | ||
| // Get one answer record | ||
| Optional<AnswerRecord> answerRecordOptional = getOneAnswerRecord(); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Currently seems like if the project doesn't have any AnswerRecords then the test will fail. Can we create an Answer record in the project using the client before running the test? So failures can be scoped to what's being tested?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Currently there is no method for creating update records separately, as they are triggered by actual suggestions for human agent assistants. We could either change the unit test to an integration test which includes the process from creating conversation profile, creating conversation and knowledge base to importing documents, or prepare answer records in the testing environment. The former one is doable and I am not sure the efforts for the latter solution. Do you have any suggestions about it?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I see. I was thinking that an Currently the tests are also failing on this line because no AnswerRecord exists. [ERROR] com.example.dialogflow.UpdateAnswerRecordTest.testUpdateAnswerRecord Time elapsed: 0.196 s <<< FAILURE!
java.lang.AssertionError
at org.junit.Assert.fail(Assert.java:87)
at org.junit.Assert.assertTrue(Assert.java:42)
at org.junit.Assert.assertTrue(Assert.java:53)
at com.example.dialogflow.UpdateAnswerRecordTest.testUpdateAnswerRecord(UpdateAnswerRecordTest.java:95)Since we use a generic test project for all java samples, I think the best approach is to prepare the requires environment before running your tests. For example the
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @kolea2 any thoughts on how cases like this are handled generally with samples? |
||
| assertTrue(answerRecordOptional.isPresent()); | ||
|
|
||
| AnswerRecord originalAnswerRecord = answerRecordOptional.get(); | ||
| String answerRecordId = | ||
| AnswerRecordName.parse(originalAnswerRecord.getName()).getAnswerRecord(); | ||
| boolean originalClickedValue = originalAnswerRecord.getAnswerFeedback().getClicked(); | ||
| boolean newClickedValue = !originalClickedValue; | ||
|
|
||
| // Update clicked value | ||
| AnswerRecordManagement.updateAnswerRecord( | ||
| PROJECT_ID, LOCATION, answerRecordId, newClickedValue); | ||
| String output = bout.toString(); | ||
| boolean updatedClickedValue = getFieldValueFromOutputString(output).equals("true"); | ||
| assertEquals(newClickedValue, updatedClickedValue); | ||
|
|
||
| // Reset clicked value | ||
| AnswerRecordManagement.updateAnswerRecord( | ||
| PROJECT_ID, LOCATION, answerRecordId, originalClickedValue); | ||
| output = bout.toString(); | ||
| boolean resetClickedValue = getFieldValueFromOutputString(output).equals("true"); | ||
| assertEquals(originalClickedValue, resetClickedValue); | ||
| } | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.