This repository was archived by the owner on Feb 5, 2023. It is now read-only.
Repository navigation
Expand file tree
/
Copy pathintent.go
More file actions
91 lines (78 loc) · 2.32 KB
/
Copy pathintent.go
File metadata and controls
91 lines (78 loc) · 2.32 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
package fsm
import (
"regexp"
"strings"
)
// Intent is an event that occurs that can trigger a transition
type Intent struct {
Slug string
PlatformSlugs map[string]string
Slots map[string]*Type
Utterances []string
}
// Type is a definition of what a Intent slot value can be
type Type struct {
Slug string
PlatformSlugs map[string]string
Options []string
IsValid func(string) bool
}
var (
strippedSlotMatchRegex = regexp.MustCompile(`\\\{[^ ]*\\\}`)
cleanUtteranceRegex = regexp.MustCompile("[^a-z0-9 {}]+")
slotsRegex = regexp.MustCompile(`\{([^ ]*)\}`)
)
// Parse checks if an input string matches this intent. If the input string
// matches this intent, any parameters are also returned.
func (intent *Intent) Parse(input string) (bool, map[string]string) {
Utterance:
for _, utterance := range intent.Utterances {
// Generate regex for the utterance
cleanedUtterance := cleanUtteranceRegex.ReplaceAllString(strings.ToLower(utterance), "")
regexStr := "^" + strippedSlotMatchRegex.ReplaceAllString(regexp.QuoteMeta(cleanedUtterance), "(.*)") + "$"
utteranceRegex := regexp.MustCompile(regexStr)
// Check if it matches
matches := utteranceRegex.FindStringSubmatch(input)
if len(matches) < 1 {
continue
}
// Prepare slotValues
slotValues := map[string]string{}
// Get utterance slots
utteranceMatches := slotsRegex.FindAllStringSubmatch(utterance, -1)
slots := []string{}
for _, match := range utteranceMatches {
slots = append(slots, match[1])
}
// Validate all Parameters
for k, slot := range slots {
inputValue := matches[k+1]
slotType := intent.Slots[slot]
// Make sure it appears in the Options if we have a whitelist
if len(slotType.Options) > 0 {
valid := false
for _, option := range slotType.Options {
cleanedOption := CleanInput(option)
if cleanedOption == inputValue {
valid = true
break
}
}
if !valid {
continue Utterance
}
} else {
// If we don't have a whitelist, validate via the IsValid function
if !slotType.IsValid(inputValue) {
continue Utterance
}
}
// Valid if we reach this point, add to our slotValues
slotValues[slot] = inputValue
}
// OK
return true, slotValues
}
// We didn't match any of the utterances
return false, nil
}