slack-smart-bot 0.9.6 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +5 -1
  3. data/README.md +80 -175
  4. data/lib/slack-smart-bot.rb +95 -1276
  5. data/lib/slack-smart-bot_rules.rb +50 -69
  6. data/lib/slack/smart-bot/comm.rb +197 -0
  7. data/lib/slack/smart-bot/commands/general/bot_help.rb +74 -0
  8. data/lib/slack/smart-bot/commands/general/bot_status.rb +41 -0
  9. data/lib/slack/smart-bot/commands/general/bye_bot.rb +17 -0
  10. data/lib/slack/smart-bot/commands/general/hi_bot.rb +24 -0
  11. data/lib/slack/smart-bot/commands/general/stop_using_rules.rb +44 -0
  12. data/lib/slack/smart-bot/commands/general/use_rules.rb +48 -0
  13. data/lib/slack/smart-bot/commands/on_bot/add_shortcut.rb +64 -0
  14. data/lib/slack/smart-bot/commands/on_bot/admin/add_routine.rb +87 -0
  15. data/lib/slack/smart-bot/commands/on_bot/admin/extend_rules.rb +63 -0
  16. data/lib/slack/smart-bot/commands/on_bot/admin/pause_bot.rb +21 -0
  17. data/lib/slack/smart-bot/commands/on_bot/admin/pause_routine.rb +26 -0
  18. data/lib/slack/smart-bot/commands/on_bot/admin/remove_routine.rb +28 -0
  19. data/lib/slack/smart-bot/commands/on_bot/admin/run_routine.rb +53 -0
  20. data/lib/slack/smart-bot/commands/on_bot/admin/see_routines.rb +57 -0
  21. data/lib/slack/smart-bot/commands/on_bot/admin/start_bot.rb +20 -0
  22. data/lib/slack/smart-bot/commands/on_bot/admin/start_routine.rb +27 -0
  23. data/lib/slack/smart-bot/commands/on_bot/admin/stop_using_rules_on.rb +30 -0
  24. data/lib/slack/smart-bot/commands/on_bot/delete_shortcut.rb +41 -0
  25. data/lib/slack/smart-bot/commands/on_bot/ruby_code.rb +48 -0
  26. data/lib/slack/smart-bot/commands/on_bot/see_shortcuts.rb +32 -0
  27. data/lib/slack/smart-bot/commands/on_extended/bot_rules.rb +37 -0
  28. data/lib/slack/smart-bot/commands/on_master/admin/kill_bot_on_channel.rb +38 -0
  29. data/lib/slack/smart-bot/commands/on_master/admin_master/exit_bot.rb +42 -0
  30. data/lib/slack/smart-bot/commands/on_master/admin_master/notify_message.rb +35 -0
  31. data/lib/slack/smart-bot/commands/on_master/create_bot.rb +94 -0
  32. data/lib/slack/smart-bot/listen.rb +36 -0
  33. data/lib/slack/smart-bot/process.rb +169 -0
  34. data/lib/slack/smart-bot/process_first.rb +201 -0
  35. data/lib/slack/smart-bot/treat_message.rb +139 -0
  36. data/lib/slack/smart-bot/utils.rb +299 -0
  37. metadata +71 -5
@@ -0,0 +1,35 @@
1
+ class SlackSmartBot
2
+ # helpmaster: ----------------------------------------------
3
+ # helpmaster: `notify MESSAGE`
4
+ # helpmaster: `notify all MESSAGE`
5
+ # helpmaster: `notify #CHANNEL_NAME MESSAGE`
6
+ # helpmaster: It will send a notification message to all bot channels
7
+ # helpmaster: It will send a notification message to all channels the bot joined and private conversations with the bot
8
+ # helpmaster: It will send a notification message to the specified channel and to its extended channels
9
+ # helpmaster: Only works if you are on Master channel and you are a master admin user
10
+ # helpmaster:
11
+ def notify_message(dest, from, where, message)
12
+ if ON_MASTER_BOT
13
+ if ADMIN_USERS.include?(from) #admin user
14
+ if where.nil? #not all and not channel
15
+ @bots_created.each do |k, v|
16
+ respond message, k
17
+ end
18
+ respond "Bot channels have been notified", dest
19
+ elsif where == "all" #all
20
+ myconv = client.web_client.users_conversations(exclude_archived: true, limit: 100, types: "im, public_channel,private_channel").channels
21
+ myconv.each do |c|
22
+ respond message, c.id unless c.name == MASTER_CHANNEL
23
+ end
24
+ respond "Channels and users have been notified", dest
25
+ else #channel
26
+ respond message, where
27
+ @bots_created[where][:extended].each do |ch|
28
+ respond message, @channels_id[ch]
29
+ end
30
+ respond "Bot channel and extended channels have been notified", dest
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,94 @@
1
+ class SlackSmartBot
2
+ # helpmaster: ----------------------------------------------
3
+ # helpmaster: `create bot on CHANNEL_NAME`
4
+ # helpmaster: `create cloud bot on CHANNEL_NAME`
5
+ # helpmaster: creates a new bot on the channel specified
6
+ # helpmaster: it will work only if you are on Master channel
7
+ # helpmaster: the admins will be the master admins, the creator of the bot and the creator of the channel
8
+ # helpmaster: follow the instructions in case creating cloud bots
9
+ # helpmaster:
10
+ def create_bot(dest, from, cloud, channel)
11
+ if ON_MASTER_BOT
12
+ get_channels_name_and_id() unless @channels_name.keys.include?(channel) or @channels_id.keys.include?(channel)
13
+ channel_id = nil
14
+ if @channels_name.key?(channel) #it is an id
15
+ channel_id = channel
16
+ channel = @channels_name[channel_id]
17
+ elsif @channels_id.key?(channel) #it is a channel name
18
+ channel_id = @channels_id[channel]
19
+ end
20
+ #todo: add pagination for case more than 1000 channels on the workspace
21
+ channels = client.web_client.conversations_list(
22
+ types: "private_channel,public_channel",
23
+ limit: "1000",
24
+ exclude_archived: "true",
25
+ ).channels
26
+ channel_found = channels.detect { |c| c.name == channel }
27
+ members = client.web_client.conversations_members(channel: @channels_id[channel]).members unless channel_found.nil?
28
+
29
+ if channel_id.nil?
30
+ respond "There is no channel with that name: #{channel}, please be sure is written exactly the same", dest
31
+ elsif channel == MASTER_CHANNEL
32
+ respond "There is already a bot in this channel: #{channel}", dest
33
+ elsif @bots_created.keys.include?(channel_id)
34
+ respond "There is already a bot in this channel: #{channel}, kill it before", dest
35
+ elsif config[:nick_id] != channel_found.creator and !members.include?(config[:nick_id])
36
+ respond "You need to add first to the channel the smart bot user: #{config[:nick]}", dest
37
+ else
38
+ if channel_id != config[:channel]
39
+ begin
40
+ rules_file = "slack-smart-bot_rules_#{channel_id}_#{from.gsub(" ", "_")}.rb"
41
+ if defined?(RULES_FOLDER)
42
+ rules_file = RULES_FOLDER + rules_file
43
+ else
44
+ Dir.mkdir("rules") unless Dir.exist?("rules")
45
+ Dir.mkdir("rules/#{channel_id}") unless Dir.exist?("rules/#{channel_id}")
46
+ rules_file = "./rules/#{channel_id}/" + rules_file
47
+ end
48
+ default_rules = (__FILE__).gsub(/slack\/smart-bot\/commands\/on_master\/create_bot\.rb$/, "slack-smart-bot_rules.rb")
49
+ File.delete(rules_file) if File.exist?(rules_file)
50
+ FileUtils.copy_file(default_rules, rules_file) unless File.exist?(rules_file)
51
+ admin_users = Array.new()
52
+ creator_info = client.web_client.users_info(user: channel_found.creator)
53
+ admin_users = [from, creator_info.user.name] + MASTER_USERS
54
+ admin_users.uniq!
55
+ @logger.info "ruby #{$0} \"#{channel}\" \"#{admin_users.join(",")}\" \"#{rules_file}\" on"
56
+
57
+ if cloud
58
+ respond "Copy the bot folder to your cloud location and run `ruby #{$0} \"#{channel}\" \"#{admin_users.join(",")}\" \"#{rules_file}\" on&`", dest
59
+ else
60
+ t = Thread.new do
61
+ `ruby #{$0} \"#{channel}\" \"#{admin_users.join(",")}\" \"#{rules_file}\" on`
62
+ end
63
+ end
64
+ @bots_created[channel_id] = {
65
+ creator_name: from,
66
+ channel_id: channel_id,
67
+ channel_name: @channels_name[channel_id],
68
+ status: :on,
69
+ created: Time.now.strftime("%Y-%m-%dT%H:%M:%S.000Z")[0..18],
70
+ rules_file: rules_file,
71
+ admins: admin_users.join(","),
72
+ extended: [],
73
+ cloud: cloud,
74
+ thread: t,
75
+ }
76
+ respond "The bot has been created on channel: #{channel}. Rules file: #{File.basename rules_file}. Admins: #{admin_users.join(", ")}", dest
77
+ update_bots_file()
78
+ rescue Exception => stack
79
+ @logger.fatal stack
80
+ message = "Problem creating the bot on channel #{channel}. Error: <#{stack}>."
81
+ @logger.error message
82
+ respond message, dest
83
+ end
84
+ else
85
+ respond "There is already a bot in this channel: #{channel}, and it is the Master Channel!", dest
86
+ end
87
+ end
88
+ else
89
+ @logger.info MASTER_CHANNEL
90
+ @logger.info @channel_id.inspect
91
+ respond "Sorry I cannot create bots from this channel, please visit the master channel: <##{@master_bot_id}>", dest
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,36 @@
1
+ class SlackSmartBot
2
+ def listen
3
+ @salutations = [config[:nick], "<@#{config[:nick_id]}>", "bot", "smart"]
4
+ @pings = []
5
+ get_bots_created()
6
+ client.on :message do |data|
7
+ unless data.user == "USLACKBOT"
8
+ treat_message(data)
9
+ end
10
+ end
11
+
12
+ restarts = 0
13
+ started = false
14
+ while restarts < 200 and !started
15
+ begin
16
+ @logger.info "Bot starting: #{config.inspect}"
17
+ client.start!
18
+ rescue Slack::RealTime::Client::ClientAlreadyStartedError
19
+ @logger.info "ClientAlreadyStarted so we continue with execution"
20
+ started = true
21
+ rescue Exception => e
22
+ started = false
23
+ restarts += 1
24
+ if restarts < 200
25
+ @logger.info "*" * 50
26
+ @logger.fatal "Rescued on starting: #{e.inspect}"
27
+ @logger.info "Waiting 60 seconds to retry. restarts: #{restarts}"
28
+ puts "#{Time.now}: Not able to start client. Waiting 60 seconds to retry: #{config.inspect}"
29
+ sleep 60
30
+ else
31
+ exit!
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,169 @@
1
+ require_relative "commands/general/hi_bot"
2
+ require_relative "commands/general/bye_bot"
3
+ require_relative "commands/general/bot_help"
4
+ require_relative "commands/on_bot/ruby_code"
5
+ require_relative "commands/general/use_rules"
6
+ require_relative "commands/general/stop_using_rules"
7
+ require_relative "commands/on_master/admin_master/exit_bot"
8
+ require_relative "commands/on_master/admin_master/notify_message"
9
+ require_relative "commands/on_master/admin/kill_bot_on_channel"
10
+ require_relative "commands/on_master/create_bot"
11
+ require_relative "commands/on_bot/admin/add_routine"
12
+ require_relative "commands/on_bot/admin/start_bot"
13
+ require_relative "commands/on_bot/admin/pause_bot"
14
+ require_relative "commands/on_bot/admin/remove_routine"
15
+ require_relative "commands/on_bot/admin/run_routine"
16
+ require_relative "commands/on_bot/admin/pause_routine"
17
+ require_relative "commands/on_bot/admin/start_routine"
18
+ require_relative "commands/on_bot/admin/see_routines"
19
+ require_relative "commands/on_bot/admin/extend_rules"
20
+ require_relative "commands/on_bot/admin/stop_using_rules_on"
21
+ require_relative "commands/general/bot_status"
22
+ require_relative "commands/on_bot/add_shortcut"
23
+ require_relative "commands/on_bot/delete_shortcut"
24
+ require_relative "commands/on_bot/see_shortcuts"
25
+ require_relative "commands/on_extended/bot_rules"
26
+
27
+ class SlackSmartBot
28
+ def process(user, command, dest, dchannel, rules_file, typem, files)
29
+ from = user.name
30
+ if user.profile.display_name.to_s.match?(/\A\s*\z/)
31
+ user.profile.display_name = user.profile.real_name
32
+ end
33
+ display_name = user.profile.display_name
34
+ processed = true
35
+
36
+ on_demand = false
37
+ if command.match(/^@?(#{config[:nick]}):*\s+(.+)/im) or
38
+ command.match(/^()!(.+)/im) or
39
+ command.match(/^()<@#{config[:nick_id]}>\s+(.+)/im)
40
+ command = $2
41
+ on_demand = true
42
+ end
43
+
44
+ #todo: check :on_pg in this case
45
+ if typem == :on_master or typem == :on_bot or typem == :on_pg or typem == :on_dm
46
+ case command
47
+
48
+ when /^\s*(Hello|Hallo|Hi|Hola|What's\sup|Hey|Hæ)\s(#{@salutations.join("|")})\s*$/i
49
+ hi_bot(user, dest, dchannel, from, display_name)
50
+ when /^\s*(Bye|Bæ|Good\sBye|Adiós|Ciao|Bless|Bless\sBless|Adeu)\s(#{@salutations.join("|")})\s*$/i
51
+ bye_bot(dest, from, display_name)
52
+ when /^\s*bot\s+(rules|help)\s*(.+)?$/i, /^bot,? what can I do/i
53
+ $1.to_s.match?(/rules/i) ? specific = true : specific = false
54
+ help_command = $2
55
+
56
+ bot_help(user, from, dest, dchannel, specific, help_command, rules_file)
57
+ when /^\s*use\s+(rules\s+)?(from\s+)?<#C\w+\|(.+)>\s*$/i, /^use\s+(rules\s+)?(from\s+)?([^\s]+\s*$)/i
58
+ channel = $3
59
+ use_rules(dest, channel, user, dchannel)
60
+ when /^\s*stop using rules (from\s+)<#\w+\|(.+)>/i, /^stop using rules (from\s+)(.+)/i
61
+ channel = $2
62
+ stop_using_rules(dest, channel, user, dchannel)
63
+ when /^\s*extend\s+rules\s+(to\s+)<#C\w+\|(.+)>/i, /^extend\s+rules\s+(to\s+)(.+)/i,
64
+ /^\s*use\s+rules\s+(on\s+)<#C\w+\|(.+)>/i, /^use\s+rules\s+(on\s+)(.+)/i
65
+ channel = $2
66
+ extend_rules(dest, user, from, channel, typem)
67
+ when /^\s*stop using rules (on\s+)<#\w+\|(.+)>/i, /^stop using rules (on\s+)(.+)/i
68
+ channel = $2
69
+ stop_using_rules_on(dest, user, from, channel, typem)
70
+ when /^\s*exit\sbot\s*$/i, /^quit\sbot\s*$/i, /^close\sbot\s*$/i
71
+ exit_bot(command, from, dest, display_name)
72
+ when /^\s*start\s(this\s)?bot$/i
73
+ start_bot(dest, from)
74
+ when /^\s*pause\s(this\s)?bot$/i
75
+ pause_bot(dest, from)
76
+ when /^\s*bot\sstatus/i
77
+ bot_status(dest, from)
78
+ when /\Anotify\s+<#(C\w+)\|.+>\s+(.+)\s*\z/im, /\Anotify\s+(all)?\s*(.+)\s*\z/im
79
+ where = $1
80
+ message = $2
81
+ notify_message(dest, from, where, message)
82
+ when /^\s*create\s+(cloud\s+)?bot\s+on\s+<#C\w+\|(.+)>\s*/i, /^create\s+(cloud\s+)?bot\s+on\s+(.+)\s*/i
83
+ cloud = !$1.nil?
84
+ channel = $2
85
+ create_bot(dest, from, cloud, channel)
86
+ when /^\s*kill\sbot\son\s<#C\w+\|(.+)>\s*$/i, /^kill\sbot\son\s(.+)\s*$/i
87
+ channel = $1
88
+ kill_bot_on_channel(dest, from, channel)
89
+ when /^\s*(add|create)\s+routine\s+(\w+)\s+(every)\s+(\d+)\s*(days|hours|minutes|seconds|mins|min|secs|sec|d|h|m|s)\s*(\s.+)?\s*$/i,
90
+ /^\s*(add|create)\s+routine\s+(\w+)\s+(at)\s+(\d+:\d+:?\d+?)\s*()(\s.+)?\s*$/i
91
+ name = $2.downcase
92
+ type = $3
93
+ number_time = $4
94
+ period = $5
95
+ command_to_run = $6
96
+ add_routine(dest, from, user, name, type, number_time, period, command_to_run, files)
97
+ when /^\s*(kill|delete|remove)\s+routine\s+(\w+)\s*$/i
98
+ name = $2.downcase
99
+ remove_routine(dest, from, name)
100
+ when /^\s*(run|execute)\s+routine\s+(\w+)\s*$/i
101
+ name = $2.downcase
102
+ run_routine(dest, from, name)
103
+ when /^\s*pause\s+routine\s+(\w+)\s*$/i
104
+ name = $1.downcase
105
+ pause_routine(dest, from, name)
106
+ when /^\s*start\s+routine\s+(\w+)\s*$/i
107
+ name = $1.downcase
108
+ start_routine(dest, from, name)
109
+ when /^\s*see\s+(all\s+)?routines\s*$/i
110
+ all = $1.to_s != ""
111
+ see_routines(dest, from, user, all)
112
+ else
113
+ processed = false
114
+ end
115
+ else
116
+ processed = false
117
+ end
118
+
119
+ # only when :on and (listening or on demand or direct message)
120
+ if @status == :on and
121
+ (@questions.keys.include?(from) or
122
+ (@listening.include?(from) and typem != :on_extended) or
123
+ typem == :on_dm or typem == :on_pg or on_demand)
124
+ processed2 = true
125
+
126
+ case command
127
+
128
+ # bot rules for extended channels
129
+ when /^bot\s+rules\s*(.+)?$/i
130
+ help_command = $1
131
+ bot_rules(dest, help_command, typem, rules_file, from)
132
+ when /^\s*(add\s)?shortcut\s(for\sall)?\s*(.+)\s*:\s*(.+)/i, /^(add\s)sc\s(for\sall)?\s*(.+)\s*:\s*(.+)/i
133
+ for_all = $2
134
+ shortcut_name = $3.to_s.downcase
135
+ command_to_run = $4
136
+ add_shortcut(dest, from, typem, for_all, shortcut_name, command, command_to_run)
137
+ when /^\s*delete\s+shortcut\s+(.+)/i, /^delete\s+sc\s+(.+)/i
138
+ shortcut = $1.to_s.downcase
139
+ delete_shortcut(dest, from, shortcut, typem, command)
140
+ when /^\s*see\sshortcuts/i, /^see\ssc/i
141
+ see_shortcuts(dest, from, typem)
142
+
143
+ #kept to be backwards compatible
144
+ when /^\s*id\schannel\s<#C\w+\|(.+)>\s*/i, /^id channel (.+)/
145
+ unless typem == :on_extended
146
+ channel_name = $1
147
+ get_channels_name_and_id()
148
+ if @channels_id.keys.include?(channel_name)
149
+ respond "the id of #{channel_name} is #{@channels_id[channel_name]}", dest
150
+ else
151
+ respond "channel: #{channel_name} not found", dest
152
+ end
153
+ end
154
+ when /^\s*ruby\s(.+)/im, /^\s*code\s(.+)/im
155
+ code = $1
156
+ code.gsub!("\\n", "\n")
157
+ code.gsub!("\\r", "\r")
158
+ @logger.info code
159
+ ruby_code(dest, code, rules_file)
160
+ else
161
+ processed2 = false
162
+ end #of case
163
+
164
+ processed = true if processed or processed2
165
+ end
166
+
167
+ return processed
168
+ end
169
+ end
@@ -0,0 +1,201 @@
1
+ class SlackSmartBot
2
+ def process_first(user, text, dest, dchannel, typem, files)
3
+ nick = user.name
4
+ rules_file = ""
5
+
6
+ if typem == :on_call
7
+ rules_file = RULES_FILE
8
+ elsif dest[0] == "C" or dest[0] == "G" # on a channel or private channel
9
+ rules_file = RULES_FILE
10
+
11
+ if @rules_imported.key?(user.id) and @rules_imported[user.id].key?(dchannel)
12
+ unless @bots_created.key?(@rules_imported[user.id][dchannel])
13
+ get_bots_created()
14
+ end
15
+ if @bots_created.key?(@rules_imported[user.id][dchannel])
16
+ rules_file = @bots_created[@rules_imported[user.id][dchannel]][:rules_file]
17
+ end
18
+ end
19
+ elsif dest[0] == "D" and @rules_imported.key?(user.id) and @rules_imported[user.id].key?(user.id) #direct message
20
+ unless @bots_created.key?(@rules_imported[user.id][user.id])
21
+ get_bots_created()
22
+ end
23
+ if @bots_created.key?(@rules_imported[user.id][user.id])
24
+ rules_file = @bots_created[@rules_imported[user.id][user.id]][:rules_file]
25
+ end
26
+ end
27
+
28
+ if nick == config[:nick] #if message is coming from the bot
29
+ begin
30
+ case text
31
+ when /^Bot has been (closed|killed) by/i
32
+ if CHANNEL == @channels_name[dchannel]
33
+ @logger.info "#{nick}: #{text}"
34
+ exit!
35
+ end
36
+ when /^Changed status on (.+) to :(.+)/i
37
+ channel_name = $1
38
+ status = $2
39
+ if ON_MASTER_BOT or CHANNEL == channel_name
40
+ @bots_created[@channels_id[channel_name]][:status] = status.to_sym
41
+ update_bots_file()
42
+ if CHANNEL == channel_name
43
+ @logger.info "#{nick}: #{text}"
44
+ else #on master bot
45
+ @logger.info "Changed status on #{channel_name} to :#{status}"
46
+ end
47
+ end
48
+ when /extended the rules from (.+) to be used on (.+)\.$/i
49
+ from_name = $1
50
+ to_name = $2
51
+ if ON_MASTER_BOT and @bots_created[@channels_id[from_name]][:cloud]
52
+ @bots_created[@channels_id[from_name]][:extended] << to_name
53
+ @bots_created[@channels_id[from_name]][:extended].uniq!
54
+ update_bots_file()
55
+ end
56
+ when /removed the access to the rules of (.+) from (.+)\.$/i
57
+ from_name = $1
58
+ to_name = $2
59
+ if ON_MASTER_BOT and @bots_created[@channels_id[from_name]][:cloud]
60
+ @bots_created[@channels_id[from_name]][:extended].delete(to_name)
61
+ update_bots_file()
62
+ end
63
+ end
64
+
65
+ return :next #don't continue analyzing #jal
66
+ rescue Exception => stack
67
+ @logger.fatal stack
68
+ return :next #jal
69
+ end
70
+ end
71
+
72
+ #only for shortcuts
73
+ if text.match(/^@?(#{config[:nick]}):*\s+(.+)\s*/im) or
74
+ text.match(/^()!\s*(.+)\s*/im) or
75
+ text.match(/^()<@#{config[:nick_id]}>\s+(.+)\s*/im)
76
+ command = $2
77
+ addexcl = true
78
+ else
79
+ addexcl = false
80
+ command = text.downcase.lstrip.rstrip
81
+ end
82
+ if command.scan(/^(shortcut|sc)\s+([^:]+)\s*$/i).any? or
83
+ (@shortcuts.keys.include?(:all) and @shortcuts[:all].keys.include?(command)) or
84
+ (@shortcuts.keys.include?(nick) and @shortcuts[nick].keys.include?(command))
85
+ command = $2.downcase unless $2.nil?
86
+ if @shortcuts.keys.include?(nick) and @shortcuts[nick].keys.include?(command)
87
+ text = @shortcuts[nick][command].dup
88
+ elsif @shortcuts.keys.include?(:all) and @shortcuts[:all].keys.include?(command)
89
+ text = @shortcuts[:all][command].dup
90
+ else
91
+ respond "Shortcut not found", dest unless dest[0] == "C" and dchannel != dest #on extended channel
92
+ return :next #jal
93
+ end
94
+ text = "!" + text if addexcl and text[0] != "!"
95
+ end
96
+
97
+ command = text
98
+
99
+ begin
100
+ t = Thread.new do
101
+ begin
102
+ Thread.current[:dest] = dest
103
+ Thread.current[:user] = user
104
+ Thread.current[:command] = command
105
+ Thread.current[:rules_file] = rules_file
106
+ processed = process(user, command, dest, dchannel, rules_file, typem, files)
107
+ @logger.info "command: #{nick}> #{command}" if processed
108
+ on_demand = false
109
+ if command.match(/^@?(#{config[:nick]}):*\s+(.+)/im) or
110
+ command.match(/^()!(.+)/im) or
111
+ command.match(/^()<@#{config[:nick_id]}>\s+(.+)/im)
112
+ command = $2
113
+ Thread.current[:command] = command
114
+ on_demand = true
115
+ end
116
+ if @status == :on and
117
+ (@questions.keys.include?(nick) or
118
+ (@listening.include?(nick) and typem != :on_extended) or
119
+ dest[0] == "D" or on_demand)
120
+ @logger.info "command: #{nick}> #{command}" unless processed
121
+ #todo: verify this
122
+
123
+ if dest[0] == "C" or dest[0] == "G" or (dest[0] == "D" and typem == :on_call)
124
+ if typem != :on_call and @rules_imported.key?(user.id) and @rules_imported[user.id].key?(dchannel)
125
+ if @bots_created.key?(@rules_imported[user.id][dchannel])
126
+ if @bots_created[@rules_imported[user.id][dchannel]][:status] != :on
127
+ respond "The bot on that channel is not :on", dest
128
+ rules_file = ""
129
+ end
130
+ end
131
+ end
132
+ unless rules_file.empty?
133
+ begin
134
+ eval(File.new(rules_file).read) if File.exist?(rules_file)
135
+ rescue Exception => stack
136
+ @logger.fatal "ERROR ON RULES FILE: #{rules_file}"
137
+ @logger.fatal stack
138
+ end
139
+ if defined?(rules)
140
+ command[0] = "" if command[0] == "!"
141
+ command.gsub!(/^@\w+:*\s*/, "")
142
+ if method(:rules).parameters.size == 4
143
+ rules(user, command, processed, dest)
144
+ elsif method(:rules).parameters.size == 5
145
+ rules(user, command, processed, dest, files)
146
+ else
147
+ rules(user, command, processed, dest, files, rules_file)
148
+ end
149
+ else
150
+ @logger.warn "It seems like rules method is not defined"
151
+ end
152
+ end
153
+ elsif @rules_imported.key?(user.id) and @rules_imported[user.id].key?(user.id)
154
+ if @bots_created.key?(@rules_imported[user.id][user.id])
155
+ if @bots_created[@rules_imported[user.id][user.id]][:status] == :on
156
+ begin
157
+ eval(File.new(rules_file).read) if File.exist?(rules_file)
158
+ rescue Exception => stack
159
+ @logger.fatal "ERROR ON imported RULES FILE: #{rules_file}"
160
+ @logger.fatal stack
161
+ end
162
+ else
163
+ respond "The bot on <##{@rules_imported[user.id][user.id]}|#{@bots_created[@rules_imported[user.id][user.id]][:channel_name]}> is not :on", dest
164
+ rules_file = ""
165
+ end
166
+ end
167
+
168
+ unless rules_file.empty?
169
+ if defined?(rules)
170
+ command[0] = "" if command[0] == "!"
171
+ command.gsub!(/^@\w+:*\s*/, "")
172
+ if method(:rules).parameters.size == 4
173
+ rules(user, command, processed, dest)
174
+ elsif method(:rules).parameters.size == 5
175
+ rules(user, command, processed, dest, files)
176
+ else
177
+ rules(user, command, processed, dest, files, rules_file)
178
+ end
179
+ else
180
+ @logger.warn "It seems like rules method is not defined"
181
+ end
182
+ end
183
+ else
184
+ @logger.info "it is a direct message with no rules file selected so no rules file executed."
185
+ if command.match?(/^\s*bot\s+rules\s*$/i)
186
+ respond "No rules running. You can use the command `use rules from CHANNEL` to specify the rules you want to use on this private conversation.\n`bot help` to see available commands.", dest
187
+ end
188
+ unless processed
189
+ dont_understand(__FILE__, command, user, dest)
190
+ end
191
+ end
192
+ end
193
+ rescue Exception => stack
194
+ @logger.fatal stack
195
+ end
196
+ end
197
+ rescue => e
198
+ @logger.error "exception: #{e.inspect}"
199
+ end
200
+ end
201
+ end