alexa-rails 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +165 -0
- data/Rakefile +36 -0
- data/app/assets/config/alexa_manifest.js +2 -0
- data/app/assets/javascripts/alexa/application.js +13 -0
- data/app/assets/stylesheets/alexa/application.css +15 -0
- data/app/controllers/alexa/application_controller.rb +6 -0
- data/app/controllers/alexa/intent_handlers_controller.rb +49 -0
- data/app/helpers/alexa/application_helper.rb +4 -0
- data/app/helpers/alexa/context_helper.rb +23 -0
- data/app/helpers/alexa/render_helper.rb +24 -0
- data/app/jobs/alexa/application_job.rb +4 -0
- data/app/mailers/alexa/application_mailer.rb +6 -0
- data/app/models/alexa/application_record.rb +5 -0
- data/app/models/alexa/usage.rb +11 -0
- data/app/models/alexa/user.rb +17 -0
- data/app/views/alexa/_response.json.erb +18 -0
- data/app/views/alexa/output/_card.json.erb +13 -0
- data/app/views/alexa/output/_ssml.json.erb +7 -0
- data/app/views/alexa/output/cards/_ask_for_permissions_consent.json.erb +6 -0
- data/app/views/alexa/output/cards/_simple.json.erb +5 -0
- data/app/views/alexa/permission_consents/device_address.text.erb +7 -0
- data/app/views/layouts/alexa/application.html.erb +14 -0
- data/config/routes.rb +3 -0
- data/lib/alexa/context.rb +38 -0
- data/lib/alexa/device.rb +61 -0
- data/lib/alexa/engine.rb +5 -0
- data/lib/alexa/intent_handlers/base.rb +158 -0
- data/lib/alexa/request.rb +97 -0
- data/lib/alexa/response.rb +85 -0
- data/lib/alexa/responses/bye.rb +26 -0
- data/lib/alexa/responses/delegate.rb +18 -0
- data/lib/alexa/responses/permission_consents/device_address.rb +28 -0
- data/lib/alexa/session.rb +35 -0
- data/lib/alexa/slot.rb +50 -0
- data/lib/alexa/version.rb +3 -0
- data/lib/alexa-rails.rb +19 -0
- data/lib/generators/alexa/migrations_generator.rb +22 -0
- data/lib/generators/alexa/templates/create_alexa_usages.rb +13 -0
- data/lib/generators/alexa/templates/create_alexa_users.rb +13 -0
- data/lib/tasks/alexa_tasks.rake +4 -0
- metadata +115 -0
@@ -0,0 +1,158 @@
|
|
1
|
+
module Alexa
|
2
|
+
module IntentHandlers
|
3
|
+
class Base
|
4
|
+
class << self
|
5
|
+
def inherited(subclass)
|
6
|
+
subclass.instance_variable_set("@_required_slot_names", _required_slot_names.clone)
|
7
|
+
end
|
8
|
+
|
9
|
+
# Lets you set +required_slot_names+ per subclass
|
10
|
+
#
|
11
|
+
# class IntentHandlers::NewIntent < IntentHandlers::Base
|
12
|
+
# required_slot_names :Function, :CareerLevel
|
13
|
+
# end
|
14
|
+
#
|
15
|
+
# handler = IntentHandlers::NewIntent.new
|
16
|
+
# handler.required_slot_names # => [:Function, :CareerLevel]
|
17
|
+
|
18
|
+
def _required_slot_names
|
19
|
+
@_required_slot_names ||= []
|
20
|
+
end
|
21
|
+
|
22
|
+
def required_slot_names(*names)
|
23
|
+
@_required_slot_names = names.map(&:to_s)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
attr_accessor :context
|
28
|
+
|
29
|
+
def initialize(alexa_context)
|
30
|
+
@context = alexa_context
|
31
|
+
end
|
32
|
+
|
33
|
+
def request
|
34
|
+
context.request
|
35
|
+
end
|
36
|
+
|
37
|
+
def handle
|
38
|
+
raise "Override .handle"
|
39
|
+
end
|
40
|
+
|
41
|
+
def session
|
42
|
+
request.session
|
43
|
+
end
|
44
|
+
|
45
|
+
def response
|
46
|
+
@_response ||= Alexa::Response.new(intent: self)
|
47
|
+
end
|
48
|
+
|
49
|
+
def say_welcome?
|
50
|
+
@say_welcome == true
|
51
|
+
end
|
52
|
+
|
53
|
+
def slots
|
54
|
+
request.slots
|
55
|
+
end
|
56
|
+
|
57
|
+
def intent_usage_count
|
58
|
+
@_usage_count ||= context.user.usage_count_for(intent_name: request.intent_name)
|
59
|
+
end
|
60
|
+
|
61
|
+
def show_device_address_permission_consent_card?
|
62
|
+
@_show_device_address_permission_consent_card == true
|
63
|
+
end
|
64
|
+
|
65
|
+
|
66
|
+
protected
|
67
|
+
|
68
|
+
def has_all_slots?
|
69
|
+
empty_slots.empty?
|
70
|
+
end
|
71
|
+
|
72
|
+
def has_required_slots?
|
73
|
+
non_empty_slot_names = non_empty_slots.map { |_, s| s.name }
|
74
|
+
(required_slot_names - non_empty_slot_names).empty?
|
75
|
+
end
|
76
|
+
|
77
|
+
def empty_slots
|
78
|
+
@_empty_slots ||= slots.select { |name, slot| slot.value.nil? }
|
79
|
+
end
|
80
|
+
|
81
|
+
def non_empty_slots
|
82
|
+
@_non_empty_slots ||= slots.select { |name, slot| !slot.value.nil? }
|
83
|
+
end
|
84
|
+
|
85
|
+
def unmatched_slots
|
86
|
+
@_unmatched_slots ||= slots.select { |_, slot| slot.bad_match? }
|
87
|
+
end
|
88
|
+
|
89
|
+
def required_slot_names
|
90
|
+
self.class._required_slot_names
|
91
|
+
end
|
92
|
+
|
93
|
+
def intent_confirmed?
|
94
|
+
# TODO: Move this to Alexa::Request
|
95
|
+
request.params["request"]["intent"]["confirmationStatus"] == "CONFIRMED"
|
96
|
+
end
|
97
|
+
|
98
|
+
def intent_denied?
|
99
|
+
# TODO: Move this to Alexa::Request
|
100
|
+
request.params["request"]["intent"]["confirmationStatus"] == "DENIED"
|
101
|
+
end
|
102
|
+
|
103
|
+
def dialog_complete?
|
104
|
+
dialog_state == "COMPLETED"
|
105
|
+
end
|
106
|
+
|
107
|
+
def has_unmatched_slots?
|
108
|
+
unmatched_slots.any?
|
109
|
+
end
|
110
|
+
|
111
|
+
def dialog_state
|
112
|
+
request.dialog_state
|
113
|
+
end
|
114
|
+
|
115
|
+
def sorry_response
|
116
|
+
{
|
117
|
+
"version": "1.0",
|
118
|
+
sessionAttributes: session,
|
119
|
+
"response": {
|
120
|
+
"outputSpeech": {
|
121
|
+
"type": "PlainText",
|
122
|
+
"ssml": "Sorry! Looks like I couldn't process your request, may be try something else?"
|
123
|
+
},
|
124
|
+
"shouldEndSession": false
|
125
|
+
}
|
126
|
+
}
|
127
|
+
end
|
128
|
+
|
129
|
+
def show_device_address_permission_consent_card!
|
130
|
+
@_show_device_address_permission_consent_card = true
|
131
|
+
end
|
132
|
+
|
133
|
+
def device_address_permission_consent_response
|
134
|
+
@_device_address_permission_consent_response ||= Alexa::Responses::PermissionConsents::DeviceAddress.new(intent: self)
|
135
|
+
end
|
136
|
+
|
137
|
+
def delegate_response
|
138
|
+
@_delegate_response ||= Alexa::Responses::Delegate.new
|
139
|
+
end
|
140
|
+
|
141
|
+
def bye_response
|
142
|
+
@_bye_response ||= Alexa::Responses::Bye.new(intent: self)
|
143
|
+
end
|
144
|
+
|
145
|
+
def say_welcome!
|
146
|
+
@say_welcome = true
|
147
|
+
end
|
148
|
+
|
149
|
+
def video_supported?
|
150
|
+
context.device.video_supported?
|
151
|
+
end
|
152
|
+
|
153
|
+
def audio_supported?
|
154
|
+
context.device.audio_supported?
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
module Alexa
|
2
|
+
class Request
|
3
|
+
attr_accessor :body, :params
|
4
|
+
|
5
|
+
def initialize(request)
|
6
|
+
@req = request
|
7
|
+
@body = request.body
|
8
|
+
@params = if request.body.size > 0
|
9
|
+
request.body.rewind
|
10
|
+
JSON.parse(request.body.read).with_indifferent_access
|
11
|
+
else
|
12
|
+
{}
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def application_id
|
17
|
+
session.application_id
|
18
|
+
end
|
19
|
+
|
20
|
+
def user_id
|
21
|
+
session.user_id
|
22
|
+
end
|
23
|
+
|
24
|
+
def type
|
25
|
+
params["request"]["type"]
|
26
|
+
end
|
27
|
+
|
28
|
+
def intent_request?
|
29
|
+
type == "IntentRequest"
|
30
|
+
end
|
31
|
+
|
32
|
+
def launch_request?
|
33
|
+
type == "LaunchRequest"
|
34
|
+
end
|
35
|
+
|
36
|
+
def session_ended_request?
|
37
|
+
type == "SessionEndedRequest"
|
38
|
+
end
|
39
|
+
|
40
|
+
def help_request?
|
41
|
+
intent_request? && intent_name == "AMAZON.HelpIntent"
|
42
|
+
end
|
43
|
+
|
44
|
+
def cancel_request?
|
45
|
+
intent_request? && intent_name == "AMAZON.CancelIntent"
|
46
|
+
end
|
47
|
+
|
48
|
+
def session
|
49
|
+
@_session ||= Alexa::Session.new(params["session"].dup)
|
50
|
+
end
|
51
|
+
|
52
|
+
def slots
|
53
|
+
@_slots ||= begin
|
54
|
+
if intent_request?
|
55
|
+
return [] if help_request?
|
56
|
+
return [] if cancel_request?
|
57
|
+
|
58
|
+
params["request"]["intent"]["slots"]
|
59
|
+
.inject(HashWithIndifferentAccess.new) do |hash, slot|
|
60
|
+
name = slot[0]
|
61
|
+
data = slot[1]
|
62
|
+
hash[name] = Alexa::Slot.new(data)
|
63
|
+
hash
|
64
|
+
end
|
65
|
+
else
|
66
|
+
[]
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def dialog_state
|
72
|
+
params["request"]["dialogState"]
|
73
|
+
end
|
74
|
+
|
75
|
+
def valid?
|
76
|
+
Rails.configuration.x.alexa.skill_ids.include?(application_id)
|
77
|
+
end
|
78
|
+
|
79
|
+
def intent_name
|
80
|
+
return nil if !intent_request?
|
81
|
+
params["request"]["intent"]["name"]
|
82
|
+
end
|
83
|
+
|
84
|
+
def locale
|
85
|
+
request_locale = params["request"]["locale"]
|
86
|
+
case params["request"]["locale"]
|
87
|
+
when "en-US", "en-GB", "en-IN", 'en-CA'
|
88
|
+
# this is to match pjpp locale codes
|
89
|
+
params["request"]["locale"].gsub("-", "_").downcase
|
90
|
+
when "de-DE"
|
91
|
+
"de"
|
92
|
+
else
|
93
|
+
"en_gb"
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
module Alexa
|
2
|
+
class Response
|
3
|
+
attr_accessor :intent, :directives
|
4
|
+
|
5
|
+
def initialize(intent:, directives: [])
|
6
|
+
@intent = intent
|
7
|
+
@directives = directives
|
8
|
+
@slots_to_not_render_elicitation = []
|
9
|
+
end
|
10
|
+
|
11
|
+
# Marks a slot for elicitation.
|
12
|
+
#
|
13
|
+
# Options:
|
14
|
+
# - skip_render: Lets you skip the rendering of the elicited slot's view.
|
15
|
+
# Helpful when you have the elication text already in the
|
16
|
+
# response and don't wanna override it.
|
17
|
+
def elicit_slot!(slot_to_elicit, skip_render: false)
|
18
|
+
directives << {
|
19
|
+
type: "Dialog.ElicitSlot",
|
20
|
+
slotToElicit: slot_to_elicit
|
21
|
+
}
|
22
|
+
|
23
|
+
if skip_render
|
24
|
+
@slots_to_not_render_elicitation << slot_to_elicit
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def partial_path(format: :ssml, filename: nil)
|
29
|
+
if elicit_directives.any?
|
30
|
+
slot_to_elicit = elicit_directives.first[:slotToElicit]
|
31
|
+
end
|
32
|
+
|
33
|
+
template_path = "alexa/#{intent.context.locale}/intent_handlers/"\
|
34
|
+
"#{intent.class.name.demodulize.underscore}"
|
35
|
+
|
36
|
+
if filename.present?
|
37
|
+
if format == :ssml
|
38
|
+
"#{template_path}/#{filename}.ssml.erb"
|
39
|
+
else
|
40
|
+
"#{template_path}/#{filename}.text.erb"
|
41
|
+
end
|
42
|
+
else
|
43
|
+
if intent.show_device_address_permission_consent_card? && format == :text
|
44
|
+
return Alexa::Responses::PermissionConsents::DeviceAddress.new(
|
45
|
+
intent: intent
|
46
|
+
).partial_path(format: :text)
|
47
|
+
end
|
48
|
+
|
49
|
+
if slot_to_elicit.present? && !@slots_to_not_render_elicitation.include?(slot_to_elicit)
|
50
|
+
if format == :ssml
|
51
|
+
"#{template_path}/elicitations/#{slot_to_elicit.underscore}.ssml.erb"
|
52
|
+
else
|
53
|
+
"#{template_path}/elicitations/#{slot_to_elicit.underscore}.text.erb"
|
54
|
+
end
|
55
|
+
else
|
56
|
+
if format == :ssml
|
57
|
+
"#{template_path}/speech.ssml.erb"
|
58
|
+
else
|
59
|
+
"#{template_path}/display.text.erb"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def elicit_directives
|
66
|
+
return [] if directives.empty?
|
67
|
+
directives.select { |directive| directive[:type] == "Dialog.ElicitSlot" }
|
68
|
+
end
|
69
|
+
|
70
|
+
def keep_listening!
|
71
|
+
@keep_listening = true
|
72
|
+
self
|
73
|
+
end
|
74
|
+
|
75
|
+
def keep_listening?
|
76
|
+
@keep_listening == true
|
77
|
+
end
|
78
|
+
|
79
|
+
def end_session?
|
80
|
+
return false if keep_listening?
|
81
|
+
return false if elicit_directives.any?
|
82
|
+
return true
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Alexa
|
2
|
+
module Responses
|
3
|
+
class Bye < Alexa::Response
|
4
|
+
attr_accessor :intent, :directives
|
5
|
+
|
6
|
+
def initialize(intent:, directives: [])
|
7
|
+
@intent = intent
|
8
|
+
end
|
9
|
+
|
10
|
+
def partial_path(format: :ssml)
|
11
|
+
template_path = "alexa/#{intent.context.locale}/intent_handlers/"\
|
12
|
+
"#{intent.class.name.demodulize.underscore}"
|
13
|
+
|
14
|
+
if format == :ssml
|
15
|
+
"#{template_path}/bye.ssml.erb"
|
16
|
+
else
|
17
|
+
"#{template_path}/bye.text.erb"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def end_session?
|
22
|
+
true
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Alexa
|
2
|
+
module Responses
|
3
|
+
module PermissionConsents
|
4
|
+
class DeviceAddress < Alexa::Response
|
5
|
+
attr_accessor :intent, :directives
|
6
|
+
|
7
|
+
def initialize(intent:, directives: [])
|
8
|
+
@intent = intent
|
9
|
+
end
|
10
|
+
|
11
|
+
def partial_path(format: :ssml)
|
12
|
+
if format == :ssml
|
13
|
+
"alexa/#{intent.context.locale}/intent_handlers/"\
|
14
|
+
"#{intent.class.name.demodulize.underscore}"\
|
15
|
+
"/permission_consents/"\
|
16
|
+
"device_address.ssml.erb"
|
17
|
+
else
|
18
|
+
"alexa/permission_consents/device_address.text.erb"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def end_session?
|
23
|
+
true
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Alexa
|
2
|
+
class Session < HashWithIndifferentAccess
|
3
|
+
def initialize(session={})
|
4
|
+
@variables = session
|
5
|
+
super(session["attributes"])
|
6
|
+
end
|
7
|
+
|
8
|
+
def elicitation_count_for(slot_name)
|
9
|
+
self["elicitations"] ||= {}
|
10
|
+
if self["elicitations"][slot_name].present?
|
11
|
+
return self["elicitations"][slot_name]["count"]
|
12
|
+
end
|
13
|
+
return 0
|
14
|
+
end
|
15
|
+
|
16
|
+
def increment_elicitation_count!(slot_name)
|
17
|
+
count = elicitation_count_for(slot_name)
|
18
|
+
self["elicitations"].merge!(
|
19
|
+
"#{slot_name}": { count: count + 1 }
|
20
|
+
)
|
21
|
+
end
|
22
|
+
|
23
|
+
def new?
|
24
|
+
@variables["new"] == true
|
25
|
+
end
|
26
|
+
|
27
|
+
def application_id
|
28
|
+
@variables["application"]["applicationId"]
|
29
|
+
end
|
30
|
+
|
31
|
+
def user_id
|
32
|
+
@variables["user"]["userId"]
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/lib/alexa/slot.rb
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
module Alexa
|
2
|
+
class Slot
|
3
|
+
attr_accessor :name, :value
|
4
|
+
|
5
|
+
def initialize(attributes={})
|
6
|
+
@name = attributes['name']
|
7
|
+
@value = attributes['value']
|
8
|
+
@resolutions = attributes['resolutions']
|
9
|
+
end
|
10
|
+
|
11
|
+
def matched_value
|
12
|
+
if matched?
|
13
|
+
resolution["values"].first["value"]["name"]
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def matched_id
|
18
|
+
if matched?
|
19
|
+
resolution["values"].first["value"]["id"]
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def matched?
|
24
|
+
return false if !has_resolutions?
|
25
|
+
resolution["status"]["code"] == "ER_SUCCESS_MATCH"
|
26
|
+
end
|
27
|
+
|
28
|
+
def bad_match?
|
29
|
+
return false if !has_resolutions?
|
30
|
+
resolution["status"]["code"] == "ER_SUCCESS_NO_MATCH"
|
31
|
+
end
|
32
|
+
|
33
|
+
def has_resolutions?
|
34
|
+
@resolutions.present?
|
35
|
+
end
|
36
|
+
|
37
|
+
def resolution
|
38
|
+
return nil if !has_resolutions?
|
39
|
+
@resolutions["resolutionsPerAuthority"].first
|
40
|
+
end
|
41
|
+
|
42
|
+
def as_json(options={})
|
43
|
+
h = { name: name }
|
44
|
+
# add other attributes only if they are present
|
45
|
+
h.merge!(value: value) if value.present?
|
46
|
+
h.merge!(resolutions: @resolutions) if @resolutions.present?
|
47
|
+
h
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
data/lib/alexa-rails.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require "alexa/engine"
|
2
|
+
require 'alexa/context'
|
3
|
+
require 'alexa/device'
|
4
|
+
require 'alexa/request'
|
5
|
+
require 'alexa/response'
|
6
|
+
require 'alexa/session'
|
7
|
+
require 'alexa/slot'
|
8
|
+
require 'alexa/version'
|
9
|
+
require 'alexa/responses/bye'
|
10
|
+
require 'alexa/responses/delegate'
|
11
|
+
require 'alexa/responses/permission_consents/device_address'
|
12
|
+
require 'alexa/intent_handlers/base'
|
13
|
+
require_relative '../app/models/alexa/user'
|
14
|
+
require_relative '../app/models/alexa/usage'
|
15
|
+
|
16
|
+
|
17
|
+
module Alexa
|
18
|
+
# Your code goes here...
|
19
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'rails/generators'
|
2
|
+
require 'rails/generators/migration'
|
3
|
+
|
4
|
+
module Alexa
|
5
|
+
module Generators
|
6
|
+
class MigrationsGenerator < ::Rails::Generators::Base
|
7
|
+
include Rails::Generators::Migration
|
8
|
+
source_root File.expand_path('../templates', __FILE__)
|
9
|
+
desc "Add the migrations for Alexa"
|
10
|
+
|
11
|
+
def self.next_migration_number(path)
|
12
|
+
next_migration_number = current_migration_number(path) + 1
|
13
|
+
ActiveRecord::Migration.next_migration_number(next_migration_number)
|
14
|
+
end
|
15
|
+
|
16
|
+
def copy_migrations
|
17
|
+
migration_template "create_alexa_users.rb", "db/migrate/create_alexa_users.rb"
|
18
|
+
migration_template "create_alexa_usages.rb", "db/migrate/create_alexa_usages.rb"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class CreateAlexaUsages < ActiveRecord::Migration[4.2]
|
2
|
+
def up
|
3
|
+
create_table :alexa_usages do |t|
|
4
|
+
t.references :alexa_user, foreign_key: true
|
5
|
+
t.string :intent_name
|
6
|
+
t.integer :count, default: 0
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def down
|
11
|
+
drop_table :alexa_usages
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class CreateAlexaUsers < ActiveRecord::Migration[4.2]
|
2
|
+
def up
|
3
|
+
create_table :alexa_users do |t|
|
4
|
+
t.string :amazon_id
|
5
|
+
end
|
6
|
+
add_index :alexa_users, :amazon_id
|
7
|
+
end
|
8
|
+
|
9
|
+
def down
|
10
|
+
remove_index :alexa_users, :amazon_id
|
11
|
+
drop_table :alexa_users
|
12
|
+
end
|
13
|
+
end
|
metadata
ADDED
@@ -0,0 +1,115 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: alexa-rails
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Sri Vishnu Totakura
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2018-03-19 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rails
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 5.1.4
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 5.1.4
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: pg
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
description: The gem adds additional capabilities to your rails app to serve as a
|
42
|
+
backend for your Alexa skill by providing routing, controllers, views and structure
|
43
|
+
to easily develop and maintain skills' backend
|
44
|
+
email:
|
45
|
+
- srivishnu@totakura.in
|
46
|
+
executables: []
|
47
|
+
extensions: []
|
48
|
+
extra_rdoc_files: []
|
49
|
+
files:
|
50
|
+
- MIT-LICENSE
|
51
|
+
- README.md
|
52
|
+
- Rakefile
|
53
|
+
- app/assets/config/alexa_manifest.js
|
54
|
+
- app/assets/javascripts/alexa/application.js
|
55
|
+
- app/assets/stylesheets/alexa/application.css
|
56
|
+
- app/controllers/alexa/application_controller.rb
|
57
|
+
- app/controllers/alexa/intent_handlers_controller.rb
|
58
|
+
- app/helpers/alexa/application_helper.rb
|
59
|
+
- app/helpers/alexa/context_helper.rb
|
60
|
+
- app/helpers/alexa/render_helper.rb
|
61
|
+
- app/jobs/alexa/application_job.rb
|
62
|
+
- app/mailers/alexa/application_mailer.rb
|
63
|
+
- app/models/alexa/application_record.rb
|
64
|
+
- app/models/alexa/usage.rb
|
65
|
+
- app/models/alexa/user.rb
|
66
|
+
- app/views/alexa/_response.json.erb
|
67
|
+
- app/views/alexa/output/_card.json.erb
|
68
|
+
- app/views/alexa/output/_ssml.json.erb
|
69
|
+
- app/views/alexa/output/cards/_ask_for_permissions_consent.json.erb
|
70
|
+
- app/views/alexa/output/cards/_simple.json.erb
|
71
|
+
- app/views/alexa/permission_consents/device_address.text.erb
|
72
|
+
- app/views/layouts/alexa/application.html.erb
|
73
|
+
- config/routes.rb
|
74
|
+
- lib/alexa-rails.rb
|
75
|
+
- lib/alexa/context.rb
|
76
|
+
- lib/alexa/device.rb
|
77
|
+
- lib/alexa/engine.rb
|
78
|
+
- lib/alexa/intent_handlers/base.rb
|
79
|
+
- lib/alexa/request.rb
|
80
|
+
- lib/alexa/response.rb
|
81
|
+
- lib/alexa/responses/bye.rb
|
82
|
+
- lib/alexa/responses/delegate.rb
|
83
|
+
- lib/alexa/responses/permission_consents/device_address.rb
|
84
|
+
- lib/alexa/session.rb
|
85
|
+
- lib/alexa/slot.rb
|
86
|
+
- lib/alexa/version.rb
|
87
|
+
- lib/generators/alexa/migrations_generator.rb
|
88
|
+
- lib/generators/alexa/templates/create_alexa_usages.rb
|
89
|
+
- lib/generators/alexa/templates/create_alexa_users.rb
|
90
|
+
- lib/tasks/alexa_tasks.rake
|
91
|
+
homepage: https://github.com/tsrivishnu/alexa-rails
|
92
|
+
licenses:
|
93
|
+
- MIT
|
94
|
+
metadata: {}
|
95
|
+
post_install_message:
|
96
|
+
rdoc_options: []
|
97
|
+
require_paths:
|
98
|
+
- lib
|
99
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
105
|
+
requirements:
|
106
|
+
- - ">="
|
107
|
+
- !ruby/object:Gem::Version
|
108
|
+
version: '0'
|
109
|
+
requirements: []
|
110
|
+
rubyforge_project:
|
111
|
+
rubygems_version: 2.5.2.1
|
112
|
+
signing_key:
|
113
|
+
specification_version: 4
|
114
|
+
summary: Serve Alexa skills with your rails app as backend
|
115
|
+
test_files: []
|