Rewrite phase 1

pull/1/head
Aaron Johnson 6 years ago
parent fc862ade07
commit 7e130f09e4

@ -0,0 +1,4 @@
def process_callback_zone(message)
host = message.data.split("|")[1]
send_message(message.message.chat.id, "You have selected #{host}!")
end

@ -25,13 +25,53 @@ def is_chat_authorized?(message, auth_chat)
end
end
def process_command_start(message, command, adm)
reply = "I am #{@botname}, and I am here to provide temperature information from various sensors. Currently I can retrieve information " +
"from temperature sensors as well as report when temperatures are out of a specified range.\n\n" +
"Commands available:\n/start (Shows this message)\n/check (Show temperatures, currently non-functional)\n/whoami or /chatinfo (Provides IDs for internal use)\n/whereareyou or /location (Provides hostname for bot server)\n\n" +
"Check again later to see if any new functions have been added, or use /patchnotes to learn about recent updates.\n" +
"You can also view the source code at the following location:\nhttps://git.skyfall.tech/skyfall/heatbot"
if message_from_admin?(message, adm)
msg_from_admin = true
end
if is_chat_authorized?(message, @auth_chat)
chat_authorized = true
end
if ! msg_from_admin && ! chat_authorized
if message.from.id == message.chat.id
reply = reply + "\n\nWARNING: I am not authorized to work with you directly. My functionality is limited."
else
reply = reply + "\n\nWARNING: I am not authorized to participate with this group. My functionality is limited."
end
elsif msg_from_admin && ! chat_authorized
reply = reply + "\n\nWARNING: Although you are an administrator, I have not been authorized to participate in this group. My functionality is limited."
end
send_message(message.chat.id, reply)
end
def process_command_patchnotes(message, command, adm)
if is_chat_authorized?(message, @auth_chat) || message_from_admin?(message, adm)
reply = `cat patchnotes.txt`
reply = File.read(static_text/patchnotes.txt)
else
reply = "I am not authorized to provide this information here."
end
return reply
send_message(message.chat.id, reply)
end
def process_command_location(message, command, adm)
if message_from_admin?(message, adm) || is_chat_authorized?(message, @auth_chat)
#reply = "I am currently located at:\n\nHost: \\\`#{`head -n1 /etc/hostname`}\\\`ExtIP: \\\`#{`curl icanhazip.com 2>/dev/null`}\\\`"
reply = "I am currently located at:\n\nHost: #{`head -n1 /etc/hostname`}ExtIP: #{`curl icanhazip.com 2>/dev/null`}"
else
reply = "I am not authorized to provide this information here."
end
#send_message_markdown(message.chat.id, reply)
send_message(message.chat.id, reply)
end
def process_command_chatinfo(message)
reply = "User ID: #{message.from.id}\nChat ID: #{message.chat.id}"
send_message(message.chat.id, reply)
end
def process_command_check(message, command, adm)
@ -39,12 +79,15 @@ def process_command_check(message, command, adm)
#begin interactive code
options = [ ]
@probes.each do |k,v|
button_text = v
options.insert(-1, Telegram::Bot::Types::InlineKeyboardButton.new(text: button_text, callback_data: "#{k}"))
puts " Option: #{k} is #{v["loc"].to_s}"
button_text = v["loc"].to_s
options.insert(-1, Telegram::Bot::Types::InlineKeyboardButton.new(text: button_text, callback_data: "ZONE|#{k}"))
end
message_text = "Which area would you like to check?\n"
send_question(message.chat.id, message_text, options)
#end interactive code
#probe = @probes[0] #set manually for now
reply = "N/A"
#hostdata = host_lookup(select_loc)
#puts "var:".blue+" hostdata".blue.bold+"::".bold + hostdata.to_s
#if ! hostdata.empty?
@ -56,11 +99,9 @@ def process_command_check(message, command, adm)
# reply = "No matching locations!"
# puts "hostdata is empty!"
#end
puts reply
else
reply = "I am not authorized to provide this information here."
send_message(message.chat.id,"I am not authorized to provide this information here.")
end
return reply
end
def process_command_test(message, command, adm)

235
run.rb

@ -6,6 +6,7 @@ require 'telegram/bot'
require 'pp'
require 'time'
require_relative 'commands.rb'
require_relative 'callbacks.rb'
require_relative 'colors.rb'
def timestamp
@ -16,7 +17,7 @@ end
@conf = YAML.load_file("bot_config.yaml")
@botname = @conf['botname']
@tmpdir = @conf['tmpdir']
token = @conf['token']
@token = @conf['token']
admin = @conf['admin']
@auth_chat = @conf['authorized_chats']
@allowed_sources = @conf['allowed_sources']
@ -27,9 +28,9 @@ STDOUT.sync = true
errcount = 0
puts "Checking if environment is sane...\n\n"
print "Checking bot token ...................... "
if token.nil?
if @token.nil?
print "FAIL!\n\n".red.bold
puts "No bot token defined in bot_config.yaml!\n" + "THIS IS REQUIRED!".red.bold + " Bot initialization failed; exiting..."
puts "No bot @token defined in bot_config.yaml!\n" + "THIS IS REQUIRED!".red.bold + " Bot initialization failed; exiting..."
exit(1)
else
print "OK\n".green.bold
@ -119,11 +120,22 @@ STDOUT.sync = false
puts "Starting [#{@botname}]...\n\n"
puts "Authorized administrator IDs: #{admin}"
puts "Authorized chat IDs: #{@auth_chat}"
puts "Bot token: #{token}"
puts "Bot @token: #{@token}"
puts "Temporary direcotry: #{@tmpdir}"
puts "Start time: " + timestamp + "\n\n\n\n"
STDOUT.flush
## Constant collection model (may be scrapped)
#last_collection = 0
#loop do
# collection_time = Time.now
# if collection_time - last_collection >= 10
# puts timestamp + ": [#{collection_time}] Updating records //Not really"
# last_collection = collection_time
# STDOUT.flush
# end
#end
def host_lookup(select_loc)
#@probes.select { |k,v| v['loc'] == select_loc }.each do |host,loc|
# return host
@ -131,21 +143,83 @@ def host_lookup(select_loc)
return @probes.select { |k,v| v['loc'] == select_loc }
end
def ack_callback(message, display_message = true)
#Delete message and notify user that we got the request
begin
Telegram::Bot::Client.run(@token) do |bot|
if display_message == true
bot.api.editMessageText(chat_id: message.message.chat.id, message_id: message.message.message_id, text: "#{message.from.username}Request received. Please wait...", reply_markup: "") #Removes buttons. Changes text
bot.api.answerCallbackQuery(callback_query_id: message.id, show_alert: false, text: "Request received. Please wait...") #Sends a pop-up notification
else
bot.api.deleteMessage(chat_id: message.message.chat.id, message_id: message.message.message_id) #Deletes message and buttons
end
end
rescue
puts "Error handling callback query. Error: " + $!.message
end
STDOUT.flush
end
def delete_message(message)
#Deletes a message referred to by message_id
begin
Telegram::Bot::Client.run(@token) do |bot|
bot.api.deleteMessage(chat_id: message.message.chat.id, message_id: message.message.message_id) #Deletes message and buttons
end
rescue
puts "Error deleting message. Error: " + $!.message
end
STDOUT.flush
end
def send_message(chatid, message_text, imageurl = nil)
if imageurl != nil
#Send message with text as html link to image
Telegram::Bot::Client.run(@token) {|bot| bot.api.send_message(chat_id: chatid, text: "#{message_text}<a href=\"#{imageurl}\">.</a>", parse_mode: "HTML") }
puts timestamp + ": Sent: #{message_text.inspect}\n\n"
else
#Send a plain-text message
Telegram::Bot::Client.run(@token) {|bot| bot.api.send_message(chat_id: chatid, text: message_text) }
puts timestamp + ": Sent: #{message_text.inspect}\n\n"
end
STDOUT.flush
end
def send_message_markdown(chatid, message_text)
#Send a plain-text message
Telegram::Bot::Client.run(@token) {|bot| bot.api.send_message(chat_id: chatid, text: "```#{message_text}```", parse_mode: 'Markdown') }
puts timestamp + ": Sent: #{message_text.inspect}\n\n"
STDOUT.flush
end
def send_question(chatid, question_text, answers = [ ])
if ! answers.empty? then
begin
keyboard = Telegram::Bot::Types::InlineKeyboardMarkup.new(inline_keyboard: answers)
Telegram::Bot::Client.run(@token) {|bot| bot.api.send_message(chat_id: chatid, text: question_text, reply_markup: keyboard) }
rescue
puts timestamp + ": " + "ERROR".red.bold + ": " + $!.message
end
else
puts timestamp + "send_question called without any possible answers provided"
end
STDOUT.flush
end
def handle_message(message)
if ! message.reply_to_message.nil? then
#drop message. Someone's replying to a message
#sent by our bot
#drop message. Someone's replying to a message sent by our bot
message.text = nil
return
end
if message.text.nil?
# Find out if user(s) joined the group. If so, welcome them
#if ! message.new_chat_members.nil?
# handle_user_join(message)
#else
# #Handle non-messages and non-joins here
#end
if ! message.new_chat_members.nil?
handle_user_join(message)
else
#Handle non-messages and non-joins here
end
return #so that we don't try to process this as a command (below)
end
@ -159,91 +233,108 @@ def handle_message(message)
#Format command
command = message.text.split(" ")[0].split("@")[0].downcase #Strip command from arguments and @tags
## Constant collection model (may be scrapped)
#last_collection = 0
#loop do
# collection_time = Time.now
# if collection_time - last_collection >= 10
# puts timestamp + ": [#{collection_time}] Updating records //Not really"
# last_collection = collection_time
# STDOUT.flush
# end
#end
reply = 'Empty String'
adm = @conf['admin']
puts Time.now.strftime("%F %H:%M:%S").yellow + ": Received command from " + "#{message.from.username}".cyan.bold + " [" + "#{message.from.id}".cyan + "]: " + "#{command}".magenta.bold
puts timestamp + ": Received command from " + "#{message.from.username}".cyan.bold + " [" + "#{message.from.id}".cyan + "]: " + "#{command}".magenta.bold
case command
when '/start'
reply = "I am #{@botname}, and I am here to provide temperature information from various sensors. Currently I can retrieve information " +
"from temperature sensors as well as report when temperatures are out of a specified range.\n\n" +
"Commands available:\n/start (Shows this message)\n/check (Show temperatures, currently non-functional)\n/whoami or /chatinfo (Provides IDs for internal use)\n/whereareyou or /location (Provides hostname for bot server)\n\n" +
"Check again later to see if any new functions have been added, or use /patchnotes to learn about recent updates.\n" +
"You can also view the source code at the following location:\nhttps://git.skyfall.tech/skyfall/heatbot"
if message_from_admin?(message, adm)
msg_from_admin = true
end
if is_chat_authorized?(message, @auth_chat)
chat_authorized = true
end
if ! msg_from_admin && ! chat_authorized
if message.from.id == message.chat.id
reply = reply + "\n\nWARNING: I am not authorized to work with you directly. My functionality is limited."
else
reply = reply + "\n\nWARNING: I am not authorized to participate with this group. My functionality is limited."
end
elsif msg_from_admin && ! chat_authorized
reply = reply + "\n\nWARNING: Although you are an administrator, I have not been authorized to participate in this group. My functionality is limited."
end
when '/patch', '/patchnotes'
reply = process_command_patchnotes(message, command, adm)
process_command_start(message, command, adm)
when '/patch', '/patchnotes', '/version', '/versioninfo'
process_command_patchnotes(message, command, adm)
when '/location', '/whereareyou'
if message_from_admin?(message, adm) || is_chat_authorized?(message, @auth_chat)
reply = "I am currently located at:\n\nHost: #{`head -n1 /etc/hostname`}ExtIP: #{`curl icanhazip.com 2>/dev/null`}"
else
reply = "I am not authorized to provide this information here."
end
process_command_location(message, command, adm)
when '/whoami', '/chatinfo'
reply = "User ID: #{message.from.id}\nChat ID: #{message.chat.id}"
process_command_chatinfo(message)
when '/check'
reply = process_command_check(message, command, adm)
process_command_check(message, command, adm)
when '/test'
reply = process_command_test(message, command, adm)
process_command_test(message, command, adm)
when '/pp', '/debug'
pp message
reply = "Confirmation: Message debug information sent to console."
send_message(message.chat.id"Confirmation: Message debug information sent to console.")
else
reply = "Sorry, #{command} is not a valid command."
send_message(message.chat.id,"Sorry, #{command} is not a valid command.")
end
rescue => e
handle_exception(e, message, true)
# Verbose output:
#print timestamp + ": Sending #{reply.inspect} ..... "
STDOUT.flush
return reply
end
Telegram::Bot::Client.run(token) do |bot|
def handle_callback_query(message)
#callbacks that start with a "!" ("!DMS|tt123456") can ONLY be submitted
#by an admin. Ignore if normal user presses
#Get "DLM" from "DLM|abc123"
command = message.data.split("|")[0].upcase
if command.start_with?('!') then
#verify an admin pressed this button
if ! message_from_admin?(message)
Telegram::Bot::Client.run(@token) {|bot| bot.api.answerCallbackQuery(callback_query_id: message.id, show_alert: false, text: "Requires admin approval")}
return
end
command = command.split("!")[1]
elsif command.start_with?('#') then
#is this an ignored command
return
end
ack_callback(message) #Change the movie/show selection message to "Request received..."
case command
when "ZONE" #Get temp info from location
process_callback_zone(message)
end
delete_message(message) #Delete the "Request received..." message
rescue => e
handle_exception(e, message, true)
end
def handle_exception(e, message, notify_users)
puts "=" * 60
puts "EXCEPTION OCCURRED!".red.bold
puts "=" * 60
puts "PRINTING INSPECT...".yellow.bold
puts e.inspect
puts "=" * 60
puts "PRINTING BACKTRACE...".yellow.bold
puts e.backtrace
puts "=" * 60
if notify_users == true then
#is this a callback query or a message
case message
when Telegram::Bot::Types::Message
send_message(message.chat.id, "I have run into an issue while processing a command.\n\nPlease notify an administrator.")
when Telegram::Bot::Types::CallbackQuery
send_message(message.message.chat.id, "I have run into an issue while processing a request.\n\nPlease notify an administrator.")
end
end
end
Telegram::Bot::Client.run(@token) do |bot|
bot.listen do |message|
#pp message
validation = validate_incoming_data(message)
#puts "DEBUG: #{validation}"
if validation
#reply = handle_message(message)
#case message
# when Telegram::Bot::Types::Message
reply = handle_message(message) #entrypoint for all messages
# when Telegram::Bot::Types::CallbackQuery
# reply = handle_callback_query(message) #entrypoint for all callback queries
#end
print timestamp + ": Sending ..... "
if ! message.text.nil?
bot.api.send_message(chat_id: message.chat.id, text: "#{reply}")
print "OK\n".green.bold
puts "Sent: #{reply.inspect}\n\n"
else
print 'FAIL'.red.bold
print " (Message is NULL)\n\n"
#Change message.from.username to something we can call the user. This makes referring to the user in replies much easier.
if ! message.from.username.nil? #Username -> @Username
#message.from.username = "@" + message.from.username
elsif ! message.from.first_name.nil? #Username -> John
message.from.username = message.from.first_name
end
case message
when Telegram::Bot::Types::Message
handle_message(message) #entrypoint for all messages
when Telegram::Bot::Types::CallbackQuery
handle_callback_query(message) #entrypoint for all callback queries
end
STDOUT.flush
else
puts "Received bad data! [#{message.chat.type}]"
puts validation

Loading…
Cancel
Save