bot_framework 0.1.0beta
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +10 -0
- data/.rspec +2 -0
- data/.travis.yml +5 -0
- data/CODE_OF_CONDUCT.md +49 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +60 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/bot_framework.gemspec +31 -0
- data/examples/echo/bot.rb +8 -0
- data/examples/echo/config.ru +5 -0
- data/examples/stock/bot.rb +38 -0
- data/examples/stock/config.ru +5 -0
- data/lib/bot_framework.rb +48 -0
- data/lib/bot_framework/api_base.rb +31 -0
- data/lib/bot_framework/bot.rb +48 -0
- data/lib/bot_framework/bot_state.rb +89 -0
- data/lib/bot_framework/connector.rb +34 -0
- data/lib/bot_framework/conversation.rb +33 -0
- data/lib/bot_framework/errors.rb +4 -0
- data/lib/bot_framework/models/activity.rb +106 -0
- data/lib/bot_framework/models/api_response.rb +23 -0
- data/lib/bot_framework/models/attachment.rb +52 -0
- data/lib/bot_framework/models/attachment_data.rb +26 -0
- data/lib/bot_framework/models/attachment_info.rb +41 -0
- data/lib/bot_framework/models/attachment_view.rb +31 -0
- data/lib/bot_framework/models/base.rb +187 -0
- data/lib/bot_framework/models/bot_data.rb +15 -0
- data/lib/bot_framework/models/card_action.rb +43 -0
- data/lib/bot_framework/models/card_image.rb +36 -0
- data/lib/bot_framework/models/channel_account.rb +18 -0
- data/lib/bot_framework/models/conversation_account.rb +22 -0
- data/lib/bot_framework/models/conversation_parameters.rb +46 -0
- data/lib/bot_framework/models/entity.rb +26 -0
- data/lib/bot_framework/models/fact.rb +29 -0
- data/lib/bot_framework/models/geo_coordinates.rb +49 -0
- data/lib/bot_framework/models/hero_card.rb +62 -0
- data/lib/bot_framework/models/object.rb +19 -0
- data/lib/bot_framework/models/place.rb +56 -0
- data/lib/bot_framework/models/receipt_card.rb +78 -0
- data/lib/bot_framework/models/receipt_item.rb +60 -0
- data/lib/bot_framework/models/resource_response.rb +13 -0
- data/lib/bot_framework/models/signin_card.rb +35 -0
- data/lib/bot_framework/models/thumbnail_card.rb +62 -0
- data/lib/bot_framework/server.rb +56 -0
- data/lib/bot_framework/token_validator.rb +87 -0
- data/lib/bot_framework/util.rb +19 -0
- data/lib/bot_framework/version.rb +3 -0
- metadata +206 -0
@@ -0,0 +1,60 @@
|
|
1
|
+
module BotFramework
|
2
|
+
class ReceiptItem < Base
|
3
|
+
# Title of the Card
|
4
|
+
attr_accessor :title
|
5
|
+
|
6
|
+
# Subtitle appears just below Title field, differs from Title in font styling only
|
7
|
+
attr_accessor :subtitle
|
8
|
+
|
9
|
+
# Text field appears just below subtitle, differs from Subtitle in font styling only
|
10
|
+
attr_accessor :text
|
11
|
+
|
12
|
+
# Image
|
13
|
+
attr_accessor :image
|
14
|
+
|
15
|
+
# Amount with currency
|
16
|
+
attr_accessor :price
|
17
|
+
|
18
|
+
# Number of items of given kind
|
19
|
+
attr_accessor :quantity
|
20
|
+
|
21
|
+
# This action will be activated when user taps on the Item bubble.
|
22
|
+
attr_accessor :tap
|
23
|
+
|
24
|
+
# Attribute type mapping.
|
25
|
+
def self.swagger_types
|
26
|
+
{
|
27
|
+
title: :String,
|
28
|
+
subtitle: :String,
|
29
|
+
text: :String,
|
30
|
+
image: :CardImage,
|
31
|
+
price: :String,
|
32
|
+
quantity: :String,
|
33
|
+
tap: :CardAction
|
34
|
+
}
|
35
|
+
end
|
36
|
+
|
37
|
+
# Initializes the object
|
38
|
+
# @param [Hash] attributes Model attributes in the form of hash
|
39
|
+
def initialize(attributes = {})
|
40
|
+
return unless attributes.is_a?(Hash)
|
41
|
+
|
42
|
+
# convert string to symbol for hash key
|
43
|
+
attributes = attributes.each_with_object({}) { |(k, v), h| h[k.to_sym] = v }
|
44
|
+
|
45
|
+
self.title = attributes[:title] if attributes.key?(:title)
|
46
|
+
|
47
|
+
self.subtitle = attributes[:subtitle] if attributes.key?(:subtitle)
|
48
|
+
|
49
|
+
self.text = attributes[:text] if attributes.key?(:text)
|
50
|
+
|
51
|
+
self.image = attributes[:image] if attributes.key?(:image)
|
52
|
+
|
53
|
+
self.price = attributes[:price] if attributes.key?(:price)
|
54
|
+
|
55
|
+
self.quantity = attributes[:quantity] if attributes.key?(:quantity)
|
56
|
+
|
57
|
+
self.tap = attributes[:tap] if attributes.key?(:tap)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module BotFramework
|
2
|
+
# A card representing a request to signing
|
3
|
+
class SigninCard < Base
|
4
|
+
# Text for signin request
|
5
|
+
attr_accessor :text
|
6
|
+
|
7
|
+
# Action to use to perform signin
|
8
|
+
attr_accessor :buttons
|
9
|
+
|
10
|
+
# Attribute type mapping.
|
11
|
+
def self.swagger_types
|
12
|
+
{
|
13
|
+
text: :String,
|
14
|
+
buttons: :'Array<CardAction>'
|
15
|
+
}
|
16
|
+
end
|
17
|
+
|
18
|
+
# Initializes the object
|
19
|
+
# @param [Hash] attributes Model attributes in the form of hash
|
20
|
+
def initialize(attributes = {})
|
21
|
+
return unless attributes.is_a?(Hash)
|
22
|
+
|
23
|
+
# convert string to symbol for hash key
|
24
|
+
attributes = attributes.each_with_object({}) { |(k, v), h| h[k.to_sym] = v }
|
25
|
+
|
26
|
+
self.text = attributes[:text] if attributes.key?(:text)
|
27
|
+
|
28
|
+
if attributes.key?(:buttons)
|
29
|
+
if (value = attributes[:buttons]).is_a?(Array)
|
30
|
+
self.buttons = value
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module BotFramework
|
2
|
+
class ThumbnailCard < Base
|
3
|
+
# Title of the card
|
4
|
+
attr_accessor :title
|
5
|
+
|
6
|
+
# Subtitle of the card
|
7
|
+
attr_accessor :subtitle
|
8
|
+
|
9
|
+
# Text for the card
|
10
|
+
attr_accessor :text
|
11
|
+
|
12
|
+
# Array of i
|
13
|
+
attr_accessor :images
|
14
|
+
|
15
|
+
# Set of actions applicable to the current card
|
16
|
+
attr_accessor :buttons
|
17
|
+
|
18
|
+
# This action will be activated when user taps on the card itself
|
19
|
+
attr_accessor :tap
|
20
|
+
|
21
|
+
# Attribute type mapping.
|
22
|
+
def self.swagger_types
|
23
|
+
{
|
24
|
+
title: :String,
|
25
|
+
subtitle: :String,
|
26
|
+
text: :String,
|
27
|
+
images: :'Array<CardImage>',
|
28
|
+
buttons: :'Array<CardAction>',
|
29
|
+
tap: :CardAction
|
30
|
+
}
|
31
|
+
end
|
32
|
+
|
33
|
+
# Initializes the object
|
34
|
+
# @param [Hash] attributes Model attributes in the form of hash
|
35
|
+
def initialize(attributes = {})
|
36
|
+
return unless attributes.is_a?(Hash)
|
37
|
+
|
38
|
+
# convert string to symbol for hash key
|
39
|
+
attributes = attributes.each_with_object({}) { |(k, v), h| h[k.to_sym] = v }
|
40
|
+
|
41
|
+
self.title = attributes[:title] if attributes.key?(:title)
|
42
|
+
|
43
|
+
self.subtitle = attributes[:subtitle] if attributes.key?(:subtitle)
|
44
|
+
|
45
|
+
self.text = attributes[:text] if attributes.key?(:text)
|
46
|
+
|
47
|
+
if attributes.key?(:images)
|
48
|
+
if (value = attributes[:images]).is_a?(Array)
|
49
|
+
self.images = value
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
if attributes.key?(:buttons)
|
54
|
+
if (value = attributes[:buttons]).is_a?(Array)
|
55
|
+
self.buttons = value
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
self.tap = attributes[:tap] if attributes.key?(:tap)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module BotFramework
|
2
|
+
class Server
|
3
|
+
def self.call(env)
|
4
|
+
new.call(env)
|
5
|
+
end
|
6
|
+
|
7
|
+
def call(env)
|
8
|
+
@request = Rack::Request.new env
|
9
|
+
@response = Rack::Response.new
|
10
|
+
if @request.post?
|
11
|
+
if verify
|
12
|
+
receive
|
13
|
+
else
|
14
|
+
raise InvalidToken
|
15
|
+
end
|
16
|
+
end
|
17
|
+
@response.finish
|
18
|
+
end
|
19
|
+
|
20
|
+
# TODO: reply in separate thread t avoid timeout
|
21
|
+
def receive
|
22
|
+
# Thread.new {
|
23
|
+
activity = Activity.new.build_from_hash JSON.parse(@request.body.read)
|
24
|
+
Bot.receive(activity)
|
25
|
+
# }
|
26
|
+
end
|
27
|
+
|
28
|
+
def headers
|
29
|
+
env = @request.env
|
30
|
+
Hash[*env.select { |k, _v| k.start_with? 'HTTP_' }
|
31
|
+
.collect { |k, v| [k.sub(/^HTTP_/, ''), v] }
|
32
|
+
.collect { |k, v| [k.split('_').collect(&:capitalize).join('-'), v] }
|
33
|
+
.sort
|
34
|
+
.flatten]
|
35
|
+
end
|
36
|
+
|
37
|
+
# Use logger instead of puts
|
38
|
+
def verify
|
39
|
+
validator = TokenValidator.new(headers)
|
40
|
+
if validator.valid?
|
41
|
+
return true
|
42
|
+
else
|
43
|
+
p "Errors: #{validator.errors}"
|
44
|
+
return false
|
45
|
+
end
|
46
|
+
rescue JWT::DecodeError
|
47
|
+
[401, { 'Content-Type' => 'text/plain' }, ['A token must be passed.']]
|
48
|
+
rescue JWT::ExpiredSignature
|
49
|
+
[403, { 'Content-Type' => 'text/plain' }, ['The token has expired.']]
|
50
|
+
rescue JWT::InvalidIssuerError
|
51
|
+
[403, { 'Content-Type' => 'text/plain' }, ['The token does not have a valid issuer.']]
|
52
|
+
rescue JWT::InvalidIatError
|
53
|
+
[403, { 'Content-Type' => 'text/plain' }, ['The token does not have a valid "issued at" time.']]
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
module BotFramework
|
2
|
+
class TokenValidator
|
3
|
+
include HTTParty
|
4
|
+
attr_accessor :headers, :errors
|
5
|
+
|
6
|
+
OPEN_ID_CONFIG_URI = 'https://api.aps.skype.com/v1/.well-known/openidconfiguration'.freeze
|
7
|
+
|
8
|
+
def initialize(headers)
|
9
|
+
@headers = headers
|
10
|
+
end
|
11
|
+
|
12
|
+
def valid?
|
13
|
+
valid_header? &&
|
14
|
+
valid_jwt? &&
|
15
|
+
valid_iss? &&
|
16
|
+
valid_audience? &&
|
17
|
+
valid_token? &&
|
18
|
+
valid_signature?
|
19
|
+
end
|
20
|
+
|
21
|
+
def errors
|
22
|
+
@errors ||= []
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def open_id_config
|
28
|
+
JSON.parse(self.class.get(OPEN_ID_CONFIG_URI).body)
|
29
|
+
end
|
30
|
+
|
31
|
+
def jwks_uri
|
32
|
+
open_id_config['jwks_uri']
|
33
|
+
end
|
34
|
+
|
35
|
+
def valid_keys
|
36
|
+
JSON.parse(self.class.get(jwks_uri).body)['keys']
|
37
|
+
end
|
38
|
+
|
39
|
+
def auth_header
|
40
|
+
headers['Authorization']
|
41
|
+
end
|
42
|
+
|
43
|
+
def token
|
44
|
+
auth_header.gsub('Bearer ', '')
|
45
|
+
end
|
46
|
+
|
47
|
+
def valid_header?
|
48
|
+
# The token was sent in the HTTP Authorization header with "Bearer" scheme
|
49
|
+
condition = auth_header.start_with? 'Bearer'
|
50
|
+
errors << 'Invalid headers' unless condition
|
51
|
+
condition
|
52
|
+
end
|
53
|
+
# Validations
|
54
|
+
|
55
|
+
def valid_jwt?
|
56
|
+
# The token is valid JSON that conforms to the JWT standard (see references)
|
57
|
+
condition = JWT.decode token, nil, false
|
58
|
+
errors << 'Invalid jwt' unless condition
|
59
|
+
condition
|
60
|
+
end
|
61
|
+
|
62
|
+
def valid_iss?
|
63
|
+
# The token contains an issuer claim with value of https://api.botframework.com
|
64
|
+
condition = JWT.decode(token, nil, false).first['iss'] == 'https://api.botframework.com'
|
65
|
+
errors << 'Invalid iss' unless condition
|
66
|
+
condition
|
67
|
+
end
|
68
|
+
|
69
|
+
def valid_audience?
|
70
|
+
# The token contains an audience claim with a value equivalent to your bot’s Microsoft App ID.
|
71
|
+
condition = (JWT.decode(token, nil, false).first['aud'] == BotFramework.connector.app_id)
|
72
|
+
errors << 'Invalid audience' unless condition
|
73
|
+
condition
|
74
|
+
end
|
75
|
+
|
76
|
+
def valid_token?
|
77
|
+
# The token has not yet expired. Industry-standard clock-skew is 5 minutes.
|
78
|
+
# Should not raise JWT::ExpiredSignature
|
79
|
+
true
|
80
|
+
end
|
81
|
+
|
82
|
+
def valid_signature?
|
83
|
+
# The token has a valid cryptographic signature with a key listed in the OpenId keys document retrieved in step 1, above.
|
84
|
+
true
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module BotFramework
|
2
|
+
module Util
|
3
|
+
class << self
|
4
|
+
def to_underscore(string)
|
5
|
+
string = string.to_s unless string.is_a? String
|
6
|
+
string.gsub(/::/, '/')
|
7
|
+
.gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
|
8
|
+
.gsub(/([a-z\d])([A-Z])/, '\1_\2')
|
9
|
+
.tr('-', '_')
|
10
|
+
.downcase
|
11
|
+
end
|
12
|
+
|
13
|
+
def camel_case_lower(string)
|
14
|
+
string = string.to_s unless string.is_a? String
|
15
|
+
string.split('_').inject([]) { |buffer, e| buffer.push(buffer.empty? ? e : e.capitalize) }.join
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
metadata
ADDED
@@ -0,0 +1,206 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: bot_framework
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0beta
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Aboobacker MK
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-11-20 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.12'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.12'
|
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: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: pry
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: oauth2
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: jwt
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: httparty
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :runtime
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: rack
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :runtime
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
description: Unofficial ruby client for microsoft botframework
|
126
|
+
email:
|
127
|
+
- aboobackervyd@gmail.com
|
128
|
+
executables: []
|
129
|
+
extensions: []
|
130
|
+
extra_rdoc_files: []
|
131
|
+
files:
|
132
|
+
- ".gitignore"
|
133
|
+
- ".rspec"
|
134
|
+
- ".travis.yml"
|
135
|
+
- CODE_OF_CONDUCT.md
|
136
|
+
- Gemfile
|
137
|
+
- LICENSE.txt
|
138
|
+
- README.md
|
139
|
+
- Rakefile
|
140
|
+
- bin/console
|
141
|
+
- bin/setup
|
142
|
+
- bot_framework.gemspec
|
143
|
+
- examples/echo/bot.rb
|
144
|
+
- examples/echo/config.ru
|
145
|
+
- examples/stock/bot.rb
|
146
|
+
- examples/stock/config.ru
|
147
|
+
- lib/bot_framework.rb
|
148
|
+
- lib/bot_framework/api_base.rb
|
149
|
+
- lib/bot_framework/bot.rb
|
150
|
+
- lib/bot_framework/bot_state.rb
|
151
|
+
- lib/bot_framework/connector.rb
|
152
|
+
- lib/bot_framework/conversation.rb
|
153
|
+
- lib/bot_framework/errors.rb
|
154
|
+
- lib/bot_framework/models/activity.rb
|
155
|
+
- lib/bot_framework/models/api_response.rb
|
156
|
+
- lib/bot_framework/models/attachment.rb
|
157
|
+
- lib/bot_framework/models/attachment_data.rb
|
158
|
+
- lib/bot_framework/models/attachment_info.rb
|
159
|
+
- lib/bot_framework/models/attachment_view.rb
|
160
|
+
- lib/bot_framework/models/base.rb
|
161
|
+
- lib/bot_framework/models/bot_data.rb
|
162
|
+
- lib/bot_framework/models/card_action.rb
|
163
|
+
- lib/bot_framework/models/card_image.rb
|
164
|
+
- lib/bot_framework/models/channel_account.rb
|
165
|
+
- lib/bot_framework/models/conversation_account.rb
|
166
|
+
- lib/bot_framework/models/conversation_parameters.rb
|
167
|
+
- lib/bot_framework/models/entity.rb
|
168
|
+
- lib/bot_framework/models/fact.rb
|
169
|
+
- lib/bot_framework/models/geo_coordinates.rb
|
170
|
+
- lib/bot_framework/models/hero_card.rb
|
171
|
+
- lib/bot_framework/models/object.rb
|
172
|
+
- lib/bot_framework/models/place.rb
|
173
|
+
- lib/bot_framework/models/receipt_card.rb
|
174
|
+
- lib/bot_framework/models/receipt_item.rb
|
175
|
+
- lib/bot_framework/models/resource_response.rb
|
176
|
+
- lib/bot_framework/models/signin_card.rb
|
177
|
+
- lib/bot_framework/models/thumbnail_card.rb
|
178
|
+
- lib/bot_framework/server.rb
|
179
|
+
- lib/bot_framework/token_validator.rb
|
180
|
+
- lib/bot_framework/util.rb
|
181
|
+
- lib/bot_framework/version.rb
|
182
|
+
homepage: https://github.com/tachyons/bot-framework-ruby
|
183
|
+
licenses:
|
184
|
+
- MIT
|
185
|
+
metadata: {}
|
186
|
+
post_install_message:
|
187
|
+
rdoc_options: []
|
188
|
+
require_paths:
|
189
|
+
- lib
|
190
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
191
|
+
requirements:
|
192
|
+
- - ">="
|
193
|
+
- !ruby/object:Gem::Version
|
194
|
+
version: '0'
|
195
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
196
|
+
requirements:
|
197
|
+
- - ">"
|
198
|
+
- !ruby/object:Gem::Version
|
199
|
+
version: 1.3.1
|
200
|
+
requirements: []
|
201
|
+
rubyforge_project:
|
202
|
+
rubygems_version: 2.6.6
|
203
|
+
signing_key:
|
204
|
+
specification_version: 4
|
205
|
+
summary: Ruby client for microsoft botframework .
|
206
|
+
test_files: []
|