slack-smart-bot 0.9.6 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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