Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implemented Session Buffer #8

Merged
merged 7 commits into from
Apr 26, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
#7 implemented a mvp buffer and add test plugin
  • Loading branch information
Simone Marzulli committed Apr 16, 2019
commit 5130fb8c309724b4fd7d5c12069abcac702c9410
63 changes: 28 additions & 35 deletions bot.rb
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
require 'json'
require 'logger'
require 'securerandom'
# remove pp
require 'pp'

logger = Logger.new("/tmp/joshua_bot_#{SecureRandom.hex(6)}.log")
logger = Logger.new(STDOUT)
# logger = Logger.new("/tmp/joshua_bot_#{SecureRandom.hex(6)}.log")

logger.info 'Reading bot configuration file...'

Expand Down Expand Up @@ -46,10 +49,6 @@
password_enabled = !bot_password.empty?
chat_id_authenticated = {}

# hash structure which contains user chat id and instance of the plugin
# which needs a reply from the user
waiting_input = {}

Telegram::Bot::Client.run(token) do |bot|
logger.info 'Bot started'

Expand Down Expand Up @@ -80,6 +79,24 @@
end
end

session_buffer = {
plugin: '',
is_open: false,
content: ''
}
buffer_file_name = "/tmp/joshua_#{message.chat.id}_buffer.json"

if File.file?(buffer_file_name)
logger.info "Reading the buffer already created in #{buffer_file_name}..."

buffer_file_content = File.read(buffer_file_name)
session_buffer = JSON.parse(buffer_file_content)
else
File.write(buffer_file_name, session_buffer.to_json)

logger.info "Created a new buffer file #{message.chat.id}"
end

bot_username = bot.api.getMe['result']['username']
logger.info "Now received: #{message.text}, from #{message.from.first_name}, in #{message.chat.id}"

Expand All @@ -95,23 +112,13 @@
plugin_name = plugin.class.name

begin
# check if a plugin is waiting for a user to give a reply
if waiting_input[message.chat.id].class.name == plugin_name
# restore old plugin instance to send reply to the user
old_plugin_instance = waiting_input[message.chat.id]
if session_buffer['is_open'] && session_buffer['plugin'] == plugin_name
logger.info "Writing message into buffer for plugin #{session_buffer['plugin']}..."

response = old_plugin_instance.do_answer(message.text)
session_buffer['content'] = message.text
session_buffer['is_open'] = false

# if plugin doesn't need further replies then stop the plugin
# from waiting new inputs
if response == AbsPlugin::STOP_REPLYING
waiting_input.delete(message.chat.id)
end

# if the current user has a plugin waiting for a reply skip
# the interpretation of other commands
elsif !waiting_input[message.chat.id].nil?
next
File.write(buffer_file_name, session_buffer.to_json)
elsif !message.text.nil?
# beautify message sent with @ format (used in groups)
if message.text.include? "@#{bot_username}"
Expand All @@ -121,13 +128,7 @@
if plugin.command.match(message.text)
# send the match result to do_stuff method if it needs to
# do something with a particular command requiring arguments
response = plugin.do_stuff(Regexp.last_match)

# if plugin needs a reply then store user chat id and plugin
# instance inside a hash structure
if response == AbsPlugin::MUST_REPLY
waiting_input[message.chat.id] = plugin
end
plugin.do_stuff(Regexp.last_match)

# if the plugin main regexp does't match the message
# then show the plugin usage example
Expand All @@ -137,10 +138,6 @@
end
rescue NotImplementedError
bot.api.sendMessage(chat_id: message.chat.id, text: "☢️ #{plugin_name} plugin is not behaving correctly! ☢️")

# in case a do_answer wasn't implemented for the plugin
# remove the user from the waiting input list
waiting_input.delete(message.chat.id)
rescue => e
logger.error "Cannot execute plugin #{plugin_name}, check if there are tools missing or wild error: #{e.message}"
bot.api.sendMessage(chat_id: message.chat.id, text: "🚫 #{plugin_name} plugin is not working properly on my brain operating system! 🚫")
Expand Down Expand Up @@ -171,10 +168,6 @@
FOO
bot.api.sendMessage(chat_id: message.chat.id, text: text_value)
when '/stop', "/stop@#{bot_username}"
# remove user from the waiting input list and remove custom keyboard
# if it was previously enabled by some plugin

waiting_input.delete(message.chat.id)
kb = Telegram::Bot::Types::ReplyKeyboardRemove.new(remove_keyboard: true)
bot.api.sendMessage(chat_id: message.chat.id, text: 'A strange game. The only winning move is not to play. How about a nice game of chess?', reply_markup: kb)
end
Expand Down
9 changes: 0 additions & 9 deletions lib/abs_plugin.rb
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
require 'telegram/bot'

class AbsPlugin
MUST_REPLY = 'MUST_REPLY'.freeze
STOP_REPLYING = 'STOP_REPLYING'.freeze

attr_accessor :bot, :message

# the following two methods will be used to know the plugins name which
Expand Down Expand Up @@ -34,10 +31,4 @@ def do_stuff(_match_results)

raise NotImplementedError, 'You must implement do_stuff method'
end

def do_answer(_answer)
# if plugin needs answer from user, code must be placed here

raise NotImplementedError, 'You must implement do_answer method'
end
end
60 changes: 60 additions & 0 deletions lib/plugins/test/buffero.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
require 'JSON'

class Buffero < AbsPlugin
def command
/\/buffero$/
end

def show_usage
bot.api.sendMessage(chat_id: message.chat.id, text: '/buffero')
end

def do_stuff(match_results)
bot.api.sendMessage(chat_id: message.chat.id, text: 'Enter first number: ')
first = read_buffer
bot.api.sendMessage(chat_id: message.chat.id, text: 'Enter second number: ')
second = read_buffer

bot.api.sendMessage(chat_id: message.chat.id, text: "Result is #{first.to_i + second.to_i}")
end

def read_buffer()
buffer_file_name = "/tmp/joshua_#{message.chat.id}_buffer.json"

# open the buffer in order to wait for input from users

session_buffer = {
plugin: self.class,
is_open: true,
content: ''
}

File.write(buffer_file_name, session_buffer.to_json)

# read the buffer until it's closed

loop do
puts 'waiting for user to reply...'

buffer_file_content = File.read(buffer_file_name)

session_buffer = JSON.parse(buffer_file_content)

unless session_buffer['is_open']
puts 'buffer is now closed returning the content:'
puts session_buffer['content']
break
end

sleep(0.5)
end

File.write(buffer_file_name, {
plugin: '',
is_open: false,
content: ''
}.to_json)

session_buffer['content']
end
end