277 lines
7.2 KiB
Ruby
277 lines
7.2 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
# Custom Commands: Add custom "echo" commands, to post a text message
|
|
#
|
|
# For example, "!hello" might print:
|
|
# "Welcome to the channel! You can follow [this link](link) to visit
|
|
# our website!"
|
|
require 'active_record'
|
|
require 'json'
|
|
|
|
module Chronicle
|
|
module Addon
|
|
# Custom Commander handles all custom command management
|
|
#
|
|
# @param bot [Chronicle] The instance of Chronicle for this addon
|
|
class CustomCommander
|
|
def self.register(bot)
|
|
addon_instance = new(bot)
|
|
addon_command = %w[addcommand modcommand remcommand]
|
|
|
|
[addon_instance, addon_command]
|
|
end
|
|
|
|
def initialize(bot)
|
|
@bot = bot
|
|
|
|
@bot.available_commands(self, list_commands)
|
|
end
|
|
|
|
# Provide help for the commands of this addon
|
|
#
|
|
# @param message [Message object] The relevant message object
|
|
def help_command(message)
|
|
pfx = @bot.cmd_prefix
|
|
cmd = message.content[:body].split(/\s+/)[1].gsub(/#{pfx}/, '')
|
|
|
|
case cmd
|
|
when 'addcommand'
|
|
cmd_add_usage
|
|
when 'modcommand'
|
|
cmd_mod_usage
|
|
when 'remcommand'
|
|
cmd_rem_usage
|
|
else
|
|
cmd_custom_usage(cmd)
|
|
end
|
|
end
|
|
|
|
# Handle a command from the Matrix protocol
|
|
#
|
|
# @param message [Message object] The relevant message object
|
|
def matrix_command(message)
|
|
pfx = @bot.cmd_prefix
|
|
roomid = message.room_id
|
|
cmd = message.content[:body].split(/\s+/)[0].gsub(/#{pfx}/, '')
|
|
msgstr = message.content[:body]
|
|
.gsub(/#{pfx}\w+\s*/, '')
|
|
.strip
|
|
|
|
res = case cmd
|
|
when 'addcommand'
|
|
handle_addcommand(roomid, msgstr)
|
|
when 'modcommand'
|
|
handle_modcommand(roomid, msgstr)
|
|
when 'remcommand'
|
|
handle_remcommand(roomid, msgstr)
|
|
else
|
|
handle_runcommand(roomid, cmd)
|
|
end
|
|
|
|
room = @bot.client.ensure_room(roomid)
|
|
|
|
room.send_notice(res)
|
|
end
|
|
|
|
# Adds a new custom command
|
|
#
|
|
# @param roomid [string] The Matrix Room ID
|
|
# @param message [String] The command plus response
|
|
# @return A response message
|
|
def handle_addcommand(roomid, message)
|
|
res = cmd_add_usage
|
|
|
|
if message.split(/\s+/).count > 1
|
|
command = message.slice!(/\w+\s+/).strip
|
|
|
|
res = save_command(roomid, command, message)
|
|
|
|
@bot.available_commands(self, [command])
|
|
end
|
|
|
|
res
|
|
end
|
|
|
|
# Modify an existing custom command
|
|
#
|
|
# @param roomid [string] The Matrix Room ID
|
|
# @param message [hash] The message data from Matrix
|
|
# @return A response message
|
|
def handle_modcommand(roomid, message)
|
|
res = cmd_add_usage
|
|
|
|
if message.split(/\s+/).count > 1
|
|
command = message.slice!(/\w+\s+/).strip
|
|
|
|
res = mod_command(roomid, command, message)
|
|
|
|
@bot.available_commands(self, [command])
|
|
end
|
|
|
|
res
|
|
end
|
|
|
|
# Remove an existing custom command
|
|
#
|
|
# @param roomid [string] The Matrix Room ID
|
|
# @param message [hash] The message data from Matrix
|
|
# @return A response message
|
|
def handle_remcommand(roomid, message)
|
|
res = cmd_rem_usage
|
|
|
|
if message.split(/\s+/).count == 1
|
|
command = message.strip
|
|
|
|
res = remove_command(roomid, command)
|
|
|
|
@bot.disable_commands(command)
|
|
end
|
|
|
|
res
|
|
end
|
|
|
|
# Return the response for a custom command
|
|
#
|
|
# @param roomid [string] The Matrix Room ID
|
|
# @param message [hash] The message data from Matrix
|
|
# @return A response message
|
|
def handle_runcommand(roomid, message)
|
|
res = cmd_rem_usage
|
|
|
|
res = CustomCommands.find_by(
|
|
roomid: roomid,
|
|
command: message.strip
|
|
).response
|
|
|
|
res
|
|
end
|
|
|
|
private
|
|
|
|
# Check if a custom command conflicts with an existing addon command
|
|
def addon_command(command)
|
|
@bot.all_commands.keys.include?(command)
|
|
end
|
|
|
|
# Help message for addcommand
|
|
def cmd_add_usage
|
|
'Add a custom command. '\
|
|
"\nUsage: !addcommand COMMAND TEXT"
|
|
end
|
|
|
|
# Help message for modcommand
|
|
def cmd_custom_usage(cmd)
|
|
'Prints text associated with the custom command'\
|
|
"\nUsage: !#{cmd}"
|
|
end
|
|
|
|
# Error message when trying to add an existing command
|
|
def cmd_addon_error
|
|
'This command is already used by another addon.'
|
|
end
|
|
|
|
# Error message when trying to modify a non-existing command
|
|
def cmd_mod_error(command)
|
|
'This custom command does not exist. '\
|
|
"You can add it by typing `!addcommand #{command}`"
|
|
end
|
|
|
|
# Help message for modcommand
|
|
def cmd_mod_usage
|
|
'Modify a custom command. '\
|
|
"\nUsage: !modcommand EXISTING-COMMAND TEXT"
|
|
end
|
|
|
|
# Error message when trying to delete a non-existing command
|
|
def cmd_rem_error
|
|
'This custom command does not exist. '\
|
|
'Nothing to remove.'
|
|
end
|
|
|
|
# Help message for modcommand
|
|
def cmd_rem_usage
|
|
'Remove a custom command. '\
|
|
"\nUsage: !remcommand EXISTING-COMMAND"
|
|
end
|
|
|
|
# List all available commands from the DB
|
|
def list_commands
|
|
commands = CustomCommands.select(:command).map do |c|
|
|
c.command
|
|
end
|
|
|
|
commands
|
|
end
|
|
|
|
# Modify an existing command in the DB
|
|
def mod_command(roomid, command, response)
|
|
res = "Command updated: !#{command}"
|
|
|
|
cc = CustomCommands.find_by(:command => command)
|
|
cc.response = response
|
|
|
|
unless cc.save
|
|
@bot.scribe.info('CustomCommander') {
|
|
"Problem modifying: #{command}. Not saved."
|
|
}
|
|
|
|
return cc.errors.objects.first.full_message
|
|
end
|
|
|
|
@bot.scribe.info('CustomCommander') {
|
|
"Custom command updated: #{command}"
|
|
}
|
|
|
|
res
|
|
end
|
|
|
|
# Remove an existing command from the DB
|
|
def remove_command(roomid, command)
|
|
res = "Command removed: !#{command}"
|
|
|
|
CustomCommands.find_by(
|
|
roomid: roomid,
|
|
command: command
|
|
).delete
|
|
|
|
res
|
|
end
|
|
|
|
# Save a new command to the DB
|
|
def save_command(roomid, command, response)
|
|
res = "Command saved: !#{command}"
|
|
|
|
cc = CustomCommands.new do |c|
|
|
c.roomid = roomid
|
|
c.command = command
|
|
c.response = response
|
|
end
|
|
|
|
unless cc.save
|
|
@bot.scribe.info('CustomCommander') {
|
|
"Duplicate command: #{command}. Not saved."
|
|
}
|
|
|
|
return cc.errors.objects.first.full_message
|
|
end
|
|
|
|
@bot.scribe.info('CustomCommander') {
|
|
"Custom command saved: #{command}"
|
|
}
|
|
|
|
res
|
|
end
|
|
end
|
|
|
|
# The ActiveRecord model for handling the custom commands
|
|
class CustomCommands < ActiveRecord::Base
|
|
validates_presence_of :roomid, :command, :response
|
|
validates_length_of :command, { minimum: 1 }
|
|
validates_length_of :response, { minimum: 1 }
|
|
|
|
validates :command, uniqueness: { message:
|
|
"already exists. You can modify it by typing `!modcommand %{value}`"
|
|
}
|
|
end
|
|
end
|
|
end
|