dialogue 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: a27497ea1b044be9cba84022a78afdd74a8aca42
4
+ data.tar.gz: 2888b75a3c090d382fe5756723b69b08dff7aa62
5
+ SHA512:
6
+ metadata.gz: de6cda0344e98d34b5f2f6c73f0aa53086becb97d125f6522933228980c56223bade77720ffd70329b62e15449548663b3c09f9fb306bc9055531e43489a8cb4
7
+ data.tar.gz: 58c4e571652b3200200cb6b33e702f625d53b4530227a68fa8115b2fe337210a7129b0ef02404217090b9952d65d39c0cfcc1c2d08bbb91c277b58f285f563a7
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --require spec_helper
@@ -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 jamie@brilliantfantastic.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,3 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
@@ -0,0 +1,66 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ dialogue (0.0.1)
5
+ slack-ruby-client
6
+
7
+ GEM
8
+ remote: http://rubygems.org/
9
+ specs:
10
+ activesupport (5.0.0.1)
11
+ concurrent-ruby (~> 1.0, >= 1.0.2)
12
+ i18n (~> 0.7)
13
+ minitest (~> 5.1)
14
+ tzinfo (~> 1.1)
15
+ concurrent-ruby (1.0.4)
16
+ diff-lcs (1.2.5)
17
+ faraday (0.9.2)
18
+ multipart-post (>= 1.2, < 3)
19
+ faraday_middleware (0.10.0)
20
+ faraday (>= 0.7.4, < 0.10)
21
+ gli (2.13.4)
22
+ hashie (3.4.6)
23
+ i18n (0.8.0)
24
+ json (2.0.2)
25
+ minitest (5.10.1)
26
+ multipart-post (2.0.0)
27
+ rake (12.0.0)
28
+ rspec (3.5.0)
29
+ rspec-core (~> 3.5.0)
30
+ rspec-expectations (~> 3.5.0)
31
+ rspec-mocks (~> 3.5.0)
32
+ rspec-core (3.5.4)
33
+ rspec-support (~> 3.5.0)
34
+ rspec-expectations (3.5.0)
35
+ diff-lcs (>= 1.2.0, < 2.0)
36
+ rspec-support (~> 3.5.0)
37
+ rspec-mocks (3.5.0)
38
+ diff-lcs (>= 1.2.0, < 2.0)
39
+ rspec-support (~> 3.5.0)
40
+ rspec-support (3.5.0)
41
+ slack-ruby-client (0.7.0)
42
+ activesupport
43
+ faraday
44
+ faraday_middleware
45
+ gli
46
+ hashie
47
+ json
48
+ websocket-driver
49
+ thread_safe (0.3.5)
50
+ tzinfo (1.2.2)
51
+ thread_safe (~> 0.1)
52
+ websocket-driver (0.6.4)
53
+ websocket-extensions (>= 0.1.0)
54
+ websocket-extensions (0.1.2)
55
+
56
+ PLATFORMS
57
+ ruby
58
+
59
+ DEPENDENCIES
60
+ bundler
61
+ dialogue!
62
+ rake
63
+ rspec
64
+
65
+ BUNDLED WITH
66
+ 1.14.4
@@ -0,0 +1,7 @@
1
+ Copyright (c) 2016 Tatsu, Inc.
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
+
5
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
+
7
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,82 @@
1
+ Dialogue
2
+ ========
3
+
4
+ [ ![Codeship Status for tatsuio/dialogue](https://app.codeship.com/projects/9afef670-f132-0134-a265-7e8cdab40218/status?branch=master)](https://app.codeship.com/projects/209305)
5
+
6
+ ## DESCRIPTION
7
+
8
+ A DSL for defining conversations and workflows in Ruby. The conversations follow those workflows based on incoming messages and their intents.
9
+
10
+ This currently supports only [Slack](https://slack.com).
11
+
12
+ ### Defining conversations
13
+
14
+ A conversation can be defined inline or within a `ConversationRouter`.
15
+
16
+ A conversation wraps the message and is comprised of several handlers. Each `ConversationHandler` defines the intent as well as a callback that get's called when that intent is reached.
17
+
18
+ #### Defining conversations inline
19
+
20
+ ```ruby
21
+ Dialogue::ConversationTemplate.build(:order_shirt) do |conversation|
22
+ conversation.ask("What size do you wear?") do |response, conversation|
23
+ conversation.reply("Gotcha. Size #{response}. Noted.")
24
+ conversation.ask("What color would you like?") do |response, conversation|
25
+ conversation.reply("Great. I have you down for a #{response}.")
26
+ conversation.end("Thank you for your order.")
27
+ end
28
+ end
29
+ end.register
30
+ ```
31
+
32
+ You can `reply` to the conversation or `ask` the participant a question.
33
+
34
+ You can move onto a different conversation thread with a `diverge` followed by the name of the conversation.
35
+
36
+ ```
37
+ conversation.diverge :end_order
38
+ ```
39
+
40
+ You `start` a conversation which will store a `user`, a `channel`, and the conversation id. This is the placeholder for the conversation.
41
+
42
+ You can `end` a conversation which will clear the conversation from the storage mechanism.
43
+
44
+ A conversation can `timeout`.
45
+
46
+ #### Defining conversations within a router
47
+
48
+ ### Starting a conversation
49
+
50
+ A `message` comes in from somewhere and you can handle that message in a conversation. A `message` has a `user_id` and a `channel_id` along with some text. If the message matches one of the stored conversations (meaning the user id and channel id match), then the conversation is continued where it left off. If the conversation is not found, then a new conversation is started.
51
+
52
+ ```ruby
53
+ Dialogue.find_template(:select_size).start message
54
+ ```
55
+
56
+ ```ruby
57
+ Dialogue.handle(message) # Will find a template based on intent of the message
58
+ ```
59
+
60
+ This will register the conversation for the user and channel with the factory and activate the conversation.
61
+
62
+ ## TODO:
63
+
64
+ - [ ] Add DSL to `Dialogue` that allows you to specify templates with a name, a list of intents, and a template
65
+ - [ ] Implement `ConversationHandler` that handles a message based on an intent
66
+ - [ ] Add pluggable intent handlers (Api.ai, Wit.ai, etc)
67
+ - [ ] Implement `ConversationRouter`
68
+ - [ ] Add timeouts for conversations
69
+ - [ ] Add support for Facebook
70
+ - [ ] Add support for persistent conversations (serializable proc)
71
+
72
+ ## RELEASING A NEW GEM
73
+
74
+ 1. Bump the VERSION in `lib/dialogue/version.rb`
75
+ 1. Commit changes and push to GitHub
76
+ 1. run `bundle exec rake release`
77
+
78
+ ## LICENSE
79
+
80
+ Copyright (c) 2016, [Tatsu, Inc.](http://tatsu.io).
81
+
82
+ This project is licensed under the [MIT License](LICENSE.md).
@@ -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
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "dialogue/version"
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "dialogue"
8
+ spec.version = Dialogue::VERSION
9
+ spec.authors = ["Jamie Wright"]
10
+ spec.email = ["jamie@tastsu.io"]
11
+
12
+ spec.summary = %q{A DSL for defining conversations for Slack.}
13
+ spec.description = %q{Define and start conversations in Ruby for Slack bots.}
14
+ spec.homepage = "https://github.com/tatsuio/dialogue"
15
+ spec.license = "MIT"
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
18
+ spec.require_paths = ["lib"]
19
+
20
+ spec.add_dependency "slack-ruby-client"
21
+
22
+ spec.add_development_dependency "bundler"
23
+ spec.add_development_dependency "rake"
24
+ spec.add_development_dependency "rspec"
25
+ end
@@ -0,0 +1,77 @@
1
+ require "dialogue/conversation_factory"
2
+ require "dialogue/conversation_options"
3
+ require "dialogue/conversation_template"
4
+ require "dialogue/conversation_template_runner"
5
+ require "dialogue/conversation"
6
+ require "dialogue/conversation_handler"
7
+ require "dialogue/conversation_options_validator"
8
+ require "dialogue/invalid_options_error"
9
+ require "dialogue/dsl"
10
+ require "dialogue/message_decorators"
11
+ require "dialogue/storable"
12
+ require "dialogue/streams"
13
+ require "dialogue/template_already_registered_error"
14
+ require "dialogue/template_factory"
15
+ require "dialogue/version"
16
+
17
+ module Dialogue
18
+ class << self
19
+ def build(&block)
20
+ DSL.run block
21
+ end
22
+
23
+ def clear_conversations
24
+ conversation_factory.conversations.clear
25
+ end
26
+
27
+ def clear_templates
28
+ template_factory.templates.clear
29
+ end
30
+
31
+ def conversation_registered?(user_id, channel_id)
32
+ conversation_factory.registered? user_id, channel_id
33
+ end
34
+
35
+ def conversations
36
+ conversation_factory.conversations
37
+ end
38
+
39
+ def find_conversation(user_id, channel_id)
40
+ conversation_factory.find user_id, channel_id
41
+ end
42
+
43
+ def find_template(name)
44
+ template_factory.find name
45
+ end
46
+
47
+ def register_conversation(conversation)
48
+ conversation_factory.register conversation
49
+ end
50
+
51
+ def register_template(template)
52
+ template_factory.register template
53
+ end
54
+
55
+ def templates
56
+ template_factory.templates
57
+ end
58
+
59
+ def template_registered?(name)
60
+ template_factory.registered? name
61
+ end
62
+
63
+ def unregister_conversation(conversation)
64
+ conversation_factory.unregister(conversation)
65
+ end
66
+
67
+ private
68
+
69
+ def conversation_factory
70
+ ConversationFactory.instance
71
+ end
72
+
73
+ def template_factory
74
+ TemplateFactory.instance
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,75 @@
1
+ require "dialogue/storable"
2
+
3
+ module Dialogue
4
+ class Conversation
5
+ include ConversationOptions
6
+ include Storable
7
+
8
+ attr_accessor :channel_id, :team_id, :user_id
9
+ attr_reader :message, :steps, :templates
10
+
11
+ def initialize(template=nil, message=nil, options={})
12
+ guard_options! options
13
+
14
+ @templates = []
15
+ @steps = []
16
+
17
+ unless template.nil?
18
+ @templates = [template]
19
+ @steps << template.template
20
+ end
21
+
22
+ @message = message
23
+ unless @message.nil?
24
+ @channel_id = message.channel_id
25
+ @team_id = message.team_id
26
+ @user_id = message.user_id
27
+ end
28
+
29
+ @options = options.freeze
30
+ end
31
+
32
+ def ask(question, opts={}, &block)
33
+ say question, opts
34
+ steps << block
35
+ end
36
+
37
+ def diverge(template_name)
38
+ template = Dialogue.find_template template_name
39
+ unless template.nil?
40
+ templates << template
41
+ steps << template.template
42
+ perform
43
+ end
44
+ end
45
+
46
+ def end(statement=nil)
47
+ say statement unless statement.nil?
48
+ Dialogue.unregister_conversation self
49
+ end
50
+
51
+ def perform(*args)
52
+ step = steps.pop
53
+ step.call self, *args unless step.nil?
54
+ Dialogue.unregister_conversation self if steps.empty?
55
+ end
56
+ alias_method :continue, :perform
57
+
58
+ def say(statement, opts={})
59
+ ensure_registration
60
+ Dialogue::Streams::Slack.new(options[:access_token])
61
+ .puts statement, channel_id, user_id, opts
62
+ end
63
+ alias_method :reply, :say
64
+
65
+ private
66
+
67
+ def ensure_registration
68
+ # The conversation can be unregistered from a diverge, so let's ensure it
69
+ # is registered
70
+ if !Dialogue.conversation_registered? user_id, channel_id
71
+ Dialogue.register_conversation self
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,31 @@
1
+ require "singleton"
2
+
3
+ module Dialogue
4
+ class ConversationFactory
5
+ include Singleton
6
+
7
+ attr_reader :conversations
8
+
9
+ def initialize
10
+ @conversations = []
11
+ end
12
+
13
+ def find(user_id, channel_id)
14
+ conversations.find do |c|
15
+ c.user_id == user_id && c.channel_id == channel_id
16
+ end if !user_id.nil? && !channel_id.nil?
17
+ end
18
+
19
+ def register(conversation)
20
+ conversations << conversation unless registered?(conversation.user_id, conversation.channel_id)
21
+ end
22
+
23
+ def registered?(user_id, channel_id)
24
+ !find(user_id, channel_id).nil?
25
+ end
26
+
27
+ def unregister(conversation)
28
+ conversations.delete conversation
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,6 @@
1
+ module Dialogue
2
+ class ConversationHandler
3
+ def self.handle!(message)
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,17 @@
1
+ module Dialogue
2
+ module ConversationOptions
3
+ attr_reader :options
4
+
5
+ def method_missing(method, *args)
6
+ return options.fetch method if options.key? method
7
+ super
8
+ end
9
+
10
+ private
11
+
12
+ def guard_options!(options)
13
+ result = ConversationOptionsValidator.new.validate options
14
+ raise InvalidOptionsError.new(result.error_messages) unless result.success?
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,32 @@
1
+ module Dialogue
2
+ class ConversationOptionsValidator
3
+ VALID_OPTIONS = [:access_token, :author_id].freeze
4
+
5
+ def validate(options)
6
+ errors = []
7
+ options.keys.each do |key|
8
+ errors << "#{key} is not a valid option" unless VALID_OPTIONS.include?(key)
9
+ end
10
+
11
+ ValidationResult.new errors
12
+ end
13
+
14
+ private
15
+
16
+ class ValidationResult
17
+ attr_reader :errors
18
+
19
+ def initialize(errors)
20
+ @errors = errors.freeze
21
+ end
22
+
23
+ def error_messages
24
+ @errors.join(", ")
25
+ end
26
+
27
+ def success?
28
+ @errors.empty?
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,23 @@
1
+ module Dialogue
2
+ class ConversationTemplate
3
+ attr_reader :name, :template
4
+
5
+ def initialize(name=nil, &block)
6
+ @name = name
7
+ @template = block
8
+ end
9
+
10
+ def self.build(name, &block)
11
+ ConversationTemplate.new name, &block
12
+ end
13
+
14
+ def register
15
+ Dialogue.register_template self
16
+ self
17
+ end
18
+
19
+ def start(message, options={})
20
+ ConversationTemplateRunner.new(message, options).run self
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,44 @@
1
+ module Dialogue
2
+ class ConversationTemplateRunner
3
+ include ConversationOptions
4
+
5
+ attr_reader :message, :options
6
+
7
+ def initialize(message, options={})
8
+ guard_options! options
9
+
10
+ @message = message
11
+ @options = options.freeze
12
+ end
13
+
14
+ def channel_id
15
+ decorated_message.channel_id
16
+ end
17
+
18
+ def decorated_message
19
+ @decorated_message ||= MessageDecorators::Slack.new(message)
20
+ end
21
+
22
+ def message_from_author?
23
+ user_id == options[:author_id]
24
+ end
25
+
26
+ def run(template)
27
+ unless message_from_author?
28
+ if Dialogue.conversation_registered? user_id, channel_id
29
+ conversation = Dialogue.find_conversation user_id, channel_id
30
+ else
31
+ conversation = Conversation.new template, decorated_message, options
32
+
33
+ Dialogue.register_conversation conversation
34
+ end
35
+
36
+ conversation.perform decorated_message
37
+ end
38
+ end
39
+
40
+ def user_id
41
+ decorated_message.user_id
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,11 @@
1
+ module Dialogue
2
+ class DSL
3
+ def on(intent, &block)
4
+ #Dialogue.register_conversation(ConversationTemplate.new(intent))
5
+ end
6
+
7
+ def self.run(block)
8
+ new.instance_eval(&block)
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,4 @@
1
+ module Dialogue
2
+ class InvalidOptionsError < RuntimeError
3
+ end
4
+ end
@@ -0,0 +1 @@
1
+ require_relative "message_decorators/slack"
@@ -0,0 +1,24 @@
1
+ module Dialogue
2
+ module MessageDecorators
3
+ class Slack < SimpleDelegator
4
+ attr_reader :original_message
5
+
6
+ def initialize(message)
7
+ @original_message = message
8
+ __setobj__ @original_message
9
+ end
10
+
11
+ def channel_id
12
+ original_message.channel
13
+ end
14
+
15
+ def team_id
16
+ original_message.team || original_message.source_team
17
+ end
18
+
19
+ def user_id
20
+ original_message.user
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,15 @@
1
+ module Dialogue
2
+ module Storable
3
+ def data
4
+ @data ||= {}
5
+ end
6
+
7
+ def fetch(key, default=nil, &block)
8
+ data.fetch key, default, &block
9
+ end
10
+
11
+ def store!(hash)
12
+ data.merge! hash
13
+ end
14
+ end
15
+ end
@@ -0,0 +1 @@
1
+ require_relative "streams/slack"
@@ -0,0 +1,24 @@
1
+ require "slack-ruby-client"
2
+
3
+ module Dialogue
4
+ module Streams
5
+ class Slack
6
+ def initialize(access_token=nil)
7
+ @client = ::Slack::Web::Client.new(token: access_token)
8
+ end
9
+
10
+ def puts(output, channel_id, user_id, opts={})
11
+ options = { channel: channel_id, as_user: true }
12
+ text = output
13
+ text = text.insert 0, "<@#{user_id}> " if opts[:direct_mention]
14
+ options.merge!(text: text)
15
+ options.merge!(attachments: opts[:attachments]) if opts[:attachments]
16
+ client.chat_postMessage options
17
+ end
18
+
19
+ private
20
+
21
+ attr_reader :client
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,7 @@
1
+ module Dialogue
2
+ class TemplateAlreadyRegisteredError < RuntimeError
3
+ def initialize(template)
4
+ super "A template with the name #{template.name} has already been registered"
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,26 @@
1
+ require "singleton"
2
+
3
+ module Dialogue
4
+ class TemplateFactory
5
+ include Singleton
6
+
7
+ attr_reader :templates
8
+
9
+ def initialize
10
+ @templates = []
11
+ end
12
+
13
+ def find(name)
14
+ templates.find { |template| template.name.to_s == name.to_s }
15
+ end
16
+
17
+ def register(template)
18
+ raise TemplateAlreadyRegisteredError.new(template) if registered?(template.name)
19
+ templates << template
20
+ end
21
+
22
+ def registered?(name)
23
+ !find(name).nil?
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,3 @@
1
+ module Dialogue
2
+ VERSION = "0.0.1"
3
+ end
metadata ADDED
@@ -0,0 +1,126 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: dialogue
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Jamie Wright
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-03-22 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: slack-ruby-client
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
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
+ description: Define and start conversations in Ruby for Slack bots.
70
+ email:
71
+ - jamie@tastsu.io
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - ".rspec"
77
+ - CODE_OF_CONDUCT.md
78
+ - Gemfile
79
+ - Gemfile.lock
80
+ - LICENSE.md
81
+ - README.md
82
+ - Rakefile
83
+ - dialogue.gemspec
84
+ - lib/dialogue.rb
85
+ - lib/dialogue/conversation.rb
86
+ - lib/dialogue/conversation_factory.rb
87
+ - lib/dialogue/conversation_handler.rb
88
+ - lib/dialogue/conversation_options.rb
89
+ - lib/dialogue/conversation_options_validator.rb
90
+ - lib/dialogue/conversation_template.rb
91
+ - lib/dialogue/conversation_template_runner.rb
92
+ - lib/dialogue/dsl.rb
93
+ - lib/dialogue/invalid_options_error.rb
94
+ - lib/dialogue/message_decorators.rb
95
+ - lib/dialogue/message_decorators/slack.rb
96
+ - lib/dialogue/storable.rb
97
+ - lib/dialogue/streams.rb
98
+ - lib/dialogue/streams/slack.rb
99
+ - lib/dialogue/template_already_registered_error.rb
100
+ - lib/dialogue/template_factory.rb
101
+ - lib/dialogue/version.rb
102
+ homepage: https://github.com/tatsuio/dialogue
103
+ licenses:
104
+ - MIT
105
+ metadata: {}
106
+ post_install_message:
107
+ rdoc_options: []
108
+ require_paths:
109
+ - lib
110
+ required_ruby_version: !ruby/object:Gem::Requirement
111
+ requirements:
112
+ - - ">="
113
+ - !ruby/object:Gem::Version
114
+ version: '0'
115
+ required_rubygems_version: !ruby/object:Gem::Requirement
116
+ requirements:
117
+ - - ">="
118
+ - !ruby/object:Gem::Version
119
+ version: '0'
120
+ requirements: []
121
+ rubyforge_project:
122
+ rubygems_version: 2.5.1
123
+ signing_key:
124
+ specification_version: 4
125
+ summary: A DSL for defining conversations for Slack.
126
+ test_files: []