1
1
package org.rewedigital.dialog.handler
2
2
3
- import org.rewedigital.dialog.extensions.getSelectedOption
4
- import org.rewedigital.dialog.extensions.hasSurfaceCapability
5
- import org.rewedigital.dialog.extensions.permissionGranted
6
- import org.rewedigital.dialog.extensions.signInStatus
3
+ import com.google.gson.Gson
4
+ import com.google.gson.reflect.TypeToken
5
+ import org.rewedigital.dialog.extensions.*
7
6
import org.rewedigital.dialog.model.dialogflow.DialogflowParams
8
7
import org.rewedigital.dialog.model.dialogflow.OutputContext
9
8
import org.rewedigital.dialog.model.dialogflow.WebhookRequest
10
9
import org.rewedigital.dialog.model.google.Conversation
11
10
import org.rewedigital.dialog.model.google.SurfaceCapabilities
11
+ import java.util.*
12
+ import kotlin.collections.HashMap
12
13
13
14
/* *
14
15
* Wrapper of [WebhookRequest] which provides utility functions for easier context access and other parameters.
@@ -19,12 +20,22 @@ class DialogflowHandler(private val webhookRequest: WebhookRequest) {
19
20
/* *
20
21
* Holds context related information.
21
22
*/
22
- val context: DialogflowHandler . ContextWrapper =
23
- DialogflowHandler . ContextWrapper (webhookRequest.queryResult?.outputContexts.orEmpty().map {
23
+ val context: ContextWrapper =
24
+ ContextWrapper (webhookRequest.queryResult?.outputContexts.orEmpty().map {
24
25
// clone the list and remove the session prefix
25
26
it.copy(name = it.name?.replace(" ${webhookRequest.session.orEmpty()} /contexts/" , " " ))
26
27
}.toMutableList(), webhookRequest.session.orEmpty())
27
28
29
+ /* *
30
+ * The stored user data aka user storage.
31
+ * @see https://developers.google.com/actions/assistant/save-data#json
32
+ */
33
+ val userData: MutableMap <String , Any ?> = run {
34
+ val userData = webhookRequest.originalDetectIntentRequest?.payload?.user?.userStorage
35
+ ? : return @run mutableMapOf<String , Any ?>()
36
+ fromJson(userData).toMutableMap()
37
+ }
38
+
28
39
/* *
29
40
* The action name defined in Dialogflow.
30
41
*/
@@ -52,9 +63,22 @@ class DialogflowHandler(private val webhookRequest: WebhookRequest) {
52
63
/* *
53
64
* An unique identifier of the users google account.
54
65
*/
55
- val userId: String?
56
- get() = webhookRequest.originalDetectIntentRequest?.payload?.user?.userId
57
- ? : webhookRequest.originalDetectIntentRequest?.payload?.user?.idToken
66
+ val userId: String
67
+ get() {
68
+ return if (userData.containsKey(" userId" )) {
69
+ userData[" userId" ] as String
70
+ } else {
71
+ val oldUserId = webhookRequest.originalDetectIntentRequest?.payload?.user?.userId
72
+ if (oldUserId.isNullOrEmpty()) {
73
+ val newUserId = UUID .randomUUID().toString()
74
+ userData[" userId" ] = newUserId
75
+ newUserId
76
+ } else {
77
+ userData[" userId" ] = oldUserId
78
+ oldUserId
79
+ }
80
+ }
81
+ }
58
82
59
83
/* *
60
84
* The unique identifier of detectIntent request session.
@@ -182,6 +206,26 @@ class DialogflowHandler(private val webhookRequest: WebhookRequest) {
182
206
context[name, key] = value
183
207
}
184
208
209
+ private fun fromJson (serializedValue : String? ): Map <String , Any > {
210
+ if (serializedValue != null && serializedValue.isNotEmpty()) {
211
+ val gson = Gson ()
212
+ try {
213
+ val map: Map <String , Any > = gson.fromJson(
214
+ serializedValue,
215
+ object : TypeToken <Map <String , Any >>() {}.type
216
+ )
217
+ // NOTE: The format of the opaque string is:
218
+ // keyValueData: {key:value; key:value; }
219
+ if (map[" data" ] != null ) {
220
+ return map[" data" ] as Map <String , Any >
221
+ }
222
+ } catch (e: Exception ) {
223
+ println (e.message)
224
+ }
225
+ }
226
+ return HashMap ()
227
+ }
228
+
185
229
class ContextWrapper (
186
230
private val context : MutableList <OutputContext >,
187
231
private val session : String
0 commit comments