alexa_web_service 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 15993c14f7130ce1da02a8b71c75e8a07ba1b5bf
4
+ data.tar.gz: 6e735f1ab713620b33c1095702f547de001645cd
5
+ SHA512:
6
+ metadata.gz: 5f1616e1cd46999c686edf440934f33ba9cf95e6fabaf65151f4c94ba3a1faa96aadf58cb8c151499c8ad31f40722b12af7f93d0fad8d83658f34ec2fa823694
7
+ data.tar.gz: 2232f4c1784ba6b339e183fe98878f6f4c8c32c56f8a20d7c86a84a52e1ace4df81274a5cc4d35cc6f434795049075f66acfbafae17b15361ffef8be7b580984
@@ -0,0 +1,7 @@
1
+ require 'alexa_web_service/version'
2
+ require 'alexa_web_service/alexa_response'
3
+ require 'alexa_web_service/alexa_request'
4
+ require 'alexa_web_service/alexa_verify'
5
+
6
+ module AlexaWebService
7
+ end
@@ -0,0 +1,54 @@
1
+ module AlexaWebService
2
+ class AlexaRequest
3
+ attr_reader :intent_name, :slots, :timestamp, :request_type, :session_new, :user_id, :access_token, :application_id
4
+ attr_accessor :attributes
5
+ alias :session_new? :session_new
6
+
7
+ def initialize(response_hash)
8
+ session = response_hash["session"]
9
+ request = response_hash["request"]
10
+ if session
11
+ @attributes = session["attributes"] ? session["attributes"] : {}
12
+ @user_id = session["user"]["userId"] if session["user"]
13
+ @access_token = session["user"]["accessToken"] if session["user"]
14
+ @application_id = session["application"]["applicationId"] if session["application"]
15
+ end
16
+
17
+ if request
18
+ @request_type = request["type"]
19
+ @timestamp = request["timestamp"]
20
+ @session_new = request["new"]
21
+
22
+ if request["intent"]
23
+ @intent_name = request["intent"]["name"] if request["intent"]
24
+ @slots = build_struct(request["intent"]["slots"]) if request["intent"]
25
+ end
26
+ end
27
+ end
28
+
29
+ def filled_slots
30
+ @slots.select { |slot| slot != nil}
31
+ end
32
+
33
+ def intent_request?
34
+ request_type == "IntentRequest"
35
+ end
36
+
37
+ def launch_request?
38
+ request_type == "LaunchRequest"
39
+ end
40
+
41
+ def session_ended_request?
42
+ request_type == "SessionEndedRequest"
43
+ end
44
+
45
+ private
46
+ def build_struct(hash)
47
+ unless hash.nil?
48
+ slot_names = hash.keys.map {|k| k.to_sym.downcase }
49
+ slot_values = hash.values.map { |v| v["value"] }
50
+ Struct.new(*slot_names).new(*slot_values)
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,57 @@
1
+ module AlexaWebService
2
+ class Response
3
+ attr_accessor :session_attributes, :spoken_response, :card_title, :card_content, :reprompt_text, :end_session, :speech_type, :text_type
4
+ def initialize(params={})
5
+ @session_attributes = params[:session_attributes] || {}
6
+ @speech_type = params[:speech_type] || "PlainText"
7
+ @spoken_response = params[:spoken_response] || nil
8
+ @card_title = params[:card_title] || nil
9
+ @card_content = params[:card_content] || nil
10
+ @reprompt_text = params[:reprompt_text] || nil
11
+ @text_type = params[:text_type] || "text"
12
+ @end_session = params[:end_session] || true
13
+ end
14
+
15
+ def add_attribute(key, value)
16
+ @session_attributes.merge!(key => value)
17
+ end
18
+
19
+ def append_attribute(key, value)
20
+ @session_attributes[key] << value if @session_attributes[key] != nil
21
+ end
22
+
23
+ def with_card
24
+ {
25
+ "version" => "1.0",
26
+ "sessionAttributes" =>
27
+ @session_attributes,
28
+ "response" => {
29
+ "outputSpeech" => {
30
+ "type" => speech_type,
31
+ "#{text_type}" => spoken_response
32
+ },
33
+ "card" => {
34
+ "type" => "Simple",
35
+ "title" => card_title,
36
+ "content" => card_content
37
+ },
38
+ "reprompt" => {
39
+ "outputSpeech" => {
40
+ "type" => speech_type,
41
+ "text" => reprompt_text
42
+ }
43
+ },
44
+ "shouldEndSession" => end_session
45
+ }
46
+ }
47
+ end
48
+
49
+ def link_card
50
+ self.with_card.tap { |hs| hs["response"]["card"] = {"type" => "LinkAccount"} }
51
+ end
52
+
53
+ def without_card
54
+ self.with_card.tap { |hs| hs["response"].delete("card") }
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,64 @@
1
+ module AlexaWebService
2
+ class AlexaVerify
3
+
4
+ def initialize(request_env, request_body)
5
+ @timestamp = JSON.parse(request_body)["request"]["timestamp"]
6
+ @url = request_env["HTTP_SIGNATURECERTCHAINURL"]
7
+ @signature = request_env["HTTP_SIGNATURE"]
8
+ @digest = OpenSSL::Digest::SHA1.new
9
+ end
10
+
11
+ def valid_address?
12
+ valid_address = /^https:\/\/s3.amazonaws.com(:443)?\/echo.api\/.*?$/
13
+ @url == @url.match(valid_address)[0] rescue false
14
+ end
15
+
16
+ def valid_timestamp?
17
+ Time.now < DateTime.parse(@timestamp).to_time + 150 rescue false
18
+ end
19
+
20
+ def valid_certificate?(certificate)
21
+ certificate.subject.to_a.last.include?("echo-api.amazon.com") &&
22
+ Time.now.utc > certificate.not_before &&
23
+ Time.now.utc < certificate.not_after
24
+ end
25
+
26
+ def get_certificate
27
+ begin
28
+ OpenSSL::X509::Certificate.new HTTParty.get(@url)
29
+ rescue TypeError
30
+ halt 400, "Bad Request"
31
+ rescue OpenSSL::SSL::SSLError
32
+ halt 400, "Bad Request"
33
+ end
34
+ end
35
+
36
+ def check_signature(certificate)
37
+ certificate.public_key.verify(@digest, Base64.decode64(@signature), @data) rescue false
38
+ end
39
+
40
+ def verify_request
41
+
42
+ if valid_address? && valid_timestamp?
43
+ @certificate = get_certificate
44
+ else
45
+ halt 400, "Bad Request"
46
+ end
47
+
48
+ if valid_certificate?(@certificate)
49
+ @verify = check_signature(@certificate)
50
+ else
51
+ halt 400, "Invalid Certificate"
52
+ end
53
+
54
+ if @verify
55
+ status 200
56
+ else
57
+ halt 400, "Invalid Signature"
58
+ end
59
+ end
60
+ end
61
+ end
62
+
63
+
64
+
@@ -0,0 +1,3 @@
1
+ module AlexaWebService
2
+ VERSION = "0.0.3"
3
+ end
metadata ADDED
@@ -0,0 +1,112 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: alexa_web_service
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.3
5
+ platform: ruby
6
+ authors:
7
+ - sarkonovich
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2016-06-27 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.10'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.10'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: httparty
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 0.13.5
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 0.13.5
55
+ - !ruby/object:Gem::Dependency
56
+ name: json
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.8'
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ version: 1.8.3
65
+ type: :runtime
66
+ prerelease: false
67
+ version_requirements: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - "~>"
70
+ - !ruby/object:Gem::Version
71
+ version: '1.8'
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: 1.8.3
75
+ description: A framework to handle and verify the JSON request/responses for an Alexa
76
+ skill
77
+ email:
78
+ - arkonovs @ reed. edu
79
+ executables: []
80
+ extensions: []
81
+ extra_rdoc_files: []
82
+ files:
83
+ - lib/alexa_web_service.rb
84
+ - lib/alexa_web_service/alexa_request.rb
85
+ - lib/alexa_web_service/alexa_response.rb
86
+ - lib/alexa_web_service/alexa_verify.rb
87
+ - lib/alexa_web_service/version.rb
88
+ homepage: https://github.com/sarkonovich/Alexa-Web-Service
89
+ licenses:
90
+ - MIT
91
+ metadata: {}
92
+ post_install_message:
93
+ rdoc_options: []
94
+ require_paths:
95
+ - lib
96
+ required_ruby_version: !ruby/object:Gem::Requirement
97
+ requirements:
98
+ - - ">="
99
+ - !ruby/object:Gem::Version
100
+ version: 2.0.0
101
+ required_rubygems_version: !ruby/object:Gem::Requirement
102
+ requirements:
103
+ - - ">="
104
+ - !ruby/object:Gem::Version
105
+ version: '0'
106
+ requirements: []
107
+ rubyforge_project:
108
+ rubygems_version: 2.4.8
109
+ signing_key:
110
+ specification_version: 4
111
+ summary: A framework to handle the JSON request/responses for an Alexa skill
112
+ test_files: []