alexa_generator 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 95714b270aa9dfa94bdaf3804000a38200a89003
4
- data.tar.gz: ab78ce1ab42d021cffee7eb1351da3476d66c164
3
+ metadata.gz: 4805b19d31381011f755d8270dc535a64bb75879
4
+ data.tar.gz: c0360ca35a27e1c95432681ba41c670c361e3606
5
5
  SHA512:
6
- metadata.gz: b057be5889006152bafea85083c142bdf89bfa2ab2ff59731843620828653973e25178993acab399349691d40f0569506a5fa6962ce44149b9fb90c528224ed9
7
- data.tar.gz: 489d2b018e6605b7ad7d64e06b8f5af47f10ea45691394cb40348b0e1be36a7d3db9e3ba6b254b982f30761a0d043962bf10b8e8680ccf8ebe001326728881e2
6
+ metadata.gz: 3a760ba8c02c4f78922b4e42e4f93b6795c5f4b7a0d506b6ac67231df366194b1ba0320f4dd17e6089ff13dd58994ed089aee42f9834013acb6f66683c35b67a
7
+ data.tar.gz: b50e3df34f7742573f1c2c49cacbe96aa96a54f358d56dc4098ae8991f0d6284ad389bfcb347fad5e88c61aa43038e2286153b1b2221384200fae7bb37c301eb
data/README.md CHANGED
@@ -1,2 +1,109 @@
1
1
  # alexa_generator
2
- Rubygem to generate voice interface components for Amazon's Alexa API
2
+ Rubygem to generate the [interaction model](https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/alexa-skills-kit-interaction-model-reference) for Amazon's Alexa API.
3
+
4
+ ## Installing
5
+
6
+ alexa_generator is available on [Rubygems](https://rubygems.org). You can install it with:
7
+
8
+ ```
9
+ $ gem install alexa_generator
10
+ ```
11
+
12
+ You can also add it to your Gemfile:
13
+
14
+ ```
15
+ gem 'alexa_generator'
16
+ ```
17
+
18
+ ## What's this?
19
+
20
+ To register a skill with Amazon's Alexa API, one must create an *intent schema* and a list of *sample utterances*. I found this process to be really tedious, and wanted an easier and more maintainable way to define interaction models.
21
+
22
+ ## Example usage
23
+
24
+ Here's an example of building the intent schema used in [Amazon's example](https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/alexa-skills-kit-interaction-model-reference):
25
+
26
+ ```ruby
27
+ model = AlexaGenerator::InteractionModel.build do |model|
28
+ model.add_intent(:GetHoroscope) do |intent|
29
+ intent.add_slot(:Sign, AlexaGenerator::Slot::SlotType::LITERAL) do |slot|
30
+ slot.add_bindings(*%w{Aries Taurus Gemini Cancer Leo Virgo Libra Scorpio Sagittarius Capricorn Aquarius Pisces})
31
+ end
32
+
33
+ intent.add_slot(:Date, AlexaGenerator::Slot::SlotType::DATE) do |slot|
34
+ slot.add_bindings('today', 'next Thursday', 'tomorrow')
35
+ end
36
+
37
+ intent.add_utterance_template('what is the horoscope for {Sign}')
38
+ intent.add_utterance_template('what will the horoscope for {Sign} be {Date}')
39
+ end
40
+ end
41
+ ```
42
+
43
+ ### Intent schema
44
+
45
+ One can then get the intent schema:
46
+
47
+ ```ruby
48
+ model.intent_schema
49
+ # => {:intents=>[{:intent=>:GetHoroscope, :slots=>[{:name=>:Sign, :type=>:LITERAL}, {:name=>:Date, :type=>:DATE}]}]}
50
+ ```
51
+
52
+ Amazon expects JSON as input, so you might want to convert:
53
+
54
+ ```ruby
55
+ require 'json'
56
+ JSON.pretty_generate(model.intent_schema)
57
+ # => {
58
+ # => "intents": [
59
+ # => {
60
+ # => "intent": "GetHoroscope",
61
+ # => "slots": [
62
+ # => {
63
+ # => "name": "Sign",
64
+ # => "type": "LITERAL"
65
+ # => },
66
+ # => {
67
+ # => "name": "Date",
68
+ # => "type": "DATE"
69
+ # => }
70
+ # => ]
71
+ # => }
72
+ # => ]
73
+ # => }
74
+ ```
75
+
76
+ ### Sample utterances
77
+
78
+ `alexa_generator` generates all possible combinations of slot bindings and applies them to the provided sample utterance templates. In the above example:
79
+
80
+ ```ruby
81
+ model.sample_utterances(:GetHoroscope)
82
+ ```
83
+
84
+ will output the following (clipped for the sake of brevity):
85
+
86
+ ```
87
+ GetHoroscope what is the horoscope for {Aquarius|Sign}
88
+ GetHoroscope what is the horoscope for {Aries|Sign}
89
+ GetHoroscope what is the horoscope for {Cancer|Sign}
90
+ GetHoroscope what is the horoscope for {Capricorn|Sign}
91
+ GetHoroscope what is the horoscope for {Gemini|Sign}
92
+ GetHoroscope what is the horoscope for {Leo|Sign}
93
+ GetHoroscope what is the horoscope for {Libra|Sign}
94
+ GetHoroscope what is the horoscope for {Pisces|Sign}
95
+ GetHoroscope what is the horoscope for {Sagittarius|Sign}
96
+ GetHoroscope what is the horoscope for {Scorpio|Sign}
97
+ GetHoroscope what is the horoscope for {Taurus|Sign}
98
+ GetHoroscope what is the horoscope for {Virgo|Sign}
99
+ GetHoroscope what will the horoscope for {Aquarius|Sign} be {next Thursday|Date}
100
+ GetHoroscope what will the horoscope for {Aquarius|Sign} be {today|Date}
101
+ GetHoroscope what will the horoscope for {Aquarius|Sign} be {tomorrow|Date}
102
+ [... clipped ...]
103
+ GetHoroscope what will the horoscope for {Taurus|Sign} be {next Thursday|Date}
104
+ GetHoroscope what will the horoscope for {Taurus|Sign} be {today|Date}
105
+ GetHoroscope what will the horoscope for {Taurus|Sign} be {tomorrow|Date}
106
+ GetHoroscope what will the horoscope for {Virgo|Sign} be {next Thursday|Date}
107
+ GetHoroscope what will the horoscope for {Virgo|Sign} be {today|Date}
108
+ GetHoroscope what will the horoscope for {Virgo|Sign} be {tomorrow|Date}
109
+ ```
@@ -0,0 +1,4 @@
1
+ module AlexaGenerator
2
+ class AlexaSyntaxError < StandardError
3
+ end
4
+ end
@@ -28,6 +28,16 @@ module AlexaGenerator
28
28
  end
29
29
 
30
30
  def initialize(intents, utterance_templates, slot_bindings)
31
+ # Validate that utterance templates reference only defined slots
32
+ all_referenced_slots = utterance_templates.map(&:referenced_slots).flatten
33
+ slot_names = Set.new(slot_bindings.map(&:slot_name))
34
+ undefined_slots = all_referenced_slots.reject { |x| slot_names.include?(x) }
35
+
36
+ if undefined_slots.any?
37
+ raise AlexaSyntaxError,
38
+ "The following slots referenced in utterances are undefined: #{undefined_slots.join ','}"
39
+ end
40
+
31
41
  @intents = Hash[ intents.map {|x| [x.name, x]} ]
32
42
 
33
43
  @utterance_templates = utterance_templates.group_by { |x| x.intent_name }
@@ -22,7 +22,7 @@ module AlexaGenerator
22
22
  end
23
23
 
24
24
  def add_bindings(*values)
25
- values.map { |v| @bindings.push(v) }
25
+ @bindings.concat(values)
26
26
  end
27
27
 
28
28
  def create
@@ -1,3 +1,3 @@
1
1
  module AlexaGenerator
2
- VERSION = '0.1.1'
2
+ VERSION = '0.1.2'
3
3
  end
@@ -1,2 +1,3 @@
1
1
  require 'alexa_generator/interaction_model'
2
+ require 'alexa_generator/alexa_syntax_error'
2
3
  require 'alexa_generator/version'
@@ -2,6 +2,18 @@ require 'spec_helper'
2
2
  require 'json'
3
3
 
4
4
  describe AlexaGenerator::InteractionModel do
5
+ context 'invalid slot bindings' do
6
+ it 'should throw an exception' do
7
+ expect {
8
+ AlexaGenerator::InteractionModel.build do |iface|
9
+ iface.add_intent(:Intent) do |intent|
10
+ intent.add_utterance_template('{UndefinedSlot}')
11
+ end
12
+ end
13
+ }.to raise_error(AlexaGenerator::AlexaSyntaxError)
14
+ end
15
+ end
16
+
5
17
  context 'builder' do
6
18
  it 'should build a valid voice interface' do
7
19
  iface = AlexaGenerator::InteractionModel.build do |iface|
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: alexa_generator
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Christopher Mullins
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-07-06 00:00:00.000000000 Z
11
+ date: 2015-07-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -51,6 +51,7 @@ files:
51
51
  - Rakefile
52
52
  - alexa_generator.gemspec
53
53
  - lib/alexa_generator.rb
54
+ - lib/alexa_generator/alexa_syntax_error.rb
54
55
  - lib/alexa_generator/intent.rb
55
56
  - lib/alexa_generator/intent_schema.rb
56
57
  - lib/alexa_generator/interaction_model.rb