stealth-alexa 1.0.0.pre1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 00d82cbb16942a0d0d6a8eed93574f89fe8668a6e8415571616e8fdc27947bbb
4
+ data.tar.gz: 7e7ff898f706709fdeaa6f4a4a2a6dafcf9923aa5118e30eddf4c665b614b263
5
+ SHA512:
6
+ metadata.gz: 77abcf122132eb2f3baaefcd155dfeb8148f54e4fc0392a770bceacf7389a63536e62134d5c45cb989f9fdd63bc4fc8623f26fadb5af5939c0c2d936c2037913
7
+ data.tar.gz: d16333d0b8d328f69a75b2df79bd75b7887053e5f47b092b700ae289135bf5e9d2522a21980d0d532a9284de505953e74ccdd0829751fe3f216ea5fdf87be9b9
@@ -0,0 +1,60 @@
1
+ # Ruby CircleCI 2.0 configuration file
2
+ #
3
+ # Check https://circleci.com/docs/2.0/language-ruby/ for more details
4
+ #
5
+ version: 2
6
+ jobs:
7
+ build:
8
+ docker:
9
+ # specify the version you desire here
10
+ - image: circleci/ruby:2.5.1-node-browsers
11
+ environment:
12
+ STEALTH_ENV: test
13
+
14
+ # Specify service dependencies here if necessary
15
+ # CircleCI maintains a library of pre-built images
16
+ # documented at https://circleci.com/docs/2.0/circleci-images/
17
+ # - image: circleci/postgres:9.4
18
+
19
+ working_directory: ~/repo
20
+
21
+ steps:
22
+ - checkout
23
+
24
+ # Download and cache dependencies
25
+ - restore_cache:
26
+ keys:
27
+ - v1-dependencies-{{ checksum "Gemfile.lock" }}
28
+ # fallback to using the latest cache if no exact match is found
29
+ - v1-dependencies-
30
+
31
+ - run:
32
+ name: install dependencies
33
+ command: |
34
+ bundle install --jobs=4 --retry=3 --path vendor/bundle
35
+
36
+ - save_cache:
37
+ paths:
38
+ - ./vendor/bundle
39
+ key: v1-dependencies-{{ checksum "Gemfile.lock" }}
40
+
41
+ # run tests!
42
+ - run:
43
+ name: run tests
44
+ command: |
45
+ mkdir /tmp/test-results
46
+ TEST_FILES="$(circleci tests glob "spec/**/*_spec.rb" | circleci tests split --split-by=timings)"
47
+
48
+ bundle exec rspec --format progress \
49
+ --format RspecJunitFormatter \
50
+ --out /tmp/test-results/rspec.xml \
51
+ --format progress \
52
+ -- \
53
+ $TEST_FILES
54
+
55
+ # collect reports
56
+ - store_test_results:
57
+ path: /tmp/test-results
58
+ - store_artifacts:
59
+ path: /tmp/test-results
60
+ destination: test-results
@@ -0,0 +1,12 @@
1
+ # please add general patterns to your global ignore list
2
+ # see https://github.com/github/gitignore#readme
3
+ .DS_STORE
4
+ *.swp
5
+ *.rbc
6
+ *.sass-cache
7
+ /pkg
8
+ /doc/api
9
+ /coverage
10
+ .yardoc
11
+ doc/
12
+ *.gem
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
@@ -0,0 +1,77 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ stealth-alexa (1.0.0)
5
+ stealth (< 2.0)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ activesupport (5.2.2)
11
+ concurrent-ruby (~> 1.0, >= 1.0.2)
12
+ i18n (>= 0.7, < 2)
13
+ minitest (~> 5.1)
14
+ tzinfo (~> 1.1)
15
+ concurrent-ruby (1.1.3)
16
+ connection_pool (2.2.2)
17
+ diff-lcs (1.3)
18
+ i18n (1.1.1)
19
+ concurrent-ruby (~> 1.0)
20
+ minitest (5.11.3)
21
+ multi_json (1.13.1)
22
+ mustermann (1.0.3)
23
+ puma (3.12.0)
24
+ rack (2.0.6)
25
+ rack-protection (2.0.4)
26
+ rack
27
+ rack-test (0.8.3)
28
+ rack (>= 1.0, < 3)
29
+ redis (4.0.3)
30
+ rspec (3.8.0)
31
+ rspec-core (~> 3.8.0)
32
+ rspec-expectations (~> 3.8.0)
33
+ rspec-mocks (~> 3.8.0)
34
+ rspec-core (3.8.0)
35
+ rspec-support (~> 3.8.0)
36
+ rspec-expectations (3.8.2)
37
+ diff-lcs (>= 1.2.0, < 2.0)
38
+ rspec-support (~> 3.8.0)
39
+ rspec-mocks (3.8.0)
40
+ diff-lcs (>= 1.2.0, < 2.0)
41
+ rspec-support (~> 3.8.0)
42
+ rspec-support (3.8.0)
43
+ rspec_junit_formatter (0.4.1)
44
+ rspec-core (>= 2, < 4, != 2.12.0)
45
+ sidekiq (5.2.3)
46
+ connection_pool (~> 2.2, >= 2.2.2)
47
+ rack-protection (>= 1.5.0)
48
+ redis (>= 3.3.5, < 5)
49
+ sinatra (2.0.4)
50
+ mustermann (~> 1.0)
51
+ rack (~> 2.0)
52
+ rack-protection (= 2.0.4)
53
+ tilt (~> 2.0)
54
+ stealth (1.1.1)
55
+ activesupport (~> 5.2)
56
+ multi_json (~> 1.12)
57
+ puma (~> 3.10)
58
+ sidekiq (~> 5.0)
59
+ sinatra (~> 2.0)
60
+ thor (~> 0.20)
61
+ thor (0.20.3)
62
+ thread_safe (0.3.6)
63
+ tilt (2.0.9)
64
+ tzinfo (1.2.5)
65
+ thread_safe (~> 0.1)
66
+
67
+ PLATFORMS
68
+ ruby
69
+
70
+ DEPENDENCIES
71
+ rack-test (~> 0.7)
72
+ rspec (~> 3.6)
73
+ rspec_junit_formatter (~> 0.3)
74
+ stealth-alexa!
75
+
76
+ BUNDLED WITH
77
+ 1.16.6
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2018 Mauricio Gomes, Black Ops Bureau Inc.
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,122 @@
1
+ # Stealth Alexa
2
+
3
+ The Stealth Alexa driver adds the ability to build Alexa voice bots via [Stealth](https://github.com/hellostealth/stealth). Alexa bots can be accessed via a wide array of Alexa-enabled products, including Amazon's own Echo devices (including those with displays).
4
+
5
+ This Stealth integration provides a way of building Alexa Skills using Stealth. Though the patterns for voice bots are the same as text-based bots, the reply types supported are unique.
6
+
7
+ ## Configure the Integration
8
+
9
+ ## Replies
10
+
11
+ Alexa replies are unique in that each request is processed synchronously (unlike most other Stealth integrations). Therefore, each reply should only contain a single reply.
12
+
13
+ Here are the supported replies for the Alexa integration:
14
+
15
+ ### Speech
16
+
17
+ These are standard replies for Alexa Skills. They are similar to `text` replies in other integrations. They can be sent like:
18
+
19
+ ```yaml
20
+ - reply_type: speech
21
+ text: Hello World!
22
+ ```
23
+
24
+ If your speech contains difficult to pronouce words or you wish to add effects to the speech, you can send along [SSML](https://developer.amazon.com/docs/custom-skills/speech-synthesis-markup-language-ssml-reference.html) to help Alexa pronouce the words.
25
+
26
+ ```yaml
27
+ - reply_type: speech
28
+ ssml: "I want to tell you a secret. <amazon:effect name="whispered">I see dead people.</amazon:effect>"
29
+ ```
30
+
31
+ Optionally, you can specify a `playBehavior` for how Alexa treats your reply. More info [here](https://developer.amazon.com/docs/custom-skills/request-and-response-json-reference.html#outputspeech-object).
32
+
33
+ ```yaml
34
+ - reply_type: speech
35
+ text: Hello World!
36
+ play_behavior: 'ENQUEUE'
37
+ ```
38
+
39
+ ### Reprompts
40
+
41
+ Reprompts are sent to the user when either they fail to respond or their response did not match one of your mapped intents. Reprompts are optional and if one is not set, nothing is sent to the user.
42
+
43
+ If you set `reprompt: true`, Stealth will re-send your speech.
44
+
45
+ ```yaml
46
+ - reply_type: speech
47
+ text: Hello World!
48
+ reprompt: true
49
+ ```
50
+
51
+ You may also customize your reprompt by specifying a complete `speech` object:
52
+
53
+ ```yaml
54
+ - reply_type: speech
55
+ text: "Today will provide you a new learning opportunity. Stick with it and the possibilities will be endless. Can I help you with anything else?"
56
+ reprompt:
57
+ text: "Can I help you with anything else?"
58
+ ```
59
+
60
+ You can also specify an SSML reprompt.
61
+
62
+ ### Cards
63
+
64
+ Cards are rich media that can be displayed via the Alexa mobile app or on devices that may feature a screen. Stealth supports all four card types:
65
+
66
+ * Simple - a card that contain a title and plain text content
67
+ * Standard - a card that contain a title, plain text content, and an image
68
+ * LinkAccount - a card that displays a link to an authorization URI that the user can use to link their Alexa account with a user in another system. See [Account Linking for Custom Skills](https://developer.amazon.com/docs/account-linking/account-linking-for-custom-skills.html) for details.
69
+ * AskForPermissionsConsent - A card that asks the customer for consent to obtain specific customer information, such as Alexa lists or address information. See [Alexa Shopping and To-Do Lists](https://developer.amazon.com/docs/custom-skills/access-the-alexa-shopping-and-to-do-lists.html#missing_permissions) and [Enhance Your Skill with Address Information](https://developer.amazon.com/docs/custom-skills/device-address-api.html).
70
+
71
+
72
+ Simple card:
73
+
74
+ ```yaml
75
+ - reply_type: card
76
+ type: Simple
77
+ title: Hello World
78
+ content: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas pretium, sem sed placerat elementum, purus quam iaculis dolor, a euismod urna magna et sem.
79
+ ```
80
+
81
+ For standard cards, you can specify a large and small image. For more info on the dimensions and file format, please check out [Alexa's documentation](https://developer.amazon.com/docs/custom-skills/include-a-card-in-your-skills-response.html#image_size).
82
+
83
+ ```yaml
84
+ - reply_type: card
85
+ type: Standard
86
+ title: Hello World
87
+ content: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas pretium, sem sed placerat elementum, purus quam iaculis dolor, a euismod urna magna et sem.
88
+ small_image_url: https://loremflickr.com/720/480
89
+ large_image_url: https://loremflickr.com/1200/800
90
+ ```
91
+
92
+ ### Sessions
93
+
94
+ By default, Stealth will keep a session open between replies. If you would like to end a session, you can set the `end_session` key to any reply:
95
+
96
+ ```yaml
97
+ - reply_type: speech
98
+ text: Hello World!
99
+ end_session: true
100
+ ```
101
+
102
+ ### Session Attributes
103
+
104
+ While your user's session is active, you can pass along key-value pairs in your responses. These will be spent back by Alexa in their requests. This is useful for multi-step scripts, like for example ordering a pizza.
105
+
106
+ To set these session values, you can include the `session_values` key in any your responses (except `AudioPlayer` and `PlaybackController` replies).
107
+
108
+ ```yaml
109
+ - reply_type: speech
110
+ text: Hello World!
111
+ session_values:
112
+ x: 1
113
+ y: blue
114
+ ```
115
+
116
+ ### Directives
117
+
118
+ Coming soon.
119
+
120
+ ### Delays
121
+
122
+ Delays are not supported for Alexa bots.
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 1.0.0.pre1
@@ -0,0 +1 @@
1
+ require 'stealth/alexa'
@@ -0,0 +1,2 @@
1
+ require 'stealth/services/alexa/version'
2
+ require 'stealth/services/alexa/client'
@@ -0,0 +1,29 @@
1
+ # coding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ require 'stealth/services/alexa/message_handler'
5
+ require 'stealth/services/alexa/reply_handler'
6
+ require 'stealth/services/alexa/setup'
7
+
8
+ module Stealth
9
+ module Services
10
+ module Alexa
11
+
12
+ class Client < Stealth::Services::BaseClient
13
+
14
+ attr_reader :reply
15
+
16
+ def initialize(reply:)
17
+ @reply = reply
18
+ Thread.current[:alexa_reply] = reply
19
+ end
20
+
21
+ def transmit
22
+ Stealth::Logger.l(topic: "alexa", message: "Response sent.")
23
+ end
24
+
25
+ end
26
+
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,101 @@
1
+ # coding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ require 'digest'
5
+
6
+ module Stealth
7
+ module Services
8
+ module Alexa
9
+ class MessageHandler < Stealth::Services::BaseMessageHandler
10
+
11
+ attr_reader :service_message, :params, :headers
12
+
13
+ def initialize(params:, headers:)
14
+ @params = params
15
+ @headers = headers
16
+ end
17
+
18
+ def coordinate
19
+ # Alexa requires an inline response
20
+ process
21
+ end
22
+
23
+ def process
24
+ @service_message = ServiceMessage.new(service: 'alexa')
25
+
26
+ # Load the request attributes
27
+ service_message.sender_id = get_sender_id
28
+ service_message.session_values = get_session_values
29
+ get_request_details
30
+
31
+ # Craft the reply
32
+ bot_controller = BotController.new(service_message: service_message)
33
+ bot_controller.route
34
+
35
+ send_alexa_reply
36
+ end
37
+
38
+ private
39
+
40
+ def send_alexa_reply
41
+ puts MultiJson.dump(Thread.current[:alexa_reply]).inspect
42
+ MultiJson.dump(Thread.current[:alexa_reply])
43
+ end
44
+
45
+ def get_sender_id
46
+ Digest::MD5.hexdigest(params.dig('session', 'user', 'userId'))
47
+ end
48
+
49
+ def get_session_values
50
+ params.dig('session', 'attributes')
51
+ end
52
+
53
+ def get_request_details
54
+ case params.dig('request', 'type')
55
+ when 'CanFulfillIntentRequest'
56
+ Stealth::Logger.l(topic: "alexa", message: "CanFulfillIntentRequest received.")
57
+ # Not yet implemented
58
+ when 'LaunchRequest'
59
+ service_message.timestamp = DateTime.parse(params.dig('request', 'timestamp'))
60
+ service_message.locale = params.dig('request', 'locale')
61
+ service_message.payload = 'LaunchRequest'
62
+ Stealth::Logger.l(topic: "alexa", message: "LaunchRequest received.")
63
+ when 'IntentRequest'
64
+ service_message.timestamp = DateTime.parse(params.dig('request', 'timestamp'))
65
+ service_message.locale = params.dig('request', 'locale')
66
+ service_message.payload = params.dig('request', 'intent', 'name')
67
+ Stealth::Logger.l(topic: "alexa", message: "IntentRequest [#{service_message.payload}] received.")
68
+
69
+ # Load the slots (if any)
70
+ # Alexa uses the SlotName as the key here 😡
71
+ params.dig('request', 'intent', 'slots')&.each do |slot_name, slot|
72
+ service_message.slots[slot_name] = slot.dig('value')
73
+ end
74
+ when 'SessionEndedRequest'
75
+ service_message.timestamp = DateTime.parse(params.dig('request', 'timestamp'))
76
+ service_message.locale = params.dig('request', 'locale')
77
+ service_message.payload = 'SessionEndedRequest'
78
+ Stealth::Logger.l(topic: "alexa", message: "SessionEndedRequest received.")
79
+ end
80
+ end
81
+
82
+ end
83
+
84
+ module Extensions
85
+ attr_accessor :slots, :session_values, :locale
86
+
87
+ def initialize(service:)
88
+ @slots = @session_values = {}
89
+ @locale = nil
90
+
91
+ super
92
+ end
93
+ end
94
+ end
95
+ end
96
+
97
+ class ServiceMessage
98
+ prepend Services::Alexa::Extensions
99
+ end
100
+
101
+ end
@@ -0,0 +1,161 @@
1
+ # coding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ module Stealth
5
+ module Services
6
+ module Alexa
7
+
8
+ class ReplyHandler < Stealth::Services::BaseReplyHandler
9
+
10
+ attr_reader :recipient_id, :reply
11
+
12
+ def initialize(recipient_id: nil, reply: nil)
13
+ @recipient_id = recipient_id
14
+ @reply = reply
15
+ end
16
+
17
+ def speech
18
+ if reply['ssml'].present? && reply['text'].present?
19
+ raise(ArgumentError, 'A speech reply cannot contain booth "text" and "SSML" values.')
20
+ end
21
+
22
+ response = generate_alexa_response
23
+ output_speech = generate_speech_response(
24
+ text: reply['text'],
25
+ ssml: reply['ssml'],
26
+ play_behavior: reply['play_behavior']
27
+ )
28
+
29
+ response['response'].merge!(output_speech)
30
+
31
+ # Session values
32
+ if reply['session_values'].present?
33
+ session_values = generate_session_response(session_values: reply['session_values'])
34
+ response.merge!(session_values)
35
+ end
36
+
37
+ # End session
38
+ response['response'].merge!(generate_end_session_response(reply['end_session']))
39
+
40
+ # Reprompts
41
+ if reply['reprompt'].present?
42
+ reprompt_response = generate_reprompt_response
43
+ response['response'].merge!(reprompt_response)
44
+ end
45
+
46
+ response
47
+ end
48
+
49
+ def card
50
+ response = generate_alexa_response
51
+
52
+
53
+
54
+ response
55
+ end
56
+
57
+ private
58
+
59
+ def generate_alexa_response
60
+ {
61
+ 'version' => '1.0',
62
+ 'response' => { }
63
+ }
64
+ end
65
+
66
+ def generate_speech_response(text:, ssml:, play_behavior: nil)
67
+ response = { 'outputSpeech' => { } }
68
+
69
+ if ssml.present?
70
+ response['outputSpeech']['type'] = 'SSML'
71
+ response['outputSpeech']['ssml'] = ssml
72
+ else
73
+ if text.size > 8_000
74
+ raise(ArgumentError, 'Speech replies cannot exceed 8000 characters.')
75
+ end
76
+
77
+ response['outputSpeech']['type'] = 'PlainText'
78
+ response['outputSpeech']['text'] = text
79
+ end
80
+
81
+ if play_behavior.present?
82
+ response['outputSpeech']['playBehavior'] = play_behavior
83
+ end
84
+
85
+ response
86
+ end
87
+
88
+ def generate_session_response(session_values:)
89
+ session_map = { 'sessionAttributes' => { } }
90
+
91
+ session_values.each do |k,v|
92
+ session_map['sessionAttributes'][k] = v
93
+ end
94
+
95
+ session_map
96
+ end
97
+
98
+ def generate_end_session_response(end_session=false)
99
+ { 'shouldEndSession' => end_session }
100
+ end
101
+
102
+ def generate_reprompt_response
103
+ if reply['reprompt'].is_a?(Boolean)
104
+ speech_response = generate_speech_response(
105
+ text: reply['text'],
106
+ ssml: reply['ssml'],
107
+ play_behavior: reply['play_behavior']
108
+ )
109
+ elsif reply['reprompt'].is_a?(Hash)
110
+ speech_response = generate_speech_response(
111
+ text: reply['reprompt']['text'],
112
+ ssml: reply['reprompt']['ssml'],
113
+ play_behavior: reply['reprompt']['play_behavior']
114
+ )
115
+ end
116
+
117
+ { 'reprompt': speech_response }
118
+ end
119
+
120
+ def generate_card_image_response
121
+ response = { }
122
+
123
+ if reply['small_image_url'].present?
124
+ response['smallImageUrl'] = reply['small_image_url']
125
+ end
126
+
127
+ if reply['large_image_url'].present?
128
+ response['largeImageUrl'] = reply['large_image_url']
129
+ end
130
+
131
+ response
132
+ end
133
+
134
+ def generate_card_response
135
+ response = { 'card' => { } }
136
+
137
+ case reply['type']
138
+ when 'Simple'
139
+ response['card']['type'] = 'Simple'
140
+ response['card']['title'] = reply['title']
141
+ response['card']['content'] = reply['content']
142
+ when 'Standard'
143
+ response['card']['type'] = 'Standard'
144
+ response['card']['title'] = reply['title']
145
+ response['card']['text'] = reply['content']
146
+
147
+ if generate_card_image_response.present?
148
+ response['card']['image'] = generate_card_image_response
149
+ end
150
+ when 'LinkAccount'
151
+ # Todo
152
+ when 'AskForPermissionsConsent'
153
+ # Todo
154
+ end
155
+ end
156
+
157
+ end
158
+
159
+ end
160
+ end
161
+ end
@@ -0,0 +1,20 @@
1
+ # coding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ module Stealth
5
+ module Services
6
+ module Alexa
7
+
8
+ class Setup
9
+
10
+ class << self
11
+ def trigger
12
+ Stealth::Logger.l(topic: "alexa", message: "There is no setup needed!")
13
+ end
14
+ end
15
+
16
+ end
17
+
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,16 @@
1
+ # coding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ module Stealth
5
+ module Services
6
+ module Alexa
7
+ module Version
8
+ def self.version
9
+ File.read(File.join(File.dirname(__FILE__), '..', '..', '..', '..', 'VERSION')).strip
10
+ end
11
+ end
12
+
13
+ VERSION = Version.version
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,14 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
3
+ require 'rspec'
4
+
5
+ require 'stealth'
6
+ require 'stealth-alexa'
7
+
8
+ # Requires supporting files with custom matchers and macros, etc,
9
+ # in ./support/ and its subdirectories.
10
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
11
+
12
+ RSpec.configure do |config|
13
+
14
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
4
+
5
+ describe "Stealth::Services::Alexa::Version" do
6
+
7
+ let(:version_in_file) { File.read(File.join(File.dirname(__FILE__), '..', 'VERSION')).strip }
8
+
9
+ it "should return the current gem version" do
10
+ expect(Stealth::Services::Alexa::Version.version).to eq version_in_file
11
+ end
12
+
13
+ it "should return the current gem version via a constant" do
14
+ expect(Stealth::Services::Alexa::VERSION).to eq version_in_file
15
+ end
16
+ end
@@ -0,0 +1,25 @@
1
+ $LOAD_PATH.push File.expand_path('../lib', __FILE__)
2
+
3
+ version = File.read(File.join(File.dirname(__FILE__), 'VERSION')).strip
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = 'stealth-alexa'
7
+ s.summary = 'Stealth Alexa driver'
8
+ s.description = 'Alexa driver for Stealth.'
9
+ s.homepage = 'https://github.com/hellostealth/stealth-alexa'
10
+ s.licenses = ['MIT']
11
+ s.version = version
12
+ s.author = 'Mauricio Gomes'
13
+ s.email = 'mauricio@edge14.com'
14
+
15
+ s.add_dependency 'stealth', '< 2.0'
16
+
17
+ s.add_development_dependency 'rspec', '~> 3.6'
18
+ s.add_development_dependency 'rspec_junit_formatter', '~> 0.3'
19
+ s.add_development_dependency 'rack-test', '~> 0.7'
20
+
21
+ s.files = `git ls-files`.split("\n")
22
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
23
+ s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
24
+ s.require_paths = ['lib']
25
+ end
metadata ADDED
@@ -0,0 +1,118 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: stealth-alexa
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0.pre1
5
+ platform: ruby
6
+ authors:
7
+ - Mauricio Gomes
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2018-12-10 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: stealth
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "<"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "<"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '3.6'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '3.6'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec_junit_formatter
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '0.3'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '0.3'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rack-test
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '0.7'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '0.7'
69
+ description: Alexa driver for Stealth.
70
+ email: mauricio@edge14.com
71
+ executables: []
72
+ extensions: []
73
+ extra_rdoc_files: []
74
+ files:
75
+ - ".circleci/config.yml"
76
+ - ".gitignore"
77
+ - Gemfile
78
+ - Gemfile.lock
79
+ - LICENSE
80
+ - README.md
81
+ - VERSION
82
+ - lib/stealth-alexa.rb
83
+ - lib/stealth/alexa.rb
84
+ - lib/stealth/services/alexa/client.rb
85
+ - lib/stealth/services/alexa/message_handler.rb
86
+ - lib/stealth/services/alexa/reply_handler.rb
87
+ - lib/stealth/services/alexa/setup.rb
88
+ - lib/stealth/services/alexa/version.rb
89
+ - spec/spec_helper.rb
90
+ - spec/version_spec.rb
91
+ - stealth-alexa.gemspec
92
+ homepage: https://github.com/hellostealth/stealth-alexa
93
+ licenses:
94
+ - MIT
95
+ metadata: {}
96
+ post_install_message:
97
+ rdoc_options: []
98
+ require_paths:
99
+ - lib
100
+ required_ruby_version: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - ">="
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
105
+ required_rubygems_version: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - ">"
108
+ - !ruby/object:Gem::Version
109
+ version: 1.3.1
110
+ requirements: []
111
+ rubyforge_project:
112
+ rubygems_version: 2.7.7
113
+ signing_key:
114
+ specification_version: 4
115
+ summary: Stealth Alexa driver
116
+ test_files:
117
+ - spec/spec_helper.rb
118
+ - spec/version_spec.rb