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,41 @@
1
+ class SlackSmartBot
2
+ # helpadmin: ----------------------------------------------
3
+ # helpadmin: `bot status`
4
+ # helpadmin: Displays the status of the bot
5
+ # helpadmin: If on master channel and admin user also it will display info about bots created
6
+ # helpadmin:
7
+ def bot_status(dest, from)
8
+ get_bots_created()
9
+ gems_remote = `gem list slack-smart-bot --remote`
10
+ version_remote = gems_remote.to_s().scan(/slack-smart-bot \((\d+\.\d+\.\d+)/).join
11
+ version_message = ""
12
+ if version_remote != VERSION
13
+ version_message = " There is a new available version: #{version_remote}."
14
+ end
15
+ require "socket"
16
+ ip_address = Socket.ip_address_list.find { |ai| ai.ipv4? && !ai.ipv4_loopback? }.ip_address
17
+ respond "*#{Socket.gethostname} (#{ip_address})*\n\tStatus: #{@status}.\n\tVersion: #{VERSION}.#{version_message}\n\tRules file: #{File.basename RULES_FILE}\n\tExtended: #{@bots_created[@channel_id][:extended] unless ON_MASTER_BOT}\n\tAdmins: #{ADMIN_USERS}\n\tBot time: #{Time.now}", dest
18
+ if @status == :on
19
+ respond "I'm listening to [#{@listening.join(", ")}]", dest
20
+ if ON_MASTER_BOT and ADMIN_USERS.include?(from)
21
+ sleep 5
22
+ @bots_created.each do |k, v|
23
+ msg = []
24
+ msg << "`#{v[:channel_name]}` (#{k}):"
25
+ msg << "\tcreator: #{v[:creator_name]}"
26
+ msg << "\tadmins: #{v[:admins]}"
27
+ msg << "\tstatus: #{v[:status]} #{" *(not responded)*" unless @pings.include?(v[:channel_name])}"
28
+ msg << "\tcreated: #{v[:created]}"
29
+ msg << "\trules: #{v[:rules_file]}"
30
+ msg << "\textended: #{v[:extended]}"
31
+ msg << "\tcloud: #{v[:cloud]}"
32
+ if ON_MASTER_BOT and v.key?(:cloud) and v[:cloud]
33
+ msg << "\trunner: `ruby #{$0} \"#{v[:channel_name]}\" \"#{v[:admins]}\" \"#{v[:rules_file]}\" on&`"
34
+ end
35
+ respond msg.join("\n"), dest
36
+ end
37
+ @pings = []
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,17 @@
1
+ class SlackSmartBot
2
+
3
+ # help: ----------------------------------------------
4
+ # help: `Bye Bot`
5
+ # help: `Bye Smart`
6
+ # help: `Bye NAME_OF_THE_BOT`
7
+ # help: Also apart of Bye you can use _Bæ, Good Bye, Adiós, Ciao, Bless, Bless Bless, Adeu_
8
+ # help: Bot stops listening to you
9
+ # help:
10
+ def bye_bot(dest, from, display_name)
11
+ if @status == :on
12
+ bye = ["Bye", "Bæ", "Good Bye", "Adiós", "Ciao", "Bless", "Bless bless", "Adeu"].sample
13
+ respond "#{bye} #{display_name}", dest
14
+ @listening.delete(from)
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,24 @@
1
+ class SlackSmartBot
2
+
3
+ # help: ----------------------------------------------
4
+ # help: `Hi Bot`
5
+ # help: `Hi Smart`
6
+ # help: `Hello Bot` `Hola Bot` `Hallo Bot` `What's up Bot` `Hey Bot` `Hæ Bot`
7
+ # help: `Hello THE_NAME_OF_THE_BOT`
8
+ # help: Also apart of Hello you can use _Hallo, Hi, Hola, What's up, Hey, Hæ_
9
+ # help: Bot starts listening to you
10
+ # help: After that if you want to avoid a single message to be treated by the smart bot, start the message by -
11
+ # help:
12
+ def hi_bot(user, dest, dchannel, from, display_name)
13
+ if @status == :on
14
+ greetings = ["Hello", "Hallo", "Hi", "Hola", "What's up", "Hey", "Hæ"].sample
15
+ respond "#{greetings} #{display_name}", dest
16
+ if @rules_imported.key?(user.id) and @rules_imported[user.id].key?(user.id) and dest[0] == "D"
17
+ respond "You are using specific rules for channel: <##{@rules_imported[user.id][user.id]}>", dest
18
+ elsif @rules_imported.key?(user.id) and @rules_imported[user.id].key?(dchannel) and (dest[0] == "C" or dest[0] == "G")
19
+ respond "You are using specific rules for channel: <##{@rules_imported[user.id][dchannel]}>", dest
20
+ end
21
+ @listening << from unless @listening.include?(from)
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,44 @@
1
+ class SlackSmartBot
2
+ # help: ----------------------------------------------
3
+ # help: `stop using rules from CHANNEL`
4
+ # help: it will stop using the rules from the specified channel.
5
+ # help:
6
+ def stop_using_rules(dest, channel, user, dchannel)
7
+ if @channels_id.key?(channel)
8
+ channel_id = @channels_id[channel]
9
+ else
10
+ channel_id = channel
11
+ end
12
+ if dest[0] == "C" or dest[0] == "G" #channel
13
+ if @rules_imported.key?(user.id) and @rules_imported[user.id].key?(dchannel)
14
+ if @rules_imported[user.id][dchannel] != channel_id
15
+ respond "You are not using those rules.", dest
16
+ else
17
+ @rules_imported[user.id].delete(dchannel)
18
+ update_rules_imported() if ON_MASTER_BOT
19
+ respond "You won't be using those rules from now on.", dest
20
+
21
+ def git_project() "" end
22
+ def project_folder() "" end
23
+ end
24
+ else
25
+ respond "You were not using those rules.", dest
26
+ end
27
+ else #direct message
28
+ if @rules_imported.key?(user.id) and @rules_imported[user.id].key?(user.id)
29
+ if @rules_imported[user.id][user.id] != channel_id
30
+ respond "You are not using those rules.", dest
31
+ else
32
+ @rules_imported[user.id].delete(user.id)
33
+ update_rules_imported() if ON_MASTER_BOT
34
+ respond "You won't be using those rules from now on.", dest
35
+
36
+ def git_project() "" end
37
+ def project_folder() "" end
38
+ end
39
+ else
40
+ respond "You were not using those rules.", dest
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,48 @@
1
+ class SlackSmartBot
2
+
3
+ # help: ----------------------------------------------
4
+ # help: `use rules from CHANNEL`
5
+ # help: `use rules CHANNEL`
6
+ # help: `use CHANNEL`
7
+ # help: it will use the rules from the specified channel.
8
+ # help: you need to be part of that channel to be able to use the rules.
9
+ # help:
10
+ def use_rules(dest, channel, user, dchannel)
11
+
12
+ #todo: add pagination for case more than 1000 channels on the workspace
13
+ channels = client.web_client.conversations_list(
14
+ types: "private_channel,public_channel",
15
+ limit: "1000",
16
+ exclude_archived: "true",
17
+ ).channels
18
+
19
+ channel_found = channels.detect { |c| c.name == channel }
20
+ members = client.web_client.conversations_members(channel: @channels_id[channel]).members unless channel_found.nil?
21
+
22
+ if channel_found.nil?
23
+ respond "The channel you are trying to use doesn't exist", dest
24
+ elsif channel_found.name == MASTER_CHANNEL
25
+ respond "You cannot use the rules from Master Channel on any other channel.", dest
26
+ elsif !@bots_created.key?(@channels_id[channel])
27
+ respond "There is no bot running on that channel.", dest
28
+ elsif @bots_created.key?(@channels_id[channel]) and @bots_created[@channels_id[channel]][:status] != :on
29
+ respond "The bot in that channel is not :on", dest
30
+ else
31
+ if user.id == channel_found.creator or members.include?(user.id)
32
+ @rules_imported[user.id] = {} unless @rules_imported.key?(user.id)
33
+ if dest[0] == "C" or dest[0] == "G" #todo: take in consideration bots that are not master
34
+ @rules_imported[user.id][dchannel] = channel_found.id
35
+ else
36
+ @rules_imported[user.id][user.id] = channel_found.id
37
+ end
38
+ update_rules_imported() if ON_MASTER_BOT
39
+ respond "I'm using now the rules from <##{channel_found.id}>", dest
40
+
41
+ def git_project() "" end
42
+ def project_folder() "" end
43
+ else
44
+ respond "You need to join the channel <##{channel_found.id}> to be able to use the rules.", dest
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,64 @@
1
+ class SlackSmartBot
2
+
3
+ # help: ----------------------------------------------
4
+ # help: `add shortcut NAME: COMMAND`
5
+ # help: `add sc NAME: COMMAND`
6
+ # help: `add shortcut for all NAME: COMMAND`
7
+ # help: `add sc for all NAME: COMMAND`
8
+ # help: `shortcut NAME: COMMAND`
9
+ # help: `shortcut for all NAME: COMMAND`
10
+ # help: It will add a shortcut that will execute the command we supply.
11
+ # help: In case we supply 'for all' then the shorcut will be available for everybody
12
+ # help: Example:
13
+ # help: _add shortcut for all Spanish account: code require 'iso/iban'; 10.times {puts ISO::IBAN.random('ES')}_
14
+ # help: Then to call this shortcut:
15
+ # help: _sc spanish account_
16
+ # help: _shortcut Spanish Account_
17
+ # help: _Spanish Account_
18
+ # help:
19
+ def add_shortcut(dest, from, typem, for_all, shortcut_name, command, command_to_run)
20
+ unless typem == :on_extended
21
+ @shortcuts[from] = Hash.new() unless @shortcuts.keys.include?(from)
22
+
23
+ found_other = false
24
+ if for_all.to_s != ""
25
+ @shortcuts.each { |sck, scv|
26
+ if sck != :all and sck != from and scv.key?(shortcut_name)
27
+ found_other = true
28
+ end
29
+ }
30
+ end
31
+ if !ADMIN_USERS.include?(from) and @shortcuts[:all].include?(shortcut_name) and !@shortcuts[from].include?(shortcut_name)
32
+ respond "Only the creator of the shortcut can modify it", dest
33
+ elsif found_other
34
+ respond "You cannot create a shortcut for all with the same name than other user is using", dest
35
+ elsif !@shortcuts[from].include?(shortcut_name)
36
+ #new shortcut
37
+ @shortcuts[from][shortcut_name] = command_to_run
38
+ @shortcuts[:all][shortcut_name] = command_to_run if for_all.to_s != ""
39
+ update_shortcuts_file()
40
+ respond "shortcut added", dest
41
+ else
42
+
43
+ #are you sure? to avoid overwriting existing
44
+ unless @questions.keys.include?(from)
45
+ ask("The shortcut already exists, are you sure you want to overwrite it?", command, from, dest)
46
+ else
47
+ case @questions[from]
48
+ when /^(yes|yep)/i
49
+ @shortcuts[from][shortcut_name] = command_to_run
50
+ @shortcuts[:all][shortcut_name] = command_to_run if for_all.to_s != ""
51
+ update_shortcuts_file()
52
+ respond "shortcut added", dest
53
+ @questions.delete(from)
54
+ when /^no/i
55
+ respond "ok, I won't add it", dest
56
+ @questions.delete(from)
57
+ else
58
+ ask "I don't understand, yes or no?", command, from, dest
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,87 @@
1
+ class SlackSmartBot
2
+ # helpadmin: ----------------------------------------------
3
+ # helpadmin: `add routine NAME every NUMBER PERIOD COMMAND`
4
+ # helpadmin: `add routine NAME every NUMBER PERIOD`
5
+ # helpadmin: `create routine NAME every NUMBER PERIOD`
6
+ # helpadmin: `add routine NAME at TIME COMMAND`
7
+ # helpadmin: `add routine NAME at TIME`
8
+ # helpadmin: `create routine NAME at TIME`
9
+ # helpadmin: It will execute the command supplied. Only for Admin and Master Admins.
10
+ # helpadmin: If no COMMAND supplied, then it will be necessary to attach a file with the code to be run and add this command as message to the file. ONLY for MASTER ADMINS.
11
+ # helpadmin: NAME: one word to identify the routine
12
+ # helpadmin: NUMBER: Integer
13
+ # helpadmin: PERIOD: days, d, hours, h, minutes, mins, min, m, seconds, secs, sec, s
14
+ # helpadmin: TIME: time at format HH:MM:SS
15
+ # helpadmin: COMMAND: any valid smart bot command or rule
16
+ # helpadmin: Examples:
17
+ # helpadmin: _add routine example every 30s ruby puts 'a'_
18
+ # helpadmin: _add routine example every 3 days ruby puts 'a'_
19
+ # helpadmin: _add routine example at 17:05 ruby puts 'a'_
20
+ # helpadmin:
21
+ def add_routine(dest, from, user, name, type, number_time, period, command_to_run, files)
22
+ if files.nil? or files.size == 0 or (files.size > 0 and MASTER_USERS.include?(from))
23
+ if ADMIN_USERS.include?(from)
24
+ if @routines.key?(@channel_id) && @routines[@channel_id].key?(name)
25
+ respond "I'm sorry but there is already a routine with that name.\nCall `see routines` to see added routines", dest
26
+ else
27
+ number_time += ":00" if number_time.split(":").size == 2
28
+ if (type == "at") && !number_time.match?(/^[01][0-9]:[0-5][0-9]:[0-5][0-9]$/) &&
29
+ !number_time.match?(/^2[0-3]:[0-5][0-9]:[0-5][0-9]$/)
30
+ respond "Wrong time specified: *#{number_time}*"
31
+ else
32
+ file_path = ""
33
+ every = ""
34
+ at = ""
35
+ next_run = Time.now
36
+ case period.downcase
37
+ when "days", "d"
38
+ every = "#{number_time} days"
39
+ every_in_seconds = number_time.to_i * 24 * 60 * 60
40
+ when "hours", "h"
41
+ every = "#{number_time} hours"
42
+ every_in_seconds = number_time.to_i * 60 * 60
43
+ when "minutes", "mins", "min", "m"
44
+ every = "#{number_time} minutes"
45
+ every_in_seconds = number_time.to_i * 60
46
+ when "seconds", "secs", "sec", "s"
47
+ every = "#{number_time} seconds"
48
+ every_in_seconds = number_time.to_i
49
+ else # time
50
+ at = number_time
51
+ if next_run.strftime("%k:%M:%S") < number_time
52
+ nt = number_time.split(":")
53
+ next_run = Time.new(next_run.year, next_run.month, next_run.day, nt[0], nt[1], nt[2])
54
+ else
55
+ next_run += (24 * 60 * 60) # one more day
56
+ nt = number_time.split(":")
57
+ next_run = Time.new(next_run.year, next_run.month, next_run.day, nt[0], nt[1], nt[2])
58
+ end
59
+ every_in_seconds = 24 * 60 * 60
60
+ end
61
+ Dir.mkdir("./routines/#{@channel_id}") unless Dir.exist?("./routines/#{@channel_id}")
62
+
63
+ if !files.nil? && (files.size == 1)
64
+ @logger.info files[0].inspect
65
+ file_path = "./routines/#{@channel_id}/#{name}#{files[0].name.scan(/[^\.]+(\.\w+$)/).join}"
66
+ http = NiceHttp.new(host: "https://files.slack.com", headers: { "Authorization" => "Bearer #{config[:token]}" }, log_headers: :partial)
67
+ http.get(files[0].url_private_download, save_data: file_path)
68
+ system("chmod +x #{file_path}")
69
+ end
70
+
71
+ @routines[@channel_id] = {} unless @routines.key?(@channel_id)
72
+ @routines[@channel_id][name] = { channel_name: CHANNEL, creator: from, creator_id: user.id, status: :on,
73
+ every: every, every_in_seconds: every_in_seconds, at: at, file_path: file_path, command: command_to_run.to_s.strip,
74
+ next_run: next_run.to_s, dest: dest, last_run: "", last_elapsed: "", running: false }
75
+ update_routines
76
+ respond "Added routine *`#{name}`* to the channel", dest
77
+ create_routine_thread(name)
78
+ end
79
+ end
80
+ else
81
+ respond "Only admin users can use this command", dest
82
+ end
83
+ else
84
+ respond "Only master admin users can add files to routines", dest
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,63 @@
1
+ class SlackSmartBot
2
+
3
+ # helpadmin: ----------------------------------------------
4
+ # helpadmin: `extend rules to CHANNEL_NAME`
5
+ # helpadmin: `use rules on CHANNEL_NAME`
6
+ # helpadmin: It will allow to use the specific rules from this channel on the CHANNEL_NAME
7
+ # helpadmin:
8
+ def extend_rules(dest, user, from, channel, typem)
9
+ unless typem == :on_extended
10
+ if ON_MASTER_BOT
11
+ respond "You cannot use the rules from Master Channel on any other channel.", dest
12
+ elsif !ADMIN_USERS.include?(from) #not admin
13
+ respond "Only admins can extend the rules. Admins on this channel: #{ADMIN_USERS}", dest
14
+ else
15
+ #todo: add pagination for case more than 1000 channels on the workspace
16
+ channels = client.web_client.conversations_list(
17
+ types: "private_channel,public_channel",
18
+ limit: "1000",
19
+ exclude_archived: "true",
20
+ ).channels
21
+
22
+ channel_found = channels.detect { |c| c.name == channel }
23
+ get_channels_name_and_id()
24
+ members = client.web_client.conversations_members(channel: @channels_id[channel]).members unless channel_found.nil?
25
+ get_bots_created()
26
+ channels_in_use = []
27
+ @bots_created.each do |k, v|
28
+ if v.key?(:extended) and v[:extended].include?(channel)
29
+ channels_in_use << v[:channel_name]
30
+ end
31
+ end
32
+
33
+ if channel_found.nil?
34
+ respond "The channel you specified doesn't exist", dest
35
+ elsif @bots_created.key?(@channels_id[channel])
36
+ respond "There is a bot already running on that channel.", dest
37
+ elsif @bots_created[@channel_id][:extended].include?(channel)
38
+ respond "The rules are already extended to that channel.", dest
39
+ elsif !members.include?(user.id)
40
+ respond "You need to join that channel first", dest
41
+ elsif !members.include?(config[:nick_id])
42
+ respond "You need to add first to the channel the smart bot user: #{config[:nick]}", dest
43
+ else
44
+ channels_in_use.each do |channel_in_use|
45
+ respond "The rules from channel <##{@channels_id[channel_in_use]}> are already in use on that channel", dest
46
+ end
47
+ @bots_created[@channel_id][:extended] = [] unless @bots_created[@channel_id].key?(:extended)
48
+ @bots_created[@channel_id][:extended] << channel
49
+ update_bots_file()
50
+ respond "<@#{user.id}> extended the rules from #{CHANNEL} to be used on #{channel}.", @master_bot_id
51
+ if @channels_id[channel][0] == "G"
52
+ respond "Now the rules from <##{@channel_id}> are available on *#{channel}*", dest
53
+ else
54
+ respond "Now the rules from <##{@channel_id}> are available on *<##{@channels_id[channel]}>*", dest
55
+ end
56
+ respond "<@#{user.id}> extended the rules from <##{@channel_id}> to this channel so now you can talk to the Smart Bot on demand using those rules.", @channels_id[channel]
57
+ respond "Use `!` before the command you want to run", @channels_id[channel]
58
+ respond "To see the specific rules for this bot on this channel: `!bot rules` or `!bot rules COMMAND`", @channels_id[channel]
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,21 @@
1
+ class SlackSmartBot
2
+
3
+ # helpadmin: ----------------------------------------------
4
+ # helpadmin: `pause bot`
5
+ # helpadmin: `pause this bot`
6
+ # helpadmin: the bot will pause so it will listen only to admin commands
7
+ # helpadmin: You can use this command only if you are an admin user
8
+ # helpadmin:
9
+ def pause_bot(dest, from)
10
+ if ADMIN_USERS.include?(from) #admin user
11
+ respond "This bot is paused from now on. You can start it again: start this bot", dest
12
+ respond "zZzzzzZzzzzZZZZZZzzzzzzzz", dest
13
+ @status = :paused
14
+ unless ON_MASTER_BOT
15
+ send_msg_channel MASTER_CHANNEL, "Changed status on #{CHANNEL} to :paused"
16
+ end
17
+ else
18
+ respond "Only admin users can put me on pause", dest
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,26 @@
1
+ class SlackSmartBot
2
+ # helpadmin: ----------------------------------------------
3
+ # helpadmin: `pause routine NAME`
4
+ # helpadmin: It will pause the specified routine
5
+ # helpadmin: You can use this command only if you are an admin user
6
+ # helpadmin: NAME: one word to identify the routine
7
+ # helpadmin: Examples:
8
+ # helpadmin: _pause routine example_
9
+ # helpadmin:
10
+ def pause_routine(dest, from, name)
11
+ if ADMIN_USERS.include?(from) #admin user
12
+ if !ON_MASTER_BOT and dest[0] == "D"
13
+ respond "It's only possible to pause routines from MASTER channel from a direct message with the bot.", dest
14
+ elsif @routines.key?(@channel_id) and @routines[@channel_id].key?(name)
15
+ @routines[@channel_id][name][:status] = :paused
16
+ @routines[@channel_id][name][:next_run] = ""
17
+ update_routines()
18
+ respond "The routine *`#{name}`* has been paused.", dest
19
+ else
20
+ respond "There isn't a routine with that name: *`#{name}`*.\nCall `see routines` to see added routines", dest
21
+ end
22
+ else
23
+ respond "Only admin users can use this command", dest
24
+ end
25
+ end
26
+ end