parent
3b84c6976a
commit
bae69e99ca
@ -0,0 +1,3 @@
|
||||
/bot_config.yaml
|
||||
/.ignore
|
||||
|
@ -0,0 +1,12 @@
|
||||
botname: 'Bob'
|
||||
tmpdir: '/tmp/.skyfall/heatbot'
|
||||
token: '<your-bot-token>'
|
||||
admin:
|
||||
- 11111111
|
||||
authorized_chats:
|
||||
- 11111111
|
||||
allowed_sources:
|
||||
- 'private'
|
||||
- 'group'
|
||||
- 'supergroup'
|
||||
|
@ -0,0 +1,28 @@
|
||||
class String
|
||||
def black; "\e[30m#{self}\e[0m" end
|
||||
def red; "\e[31m#{self}\e[0m" end
|
||||
def green; "\e[32m#{self}\e[0m" end
|
||||
def yellow; "\e[33m#{self}\e[0m" end
|
||||
def brown; "\e[33m#{self}\e[0m" end
|
||||
def blue; "\e[34m#{self}\e[0m" end
|
||||
def magenta; "\e[35m#{self}\e[0m" end
|
||||
def cyan; "\e[36m#{self}\e[0m" end
|
||||
def gray; "\e[37m#{self}\e[0m" end
|
||||
|
||||
def bg_black; "\e[40m#{self}\e[0m" end
|
||||
def bg_red; "\e[41m#{self}\e[0m" end
|
||||
def bg_green; "\e[42m#{self}\e[0m" end
|
||||
def bg_yellow; "\e[43m#{self}\e[0m" end
|
||||
def bg_brown; "\e[43m#{self}\e[0m" end
|
||||
def bg_blue; "\e[44m#{self}\e[0m" end
|
||||
def bg_magenta; "\e[45m#{self}\e[0m" end
|
||||
def bg_cyan; "\e[46m#{self}\e[0m" end
|
||||
def bg_gray; "\e[47m#{self}\e[0m" end
|
||||
|
||||
def bold; "\e[1m#{self}\e[22m" end
|
||||
def italic; "\e[3m#{self}\e[23m" end
|
||||
def underline; "\e[4m#{self}\e[24m" end
|
||||
def blink; "\e[5m#{self}\e[25m" end
|
||||
def reverse_color; "\e[7m#{self}\e[27m" end
|
||||
end
|
||||
|
@ -0,0 +1,45 @@
|
||||
def validate_incoming_data(message)
|
||||
auth_chat = @conf['auth_chat']
|
||||
message = message.message if message.is_a? Telegram::Bot::Types::CallbackQuery
|
||||
return "Received message is not from a valid source! Type: \"#{message.chat.type}\". Ignoring." if ! @allowed_sources.include?(message.chat.type)
|
||||
return true
|
||||
end
|
||||
|
||||
def message_from_admin?(message, adm)
|
||||
if adm.include?(message.from.id)
|
||||
puts "Command is from an admin. [" + "#{message.from.username}".green.bold + "]"
|
||||
return true
|
||||
else
|
||||
puts "Command is NOT from an admin! [" + "#{message.from.username}".yellow.bold + "]"
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
def is_chat_authorized?(message, auth_chat)
|
||||
if auth_chat.include?(message.chat.id)
|
||||
puts "Group [" + "#{message.chat.id}".green.bold + "][" + "#{message.chat.title}".green + "] is authorized"
|
||||
return true
|
||||
else
|
||||
puts "Group [" + "#{message.chat.id}".red.bold + "][" + "#{message.chat.title}".red + "] is NOT authorized!"
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
def process_command_patchnotes(message, command, adm)
|
||||
if is_chat_authorized?(message, @auth_chat) || message_from_admin?(message, adm)
|
||||
reply = `cat patchnotes.txt`
|
||||
else
|
||||
reply = "I am not authorized to provide this information here."
|
||||
end
|
||||
return reply
|
||||
end
|
||||
|
||||
def process_command_check(message, command, adm)
|
||||
if is_chat_authorized?(message, @auth_chat) || message_from_admin?(message, adm)
|
||||
reply = `cat fakeoutput.txt`
|
||||
else
|
||||
reply = "I am not authorized to provide this information here."
|
||||
end
|
||||
return reply
|
||||
end
|
||||
|
@ -0,0 +1,18 @@
|
||||
[Unit]
|
||||
Description=Temperature Checking and Alert Bot by SKYFALL
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
User=ivo
|
||||
WorkingDirectory=/opt/skyfall/heatbot
|
||||
# Uncomment these for logging to flat files instead of journald
|
||||
#StandardOutput=file:/var/log/skyfall/heatbot/run.log
|
||||
#StandardError=file:/var/log/skyfall/heatbot/error.log
|
||||
PIDFile=/var/run/skyfall/heatbot.pid
|
||||
ExecStart=/usr/bin/ruby /opt/skyfall/heatbot/run.rb
|
||||
SuccessExitStatus=SIGKILL
|
||||
Restart=on-failure
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
@ -0,0 +1,5 @@
|
||||
Living Room: 68F
|
||||
Basement: 66F
|
||||
Server Room: 74F
|
||||
Sun (Surface): 9941F
|
||||
Sun (Corona): 6800000F
|
@ -0,0 +1,5 @@
|
||||
SkyfallTech HeatBot
|
||||
Patch Notes:
|
||||
|
||||
v0.1.00
|
||||
+ Starting from a fork of the Skyfall EGS-Bot v0.4.00
|
@ -0,0 +1,212 @@
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
require 'rubygems'
|
||||
require 'yaml'
|
||||
require 'telegram/bot'
|
||||
require 'pp'
|
||||
require 'time'
|
||||
require_relative 'commands.rb'
|
||||
require_relative 'colors.rb'
|
||||
|
||||
def timestamp
|
||||
Time.now.strftime("%F %H:%M:%S").yellow
|
||||
end
|
||||
|
||||
#conf = YAML.load(File.read("bot_config.yaml"))
|
||||
@conf = YAML.load_file("bot_config.yaml")
|
||||
@botname = @conf['botname']
|
||||
@tmpdir = @conf['tmpdir']
|
||||
token = @conf['token']
|
||||
admin = @conf['admin']
|
||||
@auth_chat = @conf['authorized_chats']
|
||||
@allowed_sources = @conf['allowed_sources']
|
||||
|
||||
### Begin sanity check ###
|
||||
STDOUT.sync = true
|
||||
errcount = 0
|
||||
puts "Checking if environment is sane...\n\n"
|
||||
print "Checking bot token ...................... "
|
||||
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..."
|
||||
exit(1)
|
||||
else
|
||||
print "OK\n".green.bold
|
||||
end
|
||||
print "Checking configured bot name ............ "
|
||||
if @botname.nil?
|
||||
errcount += 1
|
||||
print "FAIL!\n\n".red.bold
|
||||
puts "Error(#{errcount.to_s}): No bot name defined. This is superficial. We'll call him Bob.\n\n"
|
||||
@botname = "Bob"
|
||||
else
|
||||
print "OK\n".green.bold
|
||||
end
|
||||
### Temporary directory check
|
||||
print "Checking configured tmp directory ....... "
|
||||
def is_tmp_writable?
|
||||
system("mkdir -p #{@tmpdir} >/dev/null 2>&1")
|
||||
if system("touch #{@tmpdir}/test.file >/dev/null 2>&1")
|
||||
system("rm #{@tmpdir}/test.file >/dev/null 2>&1")
|
||||
return true
|
||||
else
|
||||
system("rm #{@tmpdir}/test.file >/dev/null 2>&1") #Attempt to clean up anyway
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
if @tmpdir.nil?
|
||||
errcount += 1
|
||||
print "FAIL!\n\n".red.bold
|
||||
puts "Error(#{errcount.to_s}): No temporary directory defined. Using '/tmp/.skyfall/egs-bot'.\n"
|
||||
@tmpdir = "/tmp/.skyfall/egs-bot"
|
||||
if is_tmp_writable?
|
||||
puts "Default temporary directory is writable. Continuing...\n\n"
|
||||
else
|
||||
errcount += 1
|
||||
puts "Error(#{errcount.to_s}): Temporary directory [" + @tmpdir.red.bold + "] is not writable!\n" + "THIS IS REQUIRED!".red.bold + " Bot initialization failed; exiting..."
|
||||
exit(1)
|
||||
end
|
||||
else
|
||||
if is_tmp_writable?
|
||||
print "OK\n".green.bold
|
||||
else
|
||||
errcount += 1
|
||||
print "FAIL!\n\n".red.bold
|
||||
puts "Error(#{errcount.to_s}): Temporary directory [" + @tmpdir.red.bold + "] is not writable!\n" + "THIS IS REQUIRED!".red.bold + " Bot initialization failed; exiting..."
|
||||
exit(1)
|
||||
end
|
||||
end
|
||||
### End tmpdir check
|
||||
print "Checking administrators ................. "
|
||||
if admin.nil?
|
||||
errcount += 1
|
||||
print "FAIL!\n\n".red.bold
|
||||
puts "Error(#{errcount.to_s}): No admin Telegram IDs provided in bot_config.yaml.\nThis is required for many functions.\n" +
|
||||
"THIS SHOULD BE ADDRESSED. Continuing. (some commands will not be available)\n\n"
|
||||
admin = ["0"]
|
||||
else
|
||||
print "OK\n".green.bold
|
||||
end
|
||||
print "Checking authorized chats ............... "
|
||||
if @auth_chat.nil?
|
||||
errcount += 1
|
||||
print "FAIL!\n\n".red.bold
|
||||
puts "Error(#{errcount.to_s}): No authorized Telegram group IDs provided in bot_config.yaml.\nThis is required for most Empyrion-related " +
|
||||
"functions.\nTHIS SHOULD BE ADDRESSED. Continuing. (some commands will not be available)\n\n"
|
||||
@auth_chat = ["0"]
|
||||
else
|
||||
print "OK\n".green.bold
|
||||
end
|
||||
puts "Errors found: #{errcount.to_s}\n\n"
|
||||
if errcount > 0
|
||||
print "Environment is grinning and holding a spatula. Please review your configuration.\n\n".red.bold
|
||||
else
|
||||
print "Environment appears sane.\n\n".green.bold
|
||||
end
|
||||
STDOUT.sync = false
|
||||
### End sanity check ###
|
||||
puts "Starting [#{@botname}]...\n\n"
|
||||
puts "Authorized administrator IDs: #{admin}"
|
||||
puts "Authorized chat IDs: #{@auth_chat}"
|
||||
puts "Bot token: #{token}"
|
||||
puts "Temporary direcotry: #{@tmpdir}"
|
||||
puts "Start time: " + timestamp + "\n\n\n\n"
|
||||
STDOUT.flush
|
||||
|
||||
def handle_message(message)
|
||||
if ! message.reply_to_message.nil? then
|
||||
#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
|
||||
return #so that we don't try to process this as a command (below)
|
||||
end
|
||||
|
||||
#Format sender name
|
||||
if ! message.from.username.nil?
|
||||
message.from.username = "@" + message.from.username
|
||||
elsif ! message.from.first_name.nil?
|
||||
message.from.username = message.from.first_name
|
||||
end
|
||||
|
||||
#Format command
|
||||
command = message.text.split(" ")[0].split("@")[0].downcase #Strip command from arguments and @tags
|
||||
|
||||
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
|
||||
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)
|
||||
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
|
||||
when '/whoami', '/chatinfo'
|
||||
reply = "User ID: #{message.from.id}\nChat ID: #{message.chat.id}"
|
||||
when '/check'
|
||||
reply = process_command_check(message, command, adm)
|
||||
when '/pp', '/debug'
|
||||
pp message
|
||||
reply = "Confirmation: Message debug information sent to console."
|
||||
else
|
||||
reply = "Sorry, #{command} is not a valid command."
|
||||
end
|
||||
# Verbose output:
|
||||
puts timestamp + ": Sending #{reply.inspect}\n\n"
|
||||
STDOUT.flush
|
||||
return reply
|
||||
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)
|
||||
if ! message.text.nil?
|
||||
bot.api.send_message(chat_id: message.chat.id, text: "#{reply}")
|
||||
end
|
||||
STDOUT.flush
|
||||
else
|
||||
puts "Received bad data! [#{message.chat.type}]"
|
||||
puts validation
|
||||
STDOUT.flush
|
||||
end
|
||||
end
|
||||
end
|
||||
|
Loading…
Reference in new issue