-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcontext.go
221 lines (187 loc) · 6.49 KB
/
context.go
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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
package alexa
import (
"fmt"
"math/rand"
"strings"
"time"
"github.com/dasjott/alexa-sdk-go/dialog"
)
var random *rand.Rand
// Context is the object sent to every intent, collecting infos for response
type Context struct {
attributes
request *dialog.EchoRequest
handlers IntentHandlers
response *dialog.EchoResponse
translator *Translator
err error
abort bool
progress *dialog.ProgressRequest
// System contains informations about the calling Device and User
System *dialog.EchoSystem
// Intent is the intents name
Intent *dialog.EchoIntent
// Time is the requests timestamp as go time.Time
Time time.Time
}
func (c *Context) start(req *dialog.EchoRequest) {
if c.translator == nil {
panic("no translator set")
}
if c.attributes == nil {
c.attributes = make(attributes)
}
random = rand.New(rand.NewSource(time.Now().Unix()))
if BeforeHandler != nil {
BeforeHandler(c)
}
if !c.abort {
c.onIntent(req.GetIntentName())
}
}
func (c *Context) onIntent(name string) {
fmt.Printf("intent: %s\n", name)
if handler, exists := c.handlers[name]; exists {
handler(c)
} else if handler, exists := c.handlers["Unhandled"]; exists {
handler(c)
} else {
panic("no handler found")
}
}
func (c *Context) getResult() (*dialog.EchoResponse, error) {
c.progressWait()
c.response.SessionAttributes = c.attributes
return c.response, c.err
}
func (c *Context) progressWait() {
if c.progress != nil {
c.progress.Wait()
c.progress = nil
}
}
// Slot gets a slot by name. The pointer is never nil.
func (c *Context) Slot(name string) *Slot {
if c.request.Request.Intent.Slots != nil {
if slot, ok := c.request.Request.Intent.Slots[name]; ok {
return slotFromEchoSlot(&slot)
}
}
return &Slot{}
}
// NewSession determines whether this is a new session that was opened with this call
func (c *Context) NewSession() bool {
return c.request.Session.New
}
// SessionID is the unique ID of this session
func (c *Context) SessionID() string {
return c.request.Session.SessionID
}
// Locale gets the locale string like one of:
// de-DE, en-AU, en-CA, en-GB, en-IN, en-US, ja-JP, fr-FR
func (c *Context) Locale() string {
return c.request.Request.Locale
}
// DialogState gets the current state of the dialog
func (c *Context) DialogState() string {
return c.request.Request.DialogState
}
// T gets a translated string according to the given key. If the value is an array, a random value is chosen.
func (c *Context) T(key ...string) string {
for i, k := range key {
key[i] = c.translator.GetString(k)
}
return strings.Join(key, " ")
}
// TA gets a translated string array according to the given key.
func (c *Context) TA(key string) []string {
return c.translator.GetArray(key)
}
// TR gets a translated string according to the given key. If the value is an array, a random value is chosen.
// Variables in {brackets} will be replaced. Use either the alexa.R or a struct for providing variables (tag name would be 'alexa')!
func (c *Context) TR(key string, replace interface{}) string {
if repR, ok := replace.(R); ok {
return c.translator.GetStringAndReplace(key, repR)
}
return c.translator.GetStringWithVariables(key, replace)
}
// Tell something to the user
func (c *Context) Tell(speech string) *Cardable {
c.response.EndSession().OutputSSML(speech)
return &Cardable{c}
}
// Ask the user something
func (c *Context) Ask(speechOutput string, repromptSpeech ...string) *Cardable {
c.response.OutputSSML(speechOutput)
if count := len(repromptSpeech); count > 0 {
reprompt := repromptSpeech[random.Intn(count)]
c.response.RepromptSSML(reprompt)
}
return &Cardable{c}
}
// AudioPlay is for AudioPlayer.Play
func (c *Context) AudioPlay(audio, id, speech string) *Cardable {
// c.response.OutputSSML(speech).AudioDirective("AudioPlayer.Play", "REPLACE_ALL")
return &Cardable{c}
}
// AudioStop is for AudioPlayer.Stop, AudioPlayer.ClearQueue
func (c *Context) AudioStop(speech string) *Cardable {
// c.response.OutputSSML(speech).AudioDirective("AudioPlayer.Stop", "")
return &Cardable{c}
}
// ElicitSlot action to fullfill a slot of a certain intent
func (c *Context) ElicitSlot(slotToElicit, speechOutput, repromptSpeech string, updatedIntent *dialog.EchoIntent) *Cardable {
c.response.OutputSSML(speechOutput).RepromptSSML(repromptSpeech).SlotDirective("Dialog.ElicitSlot", slotToElicit, "", updatedIntent)
return &Cardable{c}
}
// ConfirmSlot confirm a slot value by Alexa
func (c *Context) ConfirmSlot(slotToConfirm, speechOutput, repromptSpeech string, updatedIntent *dialog.EchoIntent) *Cardable {
c.response.OutputSSML(speechOutput).RepromptSSML(repromptSpeech).SlotDirective("Dialog.ConfirmSlot", "", slotToConfirm, updatedIntent)
return &Cardable{c}
}
// ConfirmIntent confirm all the slots given to the intent by Alexa
func (c *Context) ConfirmIntent(speechOutput, repromptSpeech string, updatedIntent *dialog.EchoIntent) *Cardable {
c.response.OutputSSML(speechOutput).RepromptSSML(repromptSpeech).SlotDirective("Dialog.ConfirmIntent", "", "", updatedIntent)
return &Cardable{c}
}
// Delegate a slot fullfillment to Alexa
func (c *Context) Delegate(updatedIntent *dialog.EchoIntent) {
c.response.SlotDirective("Dialog.Delegate", "", "", updatedIntent)
}
// Progress sends a progress for the user to be entertained while waiting
func (c *Context) Progress(speech string) {
c.progressWait()
c.progress = dialog.NewProgressRequest(speech, c.request.Request.RequestID, c.System)
if c.progress != nil {
c.progress.Send()
}
}
// Now returns the time of the request on users side
func (c *Context) Now() time.Time {
return time.Now()
}
// Abort prevents the execution of a following handler within an alexa.MultiHandler chain.
func (c *Context) Abort() {
c.abort = true
}
// Cardable is returned by functions, to make them cardable
type Cardable struct {
cc *Context
}
// SimpleCard adds a simple card to the response
func (c *Cardable) SimpleCard(title, content string) {
c.cc.response.SimpleCard(title, content)
}
// StandardCard adds a standard card to the response
func (c *Cardable) StandardCard(title, content, smallImageURL, largeImageURL string) {
c.cc.response.StandardCard(title, content, smallImageURL, largeImageURL)
}
// LinkAccountCard adds a link account card to the response
func (c *Cardable) LinkAccountCard() {
c.cc.response.LinkAccountCard()
}
// AskPermissionCard adds a "ask for permission" card to the response
// you can use the constants from this package, prefixed with Permission
func (c *Cardable) AskPermissionCard(permissions []string) {
c.cc.response.AskPermissionCard(permissions)
}