actions-on-google / actions-on-google-java

Java/Kotlin library for Actions on Google
Apache License 2.0
287 stars 39 forks source link

Unable to modify conversationData, userStorage values in Kotlin #26

Closed pawelcala closed 5 years ago

pawelcala commented 5 years ago

conversationData and userStorage are immutable values and cannot be changed using kotlin. For now there is no option to modify this! One of possible solution is to override getResponseBuilder in DialogflowApp and construct own ResponseBuilder with custom data BUT ResponseBuilder is internal class. Someone already noticed that in other task few months ago and you didn't fixed it yet. Please fix this!

Fleker commented 5 years ago

This is the same as #17, where you can clone the object to a mutable implementation.

cbeaujoin commented 5 years ago

As said in #17 userStorage works fine when cloned.

But conversationData doesn't works.

The conversationData is overrided in ResponseSerializer.kt https://github.com/actions-on-google/actions-on-google-java/blob/5e2c7c9b2912d2f8b11aafb05162c2c9967af5f8/src/main/kotlin/com/google/actions/api/impl/io/ResponseSerializer.kt#L94

You should put it before line 86

As workaround you can try to access and modify conversationData trough context

ActionContext context = request.getContext(request.getSessionId() + "/contexts/" + "_actions_on_google");
String serializedData = (String) context.getParameters().get("data");
Type empMapType = new TypeToken<Map<String, Object>>() {}.getType();
Map<String, Object> conversationData = new Gson().fromJson(serializedData, empMapType);
...
conversationData.put("test", test);
responseContext.getParameters().put("data", conversationData);

Edit: The workaround was a bad idea, once the conversationData has been set it can't be parse in the next request due to a class cast exception (String <=> LinkedTreeMap).

https://github.com/actions-on-google/actions-on-google-java/blob/5e2c7c9b2912d2f8b11aafb05162c2c9967af5f8/src/main/kotlin/com/google/actions/api/impl/DialogflowRequest.kt#L63

Fleker commented 5 years ago

The same thing seems to work for conversation data in Kotlin

val sessionData = mutableMapOf<String, Any>()
sessionData.putAll(aogRequest.conversationData)

val headquarters = sessionData["headquarters"] as MutableList<String>
assertEquals("google1", headquarters[0])
headquarters[0] = "google2"

sessionData["headquarters"] = headquarters
val responseBuilder =
        ResponseBuilder(usesDialogflow = false, conversationData = sessionData)

val aogResponse = responseBuilder.build()
val jsonOutput = aogResponse.toJson()
cbeaujoin commented 5 years ago

Have you noticed that conversationData is overided by the context: [sessionId]/contexts/_actions_on_google

Fleker commented 5 years ago

When using Dialogflow?

cbeaujoin commented 5 years ago

When using Dialogflow?

Yes

taycaldwell commented 5 years ago

Closing as a duplicate of https://github.com/actions-on-google/actions-on-google-java/issues/17

For separate/unrelated bugs, please open a new issue.