Class: Rebot::Conversation

Inherits:
Object
  • Object
show all
Defined in:
lib/rebot/conversation.rb

Constant Summary collapse

DEFAULT_TIMEOUT =

set default timeout to 180 seconds (3 minutes)

180
DEFAULT_TIMEOUT_MESSAGE =
"We can pick this up later."

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(bot, source_message) ⇒ Conversation

Returns a new instance of Conversation.



8
9
10
11
12
13
14
15
16
17
18
19
# File 'lib/rebot/conversation.rb', line 8

def initialize(bot, source_message)
  @bot            = bot
  @source_message = source_message
  @data           = {}
  @handlers_stack = [[]]
  @messages       = []
  @sent           = []
  @last_active_at = Time.now

  @timeout = DEFAULT_TIMEOUT
  @timeout_message = DEFAULT_TIMEOUT_MESSAGE
end

Instance Attribute Details

#dataObject (readonly)

Returns the value of attribute data.



6
7
8
# File 'lib/rebot/conversation.rb', line 6

def data
  @data
end

#source_messageObject (readonly)

Returns the value of attribute source_message.



6
7
8
# File 'lib/rebot/conversation.rb', line 6

def source_message
  @source_message
end

Instance Method Details

#active?Boolean

Returns:

  • (Boolean)


57
58
59
# File 'lib/rebot/conversation.rb', line 57

def active?
  @status == :active
end

#anythingObject



129
130
131
# File 'lib/rebot/conversation.rb', line 129

def anything
  /(.*)/i
end

#default(&callback) ⇒ Object



120
121
122
# File 'lib/rebot/conversation.rb', line 120

def default( &callback)
  hears(nil, { default: true }, &callback)
end

#handle(message) ⇒ Object



84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/rebot/conversation.rb', line 84

def handle(message)
  @last_active_at = Time.now
  Rebot.logger.debug "Handling message in conversation: #{message.text}"
  if option = matched_option(message.text)
    @handlers_stack.push([])
    if option[:default]
      instance_exec(message.text, &option[:callback])
    else
      instance_exec(*@last_matched_data.captures, &option[:callback])
    end
  else
    # FIXME
    say(@sent.last) if @messages.empty?
  end
end

#hears(pattern, meta = {}, &callback) ⇒ Object



109
110
111
112
113
114
# File 'lib/rebot/conversation.rb', line 109

def hears(pattern, meta = {}, &callback)
  pattern = Regexp.new(pattern) if pattern.is_a?(String)
  @handlers_stack.last.push(
    { pattern: pattern, callback: callback }.merge(meta)
  )
end

#matched_option(text) ⇒ Object



42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/rebot/conversation.rb', line 42

def matched_option(text)
  stack = @handlers_stack.last
  handler = stack.find do |o|
    if o[:pattern]
      @last_matched_data = o[:pattern].match(text)
    end
  end

  unless handler
    handler = stack.find { |o| o[:default] }
  end

  handler
end

#noObject



137
138
139
# File 'lib/rebot/conversation.rb', line 137

def no
  /^(no|nah|nope|n)/i
end

#repeatObject



116
117
118
# File 'lib/rebot/conversation.rb', line 116

def repeat
  @handlers_stack.pop
end

#say(message) ⇒ Object



100
101
102
103
104
105
106
107
# File 'lib/rebot/conversation.rb', line 100

def say(message)
  if message.is_a?(String)
    message =  { text: message, channel: @source_message.channel }
  else
    message[:channel] = @source_message.channel
  end
  @messages.push(message)
end

#start(block, *args) ⇒ Object



37
38
39
40
# File 'lib/rebot/conversation.rb', line 37

def start(block, *args)
  @status = :active
  instance_exec(*args, &block)
end

#tickObject



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/rebot/conversation.rb', line 61

def tick
  return unless active?

  if @messages.any?
    message = @messages.shift
    @bot.say(message)
    @sent.push(message)
    @last_active_at = Time.now
  end

  if @messages.empty? && @handlers_stack.last.empty?
    @status = :completed
    @bot.conversation_ended(self)
  end

  if Time.now - @last_active_at > timeout
    # TODO: keep it simple for now
    @status = :timeout
    @bot.say(text: timeout_message, channel: @source_message.channel)
    @bot.conversation_ended(self)
  end
end

#timeObject

extract into Conversation::Helpers



125
126
127
# File 'lib/rebot/conversation.rb', line 125

def time
  /\d{1,2}:\d{1,2}\s*(am|pm)/i
end

#timeout(value = nil) ⇒ Object



21
22
23
24
25
26
27
# File 'lib/rebot/conversation.rb', line 21

def timeout(value = nil)
  if value
    @timeout = value
  else
    @timeout
  end
end

#timeout_message(value = nil) ⇒ Object



29
30
31
32
33
34
35
# File 'lib/rebot/conversation.rb', line 29

def timeout_message(value = nil)
  if value
    @timeout_message = value
  else
    @timeout_message
  end
end

#yesObject



133
134
135
# File 'lib/rebot/conversation.rb', line 133

def yes
  /^(yes|yea|yup|yep|ya|sure|ok|y|yeah|yah)/i
end