bot_framework 0.1.0beta

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +10 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +5 -0
  5. data/CODE_OF_CONDUCT.md +49 -0
  6. data/Gemfile +4 -0
  7. data/LICENSE.txt +21 -0
  8. data/README.md +60 -0
  9. data/Rakefile +6 -0
  10. data/bin/console +14 -0
  11. data/bin/setup +8 -0
  12. data/bot_framework.gemspec +31 -0
  13. data/examples/echo/bot.rb +8 -0
  14. data/examples/echo/config.ru +5 -0
  15. data/examples/stock/bot.rb +38 -0
  16. data/examples/stock/config.ru +5 -0
  17. data/lib/bot_framework.rb +48 -0
  18. data/lib/bot_framework/api_base.rb +31 -0
  19. data/lib/bot_framework/bot.rb +48 -0
  20. data/lib/bot_framework/bot_state.rb +89 -0
  21. data/lib/bot_framework/connector.rb +34 -0
  22. data/lib/bot_framework/conversation.rb +33 -0
  23. data/lib/bot_framework/errors.rb +4 -0
  24. data/lib/bot_framework/models/activity.rb +106 -0
  25. data/lib/bot_framework/models/api_response.rb +23 -0
  26. data/lib/bot_framework/models/attachment.rb +52 -0
  27. data/lib/bot_framework/models/attachment_data.rb +26 -0
  28. data/lib/bot_framework/models/attachment_info.rb +41 -0
  29. data/lib/bot_framework/models/attachment_view.rb +31 -0
  30. data/lib/bot_framework/models/base.rb +187 -0
  31. data/lib/bot_framework/models/bot_data.rb +15 -0
  32. data/lib/bot_framework/models/card_action.rb +43 -0
  33. data/lib/bot_framework/models/card_image.rb +36 -0
  34. data/lib/bot_framework/models/channel_account.rb +18 -0
  35. data/lib/bot_framework/models/conversation_account.rb +22 -0
  36. data/lib/bot_framework/models/conversation_parameters.rb +46 -0
  37. data/lib/bot_framework/models/entity.rb +26 -0
  38. data/lib/bot_framework/models/fact.rb +29 -0
  39. data/lib/bot_framework/models/geo_coordinates.rb +49 -0
  40. data/lib/bot_framework/models/hero_card.rb +62 -0
  41. data/lib/bot_framework/models/object.rb +19 -0
  42. data/lib/bot_framework/models/place.rb +56 -0
  43. data/lib/bot_framework/models/receipt_card.rb +78 -0
  44. data/lib/bot_framework/models/receipt_item.rb +60 -0
  45. data/lib/bot_framework/models/resource_response.rb +13 -0
  46. data/lib/bot_framework/models/signin_card.rb +35 -0
  47. data/lib/bot_framework/models/thumbnail_card.rb +62 -0
  48. data/lib/bot_framework/server.rb +56 -0
  49. data/lib/bot_framework/token_validator.rb +87 -0
  50. data/lib/bot_framework/util.rb +19 -0
  51. data/lib/bot_framework/version.rb +3 -0
  52. metadata +206 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: affe51df6b475a675f090f4130ced19a0f2ff6c9
4
+ data.tar.gz: 053aa8a5ace3a3fbd89fbe8ddb61d9ea168786f0
5
+ SHA512:
6
+ metadata.gz: d07903a48bc1036bb7f1e3c8960d7fd9d24ef5face9fccc1975e66e6ec1090f078e7425e718d5f6f8c91eb1d3db5b031035a6deb506a3af2feb57b0e6aa7dce3
7
+ data.tar.gz: b639f369042b2b8ccc98ea589cb1a29018e767f1ce2572755c4c2ab7eda79c0dc78f96f39ec1dfc82abcdcd1a4857260fc12581a9be6fff1c62c26b7f009ee5d
data/.gitignore ADDED
@@ -0,0 +1,10 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ .vscode
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.3.1
5
+ before_install: gem install bundler -v 1.12.5
@@ -0,0 +1,49 @@
1
+ # Contributor Code of Conduct
2
+
3
+ As contributors and maintainers of this project, and in the interest of
4
+ fostering an open and welcoming community, we pledge to respect all people who
5
+ contribute through reporting issues, posting feature requests, updating
6
+ documentation, submitting pull requests or patches, and other activities.
7
+
8
+ We are committed to making participation in this project a harassment-free
9
+ experience for everyone, regardless of level of experience, gender, gender
10
+ identity and expression, sexual orientation, disability, personal appearance,
11
+ body size, race, ethnicity, age, religion, or nationality.
12
+
13
+ Examples of unacceptable behavior by participants include:
14
+
15
+ * The use of sexualized language or imagery
16
+ * Personal attacks
17
+ * Trolling or insulting/derogatory comments
18
+ * Public or private harassment
19
+ * Publishing other's private information, such as physical or electronic
20
+ addresses, without explicit permission
21
+ * Other unethical or unprofessional conduct
22
+
23
+ Project maintainers have the right and responsibility to remove, edit, or
24
+ reject comments, commits, code, wiki edits, issues, and other contributions
25
+ that are not aligned to this Code of Conduct, or to ban temporarily or
26
+ permanently any contributor for other behaviors that they deem inappropriate,
27
+ threatening, offensive, or harmful.
28
+
29
+ By adopting this Code of Conduct, project maintainers commit themselves to
30
+ fairly and consistently applying these principles to every aspect of managing
31
+ this project. Project maintainers who do not follow or enforce the Code of
32
+ Conduct may be permanently removed from the project team.
33
+
34
+ This code of conduct applies both within project spaces and in public spaces
35
+ when an individual is representing the project or its community.
36
+
37
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
38
+ reported by contacting a project maintainer at aboobackervyd@gmail.com. All
39
+ complaints will be reviewed and investigated and will result in a response that
40
+ is deemed necessary and appropriate to the circumstances. Maintainers are
41
+ obligated to maintain confidentiality with regard to the reporter of an
42
+ incident.
43
+
44
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage],
45
+ version 1.3.0, available at
46
+ [http://contributor-covenant.org/version/1/3/0/][version]
47
+
48
+ [homepage]: http://contributor-covenant.org
49
+ [version]: http://contributor-covenant.org/version/1/3/0/
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in bot_framework.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 Aboobacker MK
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,60 @@
1
+ # BotFramework
2
+
3
+ Ruby client to make statefull bots using microsoft botframework . Currently under development , don't try this in under production till v1.0
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'bot_framework'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install bot_framework
20
+
21
+ ## Usage
22
+
23
+ Simple echo bot
24
+ ```ruby
25
+ BotFramework.configure do |connector|
26
+ connector.app_id = ENV['MICROSOFT_APP_ID']
27
+ connector.app_secret = ENV['MICROSOFT_APP_SECRET']
28
+ end
29
+
30
+ BotFramework::Bot.on :activity do |activity|
31
+ # Activity.id , identifier of the activity
32
+ # activity.timestamp
33
+ # activity.channel_id
34
+ # activity.from, sender
35
+ # activity.conversation
36
+ # activity.topic_name
37
+ # activity.locale
38
+ # activity.text
39
+ # and so on
40
+
41
+ reply(activity,activity.text)
42
+ end
43
+
44
+ ```
45
+
46
+ ## Development
47
+
48
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
49
+
50
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
51
+
52
+ ## Contributing
53
+
54
+ Bug reports and pull requests are welcome on GitHub at https://github.com/tachyons/bot_framework. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
55
+
56
+
57
+ ## License
58
+
59
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
60
+
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task default: :spec
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+ require 'bot_framework'
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ require 'pry'
11
+ Pry.start
12
+
13
+ # require 'irb'
14
+ # IRB.start
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,31 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'bot_framework/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'bot_framework'
8
+ spec.version = BotFramework::VERSION
9
+ spec.authors = ['Aboobacker MK']
10
+ spec.email = ['aboobackervyd@gmail.com']
11
+
12
+ spec.summary = 'Ruby client for microsoft botframework .'
13
+ spec.description = 'Unofficial ruby client for microsoft botframework'
14
+ spec.homepage = 'https://github.com/tachyons/bot-framework-ruby'
15
+ spec.license = 'MIT'
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
18
+ spec.bindir = 'exe'
19
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
+ spec.require_paths = ['lib']
21
+
22
+ spec.add_development_dependency 'bundler', '~> 1.12'
23
+ spec.add_development_dependency 'rake', '~> 10.0'
24
+ spec.add_development_dependency 'rspec', '~> 3.0'
25
+ spec.add_development_dependency 'pry'
26
+
27
+ spec.add_dependency 'oauth2'
28
+ spec.add_dependency 'jwt'
29
+ spec.add_dependency 'httparty'
30
+ spec.add_dependency 'rack'
31
+ end
@@ -0,0 +1,8 @@
1
+ BotFramework.configure do |connector|
2
+ connector.app_id = ENV['MICROSOFT_APP_ID']
3
+ connector.app_secret = ENV['MICROSOFT_APP_SECRET']
4
+ end
5
+
6
+ BotFramework::Bot.on :activity do |activity|
7
+ reply(activity, activity.text)
8
+ end
@@ -0,0 +1,5 @@
1
+ require 'pry'
2
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
3
+ require 'bot_framework'
4
+ require_relative 'bot'
5
+ run BotFramework::Server
@@ -0,0 +1,38 @@
1
+ require 'luis'
2
+ require 'stock_quote'
3
+
4
+ BotFramework.configure do |connector|
5
+ connector.app_id = ENV['MICROSOFT_APP_ID']
6
+ connector.app_secret = ENV['MICROSOFT_APP_SECRET']
7
+ end
8
+ Luis.configure do |config|
9
+ config.id = ENV['STOCK_LUIS_ID']
10
+ config.subscription_key = ENV['STOCK_LUIS_KEY']
11
+ # config.is_preview_mod = true
12
+ end
13
+
14
+ BotFramework::Bot.on :activity do |activity|
15
+ luis_result = Luis.query(activity.text)
16
+ if luis_result.intents.count > 0
17
+ case luis_result.intents[0].intent
18
+ when 'StockPrice'
19
+ stock = luis_result.entities[0].entity
20
+ stock_value = StockQuote::Stock.quote(stock).ask
21
+ result = " Current stock value of #{stock} is #{stock_value}"
22
+ set_conversation_data(activity, last_stock: stock)
23
+ when 'RepeatLastStock'
24
+ last_stock = get_conversation_data(activity)[:last_stock]
25
+ if last_stock
26
+ stock_value = StockQuote::Stock.quote(last_stock).ask
27
+ result = " Current stock value of #{last_stock} is #{stock_value}"
28
+ else
29
+ result = 'No previous value available'
30
+ end
31
+ when 'None'
32
+ result = "Sorry , I don't undersatnd"
33
+ end
34
+ else
35
+ result = "Sorry, I don't understand"
36
+ end
37
+ reply(activity, result)
38
+ end
@@ -0,0 +1,5 @@
1
+ require 'pry'
2
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
3
+ require 'bot_framework'
4
+ require_relative 'bot'
5
+ run BotFramework::Server
@@ -0,0 +1,48 @@
1
+ require 'oauth2'
2
+ require 'jwt'
3
+ require 'httparty'
4
+ require 'json'
5
+ require 'bot_framework/version'
6
+ require 'bot_framework/errors'
7
+ require 'bot_framework/util'
8
+ require 'bot_framework/connector'
9
+ require 'bot_framework/api_base'
10
+ require 'bot_framework/conversation'
11
+ require 'bot_framework/bot_state'
12
+ require 'bot_framework/token_validator'
13
+ require 'bot_framework/bot'
14
+ require 'bot_framework/server'
15
+ require 'bot_framework/models/base'
16
+ require 'bot_framework/models/activity'
17
+ require 'bot_framework/models/api_response'
18
+ require 'bot_framework/models/attachment'
19
+ require 'bot_framework/models/attachment_data'
20
+ require 'bot_framework/models/attachment_info'
21
+ require 'bot_framework/models/attachment_view'
22
+ require 'bot_framework/models/bot_data'
23
+ require 'bot_framework/models/card_action'
24
+ require 'bot_framework/models/card_image'
25
+ require 'bot_framework/models/channel_account'
26
+ require 'bot_framework/models/conversation_account'
27
+ require 'bot_framework/models/conversation_parameters'
28
+ require 'bot_framework/models/entity'
29
+ require 'bot_framework/models/fact'
30
+ require 'bot_framework/models/geo_coordinates'
31
+ require 'bot_framework/models/hero_card'
32
+ require 'bot_framework/models/object'
33
+ require 'bot_framework/models/place'
34
+ require 'bot_framework/models/receipt_card'
35
+ require 'bot_framework/models/receipt_item'
36
+ require 'bot_framework/models/resource_response'
37
+ require 'bot_framework/models/signin_card'
38
+ require 'bot_framework/models/thumbnail_card'
39
+
40
+ module BotFramework
41
+ class << self
42
+ attr_accessor :connector
43
+
44
+ def configure(*args, &block)
45
+ @connector = Connector.new(*args, &block)
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,31 @@
1
+ module BotFramework
2
+ class ApiBase
3
+ include HTTParty
4
+ attr_accessor :service_url
5
+
6
+ def initialize(service_url)
7
+ @service_url = service_url
8
+ end
9
+
10
+ def api_get(local_uri, _opts = {})
11
+ uri = service_url + local_uri
12
+ JSON.parse(BotFramework.connector.token.get(uri).body)
13
+ end
14
+
15
+ def api_post(local_uri, opts = {})
16
+ uri = service_url + local_uri
17
+ JSON.parse(BotFramework.connector.token.post(uri, body: opts.to_json,
18
+ headers: { 'Content-Type' => 'application/json' }).body)
19
+ end
20
+
21
+ def api_delete(local_uri)
22
+ uri = service_url + local_uri
23
+ BotFramework.connector.token.delete(uri)
24
+ end
25
+
26
+ def api_request(method, local_uri, opts)
27
+ uri = service_url + local_uri
28
+ BotFramework.connector.token.request(method, uri, opts)
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,48 @@
1
+ module BotFramework
2
+ class Bot
3
+ class << self
4
+ def on(event, &block)
5
+ hooks[event] = block
6
+ end
7
+
8
+ def trigger(event, *args)
9
+ # hooks.fetch(event).call(*args)
10
+ instance_exec *args, &hooks.fetch(event)
11
+ end
12
+
13
+ def receive(payload)
14
+ trigger(:activity, payload)
15
+ end
16
+
17
+ def reply(activity, message = '')
18
+ activity.reply(message)
19
+ end
20
+
21
+ def user_data=(data)
22
+ p "Data set as #{data}"
23
+ end
24
+
25
+ def set_conversation_data(activity, data)
26
+ data = BotFramework::BotData.new(data: data, e_tag: '*') if data.is_a? Hash
27
+ BotFramework::BotState.new('').set_conversation_data('channel_id' => activity.channel_id,
28
+ 'conversation_id' => activity.conversation.id,
29
+ 'bot_data' => data)
30
+ end
31
+
32
+ def conversation_data(activity)
33
+ BotFramework::BotState.new('').get_conversation_data(
34
+ 'channel_id' => activity.channel_id,
35
+ 'conversation_id' => activity.conversation.id
36
+ ).data || {}
37
+ end
38
+
39
+ def hooks
40
+ @hooks ||= {}
41
+ end
42
+
43
+ def reset_hooks
44
+ @hooks = {}
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,89 @@
1
+ module BotFramework
2
+ class BotState < ApiBase
3
+ def initialize(_service_url)
4
+ @service_url = 'https://state.botframework.com'
5
+ end
6
+
7
+ # DeleteStateForUser
8
+ # Delete all data for a user in a channel (UserData and PrivateConversationData)
9
+ # @param channel_id channelId
10
+ # @param user_id id for the user on the channel
11
+ # @param [Hash] opts the optional parameters
12
+ # @return [Array<String>]
13
+ def delete_state_for_user(opts = {})
14
+ uri = "/v3/botstate/#{opts['channel_id']}/users/#{opts['user_id']}"
15
+ api_delete(uri)
16
+ end
17
+
18
+ # GetConversationData
19
+ # get the bots data for all users in a conversation
20
+ # @param channel_id the channelId
21
+ # @param conversation_id The id for the conversation on the channel
22
+ # @param [Hash] opts the optional parameters
23
+ # @return [BotData]
24
+
25
+ def get_conversation_data(opts = {})
26
+ # opts['channel_id'] & opts['conversation_id']
27
+ uri = "/v3/botstate/#{opts['channel_id']}/conversations/#{opts['conversation_id']}"
28
+ BotFramework::BotData.new api_get(uri)
29
+ end
30
+
31
+ # GetPrivateConversationData
32
+ # get bot's data for a single user in a conversation
33
+ # @param channel_id channelId
34
+ # @param conversation_id The id for the conversation on the channel
35
+ # @param user_id id for the user on the channel
36
+ def get_private_conversation_data(opts = {})
37
+ uri = "/v3/botstate/#{opts['channel_id']}/conversations/#{opts['conversation_id']}/users/#{opts['user_id']}"
38
+ BotFramework::BotData.new api_get(uri)
39
+ end
40
+
41
+ # GetUserData
42
+ # Get a bots data for the user across all conversations
43
+ # @param channel_id channelId
44
+ # @param user_id id for the user on the channel
45
+ # @return [BotData]
46
+
47
+ def get_user_data(opts = {})
48
+ uri = "/v3/botstate/#{opts['channel_id']}/users/#{opts['user_id']}"
49
+ BotFramework::BotData.new api_get(uri)
50
+ end
51
+
52
+ # SetConversationData
53
+ # Update the bot's data for all users in a conversation
54
+ # @param channel_id channelId
55
+ # @param conversation_id The id for the conversation on the channel
56
+ # @param bot_data the new botdata
57
+ # @return [BotData]
58
+ def set_conversation_data(opts = {})
59
+ uri = "/v3/botstate/#{opts['channel_id']}/conversations/#{opts['conversation_id']}"
60
+ api_post(uri, opts['bot_data'])
61
+ end
62
+
63
+ # SetPrivateConversationData
64
+ # Update the bot's data for a single user in a conversation
65
+ # @param channel_id channelId
66
+ # @param conversation_id The id for the conversation on the channel
67
+ # @param user_id id for the user on the channel
68
+ # @param bot_data the new botdata
69
+ # @param [Hash] opts the optional parameters
70
+ # @return [BotData]
71
+
72
+ def set_private_conversation_data(opts = {})
73
+ uri = "/v3/botstate/#{opts['channel_id']}/conversations/#{opts['conversation_id']}/users/#{opts['user_id']}"
74
+ api_post(uri, opts['bot_data'])
75
+ end
76
+ # SetUserData
77
+ # Update the bot's data for a user
78
+ # @param channel_id channelId
79
+ # @param user_id id for the user on the channel
80
+ # @param bot_data the new botdata
81
+ # @param [Hash] opts the optional parameters
82
+ # @return [BotData]
83
+
84
+ def set_user_data(opts = {})
85
+ uri = "/v3/botstate/#{opts['channel_id']}/users/#{opts['user_id']}"
86
+ api_post(uri, opts['bot_data'])
87
+ end
88
+ end
89
+ end