People,
I have a Java chatbot running my Fedora 25 x86_64 server and people can chat with it via FaceBook:
FB talks to the Ruby CGI script which communicates with the chatbot and I am thinking that I would convert this Ruby script to Kotlin as an exercise but also I would like to develop the resulting app as a general-purpose gateway for other social networks and then further develop it to act as dispatcher for NLP and AI modules. I attach the Ruby script below - could people comment on the degree of difficulty of conversion and whether it is even sensible to attempt it?
Thanks,
Phil.
#!/usr/bin/env ruby
require 'byebug'
require 'cgi'
require 'faraday'
require 'json'
require 'logger'
cgi = CGI.new
puts cgi.header
# system('gem install faraday > /dev/null 2>&1') # this is already installed
@logger = Logger.new('logs/fb_chatbot.log', 'monthly')
# There are 6 levels: Logger::DEBUG, Logger::INFO, Logger::WARN, Logger::Error, Logger::FATAL, and Logger::UNKOWN.
# @logger.level = Logger::DEBUG
@logger.level = Logger::INFO
@logger.debug( "Reached the CGI script!")
FB_ACCESS_TOKEN = 'xxx'
CHATBOT_HOST = 'localhost'
CHATBOT_PORT = 9192
@xmit = {
:commands => {
:users_name => '',
:users_lastname => '',
:users_fullname => '',
:name => ''
},
:topic_slug => 'phirhodev',
:session_id => '',
:message => ''
}
# byebug
def send_message_to_facebook(user_id, message)
json_data = {
recipient: {
id: user_id
},
message: {
text: message
}
}
url = 'https://graph.facebook.com/v2.6/me/messages?access_token=' + FB_ACCESS_TOKEN
conn = Faraday.new(url)
response =
conn.post do |req|
req.headers['Content-Type'] = 'application/json'
req.body = json_data.to_json
end
@logger.debug(user_id)
@logger.debug(JSON.parse(response.body))
response.status == 200
end
def send_indicator_to_facebook(user_id)
json_data = {
recipient: {
id: user_id
},
sender_action: 'typing_on'
}
url = 'https://graph.facebook.com/v2.6/me/messages?access_token=' + FB_ACCESS_TOKEN
conn = Faraday.new(url)
response =
conn.post do |req|
req.headers['Content-Type'] = 'application/json'
req.body = json_data.to_json
end
@logger.debug(user_id)
@logger.debug(JSON.parse(response.body))
response.status == 200
end
def load_facebook_profile_details(user_id)
# check for cached entry
profile_path = 'logs/' + user_id + '.json'
@logger.debug( 'Reached here ----------> 5a' )
if File.file? profile_path
data = JSON.parse(File.read(profile_path))
else
# fetch profile data
@logger.info('loading first time profile data')
url = 'https://graph.facebook.com/v2.6/' + user_id + '?fields=first_name,last_name,locale,timezone,gender&access_token=' + FB_ACCESS_TOKEN
response = Faraday.get(url)
data = JSON.parse(response.body)
@logger.debug(user_id)
@logger.debug(data)
return 0 if response.status != 200
File.open(profile_path, 'w') { |f| f.write(data.to_json) }
end
@xmit[:commands][:users_name] = data['first_name']
@xmit[:commands][:users_lastname] = data['last_name']
@xmit[:commands][:users_fullname] = data['first_name'] + ' ' + data['last_name']
@xmit[:commands][:name] = data['first_name']
return(1)
end
def send_message_to_bot(request)
# Prepare data
@xmit[:session_id] = '@@PHIRHOBOT_' + request['sender']['id']
@xmit[:message] = request['message']['text']
# Send request
unless TCPSocket.gethostbyname(CHATBOT_HOST)
@logger.debug('Hostname could not be resolved. Exiting')
return 0
end
@logger.debug(@xmit)
# @logger.debug(@xmit.to_json)
# @logger.debug(@xmit.to_s)
# @logger.debug(@xmit.to_json.to_s)
# @logger.debug(@xmit.to_s.to_json)
begin
client_socket = TCPSocket.open(CHATBOT_HOST, CHATBOT_PORT)
rescue
@logger.debug('Could not connect to chatbot')
return 0
end
client_socket.puts @xmit.to_json
data = ''
while true
buf = client_socket.recv(1024)
break if buf == ""
data += buf
end
client_socket.close
return data.sub(/\n@@END_OF_REPLY\n/, '')
end
resp_text = ''
# byebug
if cgi.params
@logger.debug( 'Reached here ----------> 1' )
fb_params = nil
fb_params = cgi.params.keys.first if cgi.params.is_a? Hash
# fb_params =
# {:entry => [
# {:messaging => [
# {:timestamp => 1494081902315,
# :message => {:text => 'test 1',
# :mid => 'mid.$cAALftLGKxSFiD33e61b3jiUhe4-x',
# :seq => 675},
# :recipient => {:id => '709466372544009'},
# :sender => {:id => '1270899366263587'}
# }],
# :id => '709466372544009',
# :time => 1494081902575}],
# :object => 'page'}
#
# fb_params = fb_params.to_json
fb_params = JSON.parse(fb_params) rescue nil
@logger.debug( fb_params )
@logger.debug( 'Reached here ----------> 2' )
if fb_params && fb_params['entry'] && fb_params['entry'].first && fb_params['entry'].first['messaging']
@logger.debug( 'Reached here ----------> 3' )
msg_data = fb_params['entry'].first['messaging'].first
@logger.info("Received message from user #{msg_data['sender']['id']}")
@logger.info(msg_data['message']['text'])
# Send processing/typing indicator to facebook
send_indicator_to_facebook(msg_data['sender']['id'])
@logger.debug( 'Reached here ----------> 4' )
# Load profile details for user id
load_facebook_profile_details(msg_data['sender']['id'])
@logger.debug( 'Reached here ----------> 5b' )
# Send request to chatbot
cb_response = send_message_to_bot(msg_data)
@logger.debug( 'Reached here ----------> 6' )
@logger.info('Chatbot response:')
@logger.info(cb_response)
cb_response ||= 'Error communicating with chatbot server!'
# Send chatbot response back to facebook
send_result = send_message_to_facebook(msg_data['sender']['id'], cb_response)
@logger.info('Failed to send reply to facebook api') unless send_result
elsif cgi.params['hub.verify_token'] == ['verify_206SouthDowlingSt']
resp_text = cgi.params['hub.challenge']
else
@logger.info('No valid request found')
end
end
puts resp_text