slack-smart-bot 1.9.1 → 1.11.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (121) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +184 -16
  3. data/lib/slack/smart-bot/comm/ask.rb +55 -49
  4. data/lib/slack/smart-bot/comm/delete.rb +13 -0
  5. data/lib/slack/smart-bot/comm/dont_understand.rb +3 -3
  6. data/lib/slack/smart-bot/comm/event_hello.rb +8 -4
  7. data/lib/slack/smart-bot/comm/get_channel_members.rb +13 -4
  8. data/lib/slack/smart-bot/comm/get_channels.rb +31 -16
  9. data/lib/slack/smart-bot/comm/get_presence.rb +20 -0
  10. data/lib/slack/smart-bot/comm/get_user_info.rb +12 -8
  11. data/lib/slack/smart-bot/comm/get_users.rb +24 -0
  12. data/lib/slack/smart-bot/comm/react.rb +19 -2
  13. data/lib/slack/smart-bot/comm/respond.rb +224 -53
  14. data/lib/slack/smart-bot/comm/respond_direct.rb +2 -3
  15. data/lib/slack/smart-bot/comm/respond_thread.rb +5 -0
  16. data/lib/slack/smart-bot/comm/send_file.rb +38 -34
  17. data/lib/slack/smart-bot/comm/send_msg_channel.rb +27 -22
  18. data/lib/slack/smart-bot/comm/send_msg_user.rb +59 -33
  19. data/lib/slack/smart-bot/comm/unreact.rb +22 -18
  20. data/lib/slack/smart-bot/comm.rb +4 -0
  21. data/lib/slack/smart-bot/commands/general/add_admin.rb +51 -0
  22. data/lib/slack/smart-bot/commands/general/add_announcement.rb +32 -0
  23. data/lib/slack/smart-bot/commands/general/add_team.rb +80 -0
  24. data/lib/slack/smart-bot/commands/general/allow_access.rb +67 -0
  25. data/lib/slack/smart-bot/commands/general/bot_help.rb +69 -33
  26. data/lib/slack/smart-bot/commands/general/bye_bot.rb +0 -7
  27. data/lib/slack/smart-bot/commands/general/delete_announcement.rb +34 -0
  28. data/lib/slack/smart-bot/commands/general/delete_share.rb +34 -0
  29. data/lib/slack/smart-bot/commands/general/delete_team.rb +34 -0
  30. data/lib/slack/smart-bot/commands/general/deny_access.rb +36 -0
  31. data/lib/slack/smart-bot/commands/general/hi_bot.rb +16 -11
  32. data/lib/slack/smart-bot/commands/general/ping_team.rb +100 -0
  33. data/lib/slack/smart-bot/commands/general/poster.rb +116 -0
  34. data/lib/slack/smart-bot/commands/general/remove_admin.rb +58 -0
  35. data/lib/slack/smart-bot/commands/general/see_access.rb +24 -0
  36. data/lib/slack/smart-bot/commands/general/see_admins.rb +33 -0
  37. data/lib/slack/smart-bot/commands/general/see_announcements.rb +115 -0
  38. data/lib/slack/smart-bot/commands/general/see_command_ids.rb +29 -0
  39. data/lib/slack/smart-bot/commands/general/see_favorite_commands.rb +53 -0
  40. data/lib/slack/smart-bot/commands/general/see_shares.rb +41 -0
  41. data/lib/slack/smart-bot/commands/general/see_statuses.rb +91 -0
  42. data/lib/slack/smart-bot/commands/general/see_teams.rb +252 -0
  43. data/lib/slack/smart-bot/commands/general/share_messages.rb +58 -0
  44. data/lib/slack/smart-bot/commands/general/update_team.rb +109 -0
  45. data/lib/slack/smart-bot/commands/general_bot_commands.rb +504 -0
  46. data/lib/slack/smart-bot/commands/on_bot/add_shortcut.rb +4 -6
  47. data/lib/slack/smart-bot/commands/on_bot/admin/add_routine.rb +45 -14
  48. data/lib/slack/smart-bot/commands/on_bot/admin/extend_rules.rb +4 -1
  49. data/lib/slack/smart-bot/commands/on_bot/admin/pause_bot.rb +6 -3
  50. data/lib/slack/smart-bot/commands/on_bot/admin/pause_routine.rb +3 -1
  51. data/lib/slack/smart-bot/commands/on_bot/admin/remove_routine.rb +4 -4
  52. data/lib/slack/smart-bot/commands/on_bot/admin/run_routine.rb +8 -2
  53. data/lib/slack/smart-bot/commands/on_bot/admin/see_result_routine.rb +33 -0
  54. data/lib/slack/smart-bot/commands/on_bot/admin/see_routines.rb +13 -10
  55. data/lib/slack/smart-bot/commands/on_bot/admin/start_bot.rb +6 -3
  56. data/lib/slack/smart-bot/commands/on_bot/admin/start_routine.rb +3 -1
  57. data/lib/slack/smart-bot/commands/on_bot/admin/stop_using_rules_on.rb +4 -1
  58. data/lib/slack/smart-bot/commands/on_bot/admin_master/delete_message.rb +25 -0
  59. data/lib/slack/smart-bot/commands/on_bot/admin_master/get_bot_logs.rb +1 -0
  60. data/lib/slack/smart-bot/commands/on_bot/admin_master/react_to.rb +34 -0
  61. data/lib/slack/smart-bot/commands/on_bot/admin_master/send_message.rb +37 -0
  62. data/lib/slack/smart-bot/commands/on_bot/delete_repl.rb +4 -5
  63. data/lib/slack/smart-bot/commands/on_bot/delete_shortcut.rb +7 -8
  64. data/lib/slack/smart-bot/commands/on_bot/general/bot_stats.rb +400 -0
  65. data/lib/slack/smart-bot/commands/{general → on_bot/general}/bot_status.rb +3 -4
  66. data/lib/slack/smart-bot/commands/on_bot/general/leaderboard.rb +201 -0
  67. data/lib/slack/smart-bot/commands/{general → on_bot/general}/stop_using_rules.rb +12 -6
  68. data/lib/slack/smart-bot/commands/on_bot/general/suggest_command.rb +36 -0
  69. data/lib/slack/smart-bot/commands/{general → on_bot/general}/use_rules.rb +13 -11
  70. data/lib/slack/smart-bot/commands/{general → on_bot/general}/whats_new.rb +2 -1
  71. data/lib/slack/smart-bot/commands/on_bot/get_repl.rb +4 -5
  72. data/lib/slack/smart-bot/commands/on_bot/repl.rb +76 -21
  73. data/lib/slack/smart-bot/commands/on_bot/ruby_code.rb +3 -4
  74. data/lib/slack/smart-bot/commands/on_bot/run_repl.rb +15 -7
  75. data/lib/slack/smart-bot/commands/on_bot/see_repls.rb +5 -6
  76. data/lib/slack/smart-bot/commands/on_bot/see_shortcuts.rb +5 -6
  77. data/lib/slack/smart-bot/commands/on_extended/bot_rules.rb +45 -12
  78. data/lib/slack/smart-bot/commands/on_master/admin/kill_bot_on_channel.rb +7 -3
  79. data/lib/slack/smart-bot/commands/on_master/admin_master/exit_bot.rb +4 -1
  80. data/lib/slack/smart-bot/commands/on_master/admin_master/notify_message.rb +3 -1
  81. data/lib/slack/smart-bot/commands/on_master/admin_master/publish_announcements.rb +33 -0
  82. data/lib/slack/smart-bot/commands/on_master/admin_master/set_general_message.rb +39 -0
  83. data/lib/slack/smart-bot/commands/on_master/admin_master/set_maintenance.rb +10 -1
  84. data/lib/slack/smart-bot/commands/on_master/create_bot.rb +28 -14
  85. data/lib/slack/smart-bot/commands/on_master/where_smartbot.rb +41 -0
  86. data/lib/slack/smart-bot/commands.rb +36 -5
  87. data/lib/slack/smart-bot/listen.rb +31 -33
  88. data/lib/slack/smart-bot/process.rb +234 -73
  89. data/lib/slack/smart-bot/process_first.rb +119 -38
  90. data/lib/slack/smart-bot/treat_message.rb +310 -237
  91. data/lib/slack/smart-bot/utils/build_help.rb +2 -2
  92. data/lib/slack/smart-bot/utils/create_routine_thread.rb +81 -46
  93. data/lib/slack/smart-bot/utils/get_access_channels.rb +13 -0
  94. data/lib/slack/smart-bot/utils/get_admins_channels.rb +13 -0
  95. data/lib/slack/smart-bot/utils/get_bots_created.rb +28 -8
  96. data/lib/slack/smart-bot/utils/get_channels_name_and_id.rb +7 -2
  97. data/lib/slack/smart-bot/utils/get_command_ids.rb +84 -0
  98. data/lib/slack/smart-bot/utils/get_help.rb +79 -73
  99. data/lib/slack/smart-bot/utils/get_repls.rb +22 -2
  100. data/lib/slack/smart-bot/utils/get_routines.rb +22 -2
  101. data/lib/slack/smart-bot/utils/get_shares.rb +12 -0
  102. data/lib/slack/smart-bot/utils/get_teams.rb +22 -0
  103. data/lib/slack/smart-bot/utils/has_access.rb +28 -0
  104. data/lib/slack/smart-bot/utils/is_admin.rb +27 -0
  105. data/lib/slack/smart-bot/utils/save_stats.rb +46 -41
  106. data/lib/slack/smart-bot/utils/save_status.rb +67 -0
  107. data/lib/slack/smart-bot/utils/update_access_channels.rb +8 -0
  108. data/lib/slack/smart-bot/utils/update_admins_channels.rb +8 -0
  109. data/lib/slack/smart-bot/utils/update_bots_file.rb +28 -7
  110. data/lib/slack/smart-bot/utils/update_repls.rb +7 -4
  111. data/lib/slack/smart-bot/utils/update_routines.rb +9 -3
  112. data/lib/slack/smart-bot/utils/update_shortcuts_file.rb +13 -6
  113. data/lib/slack/smart-bot/utils/update_teams.rb +16 -0
  114. data/lib/slack/smart-bot/utils.rb +11 -0
  115. data/lib/slack-smart-bot.rb +72 -12
  116. data/lib/slack-smart-bot_general_commands.rb +61 -0
  117. data/lib/slack-smart-bot_general_rules.rb +5 -2
  118. data/lib/slack-smart-bot_rules.rb +43 -17
  119. data/whats_new.txt +20 -15
  120. metadata +76 -9
  121. data/lib/slack/smart-bot/commands/general/bot_stats.rb +0 -313
@@ -1,284 +1,357 @@
1
1
  class SlackSmartBot
2
2
  def treat_message(data, remove_blocks = true)
3
-
3
+ @buffered = false if config[:testing]
4
4
  begin
5
- unless data.text.to_s.match(/\A\s*\z/)
6
- #to remove italic, bold... from data.text since there is no method on slack api
7
- if remove_blocks and !data.blocks.nil? and data.blocks.size > 0
8
- data_text = ''
9
- data.blocks.each do |b|
10
- if b.type == 'rich_text'
11
- if b.elements.size > 0
12
- b.elements.each do |e|
13
- if e.type == 'rich_text_section' or e.type == 'rich_text_preformatted'
14
- if e.elements.size > 0 and (e.elements.type.uniq - ['link', 'text', 'user', 'channel']) == []
15
- data_text += '```' if e.type == 'rich_text_preformatted'
16
- e.elements.each do |el|
17
- if el.type == 'text'
18
- data_text += el.text
19
- elsif el.type == 'user'
20
- data_text += "<@#{el.user_id}>"
21
- elsif el.type == 'channel'
22
- tch = data.text.scan(/(<##{el.channel_id}\|[^\>]+>)/).join
23
- data_text += tch
24
- else
25
- data_text += el.url
5
+ begin
6
+ command_orig = data.text
7
+ unless data.text.to_s.match(/\A\s*\z/)
8
+ #to remove italic, bold... from data.text since there is no method on slack api
9
+ if remove_blocks and !data.blocks.nil? and data.blocks.size > 0
10
+ data_text = ''
11
+ data.blocks.each do |b|
12
+ if b.type == 'rich_text'
13
+ if b.elements.size > 0
14
+ b.elements.each do |e|
15
+ if e.type == 'rich_text_section' or e.type == 'rich_text_preformatted'
16
+ if e.elements.size > 0 and (e.elements.type.uniq - ['link', 'text', 'user', 'channel']) == []
17
+ data_text += '```' if e.type == 'rich_text_preformatted'
18
+ e.elements.each do |el|
19
+ if el.type == 'text'
20
+ data_text += el.text
21
+ elsif el.type == 'user'
22
+ data_text += "<@#{el.user_id}>"
23
+ elsif el.type == 'channel'
24
+ tch = data.text.scan(/(<##{el.channel_id}\|[^\>]*>)/).join
25
+ data_text += tch
26
+ else
27
+ data_text += el.url
28
+ end
26
29
  end
30
+ data_text += '```' if e.type == 'rich_text_preformatted'
27
31
  end
28
- data_text += '```' if e.type == 'rich_text_preformatted'
29
32
  end
30
33
  end
31
34
  end
32
35
  end
33
36
  end
37
+ data.text = data_text unless data_text == ''
34
38
  end
35
- data.text = data_text unless data_text == ''
39
+ data.text = CGI.unescapeHTML(data.text)
40
+ data.text.gsub!("\u00A0", " ") #to change &nbsp; (asc char 160) into blank space
36
41
  end
37
- data.text = CGI.unescapeHTML(data.text)
38
- data.text.gsub!("\u00A0", " ") #to change &nbsp; (asc char 160) into blank space
42
+ data.text.gsub!('‘', "'")
43
+ data.text.gsub!('’', "'")
44
+ data.text.gsub!('“', '"')
45
+ data.text.gsub!('”', '"')
46
+ rescue Exception => exc
47
+ @logger.warn "Impossible to unescape or clean format for data.text:#{data.text}"
48
+ @logger.warn exc.inspect
39
49
  end
40
- data.text.gsub!('‘', "'")
41
- data.text.gsub!('’', "'")
42
- data.text.gsub!('“', '"')
43
- data.text.gsub!('”', '"')
44
- rescue Exception => exc
45
- @logger.warn "Impossible to unescape or clean format for data.text:#{data.text}"
46
- @logger.warn exc.inspect
47
- end
48
- data.routine = false unless data.key?(:routine)
49
-
50
- if config[:testing] and config.on_master_bot
51
- open("#{config.path}/buffer.log", "a") { |f|
52
- f.puts "|#{data.channel}|#{data.user}|#{data.user_name}|#{data.text}"
53
- }
54
- end
55
- if data.key?(:dest) and data.dest.to_s!='' # for run routines and publish on different channels
56
- dest = data.dest
57
- elsif data.channel[0] == "D" or data.channel[0] == "C" or data.channel[0] == "G" #Direct message or Channel or Private Channel
58
- dest = data.channel
59
- else # not treated
60
- dest = nil
61
- end
62
- #todo: sometimes data.user is nil, check the problem.
63
- @logger.warn "!dest is nil. user: #{data.user}, channel: #{data.channel}, message: #{data.text}" if dest.nil?
64
- if !data.files.nil? and data.files.size == 1 and data.text.to_s == "" and data.files[0].filetype == "ruby"
65
- data.text = "ruby"
66
- end
67
- if !dest.nil? and config.on_master_bot and !data.text.nil? and data.text.match(/^ping from (.+)\s*$/) and data.user == config[:nick_id]
68
- @pings << $1
69
- end
70
- typem = :dont_treat
71
- if !dest.nil? and !data.text.nil? and !data.text.to_s.match?(/\A\s*\z/)
72
- #if data.text.match(/^\s*<@#{config[:nick_id]}>\s+(on\s+)?<#(\w+)\|([^>]+)>\s*:?\s*(.*)/im)
73
- if data.text.match(/^\s*<@#{config[:nick_id]}>\s+(on\s+)?((<#\w+\|[^>]+>\s*)+)\s*:?\s*(.*)/im)
74
- channels_rules = $2 #multiple channels @smart-bot on #channel1 #channel2 echo AAA
75
- data_text = $4
76
- channel_rules_name = ''
77
- channel_rules = ''
78
- # to be treated only on the bots of the requested channels
79
- channels_rules.scan(/<#(\w+)\|([^>]+)>/).each do |tcid, tcname|
80
- if @channel_id == tcid
81
- data.text = data_text
82
- typem = :on_call
83
- channel_rules = tcid
84
- channel_rules_name = tcname
85
- break
86
- end
87
- end
88
- elsif data.channel == @master_bot_id
89
- if config.on_master_bot #only to be treated on master bot channel
90
- typem = :on_master
50
+
51
+ unless data.key?(:routine)
52
+ data.routine = false
53
+ data.routine_name = ''
54
+ data.routine_type = ''
55
+ end
56
+ if config[:testing] and config.on_master_bot and !@buffered
57
+ @buffered = true
58
+ open("#{config.path}/buffer.log", "a") { |f|
59
+ f.puts "|#{data.channel}|#{data.user}|#{data.user_name}|#{data.text}"
60
+ }
61
+ end
62
+ if data.key?(:dest) and data.dest.to_s!='' # for run routines and publish on different channels
63
+ dest = data.dest
64
+ elsif data.channel[0] == "D" or data.channel[0] == "C" or data.channel[0] == "G" #Direct message or Channel or Private Channel
65
+ dest = data.channel
66
+ else # not treated
67
+ dest = nil
68
+ end
69
+ #todo: sometimes data.user is nil, check the problem.
70
+ @logger.warn "!dest is nil. user: #{data.user}, channel: #{data.channel}, message: #{data.text}" if dest.nil?
71
+ if !data.files.nil? and data.files.size == 1 and data.text.to_s == "" and data.files[0].filetype == "ruby"
72
+ data.text = "ruby"
73
+ end
74
+ if !dest.nil? and config.on_master_bot and !data.text.nil? and data.text.match(/^ping from (.+)\s*$/) and data.user == config[:nick_id]
75
+ @pings << $1
76
+ end
77
+ typem = :dont_treat
78
+ if data.nil? or data.user.nil? or data.user.to_s==''
79
+ user_info = nil
80
+ @users = get_users() if @users.empty?
81
+ else
82
+ #todo: when changed @questions user_id then move user_info inside the ifs to avoid calling it when not necessary
83
+ user_info = @users.select{|u| u.id == data.user or (u.key?(:enterprise_user) and u.enterprise_user.id == data.user)}[-1]
84
+ if user_info.nil? or user_info.empty?
85
+ @users = get_users()
86
+ user_info = @users.select{|u| u.id == data.user or (u.key?(:enterprise_user) and u.enterprise_user.id == data.user)}[-1]
91
87
  end
92
- elsif @bots_created.key?(data.channel)
93
- if @channel_id == data.channel #only to be treated by the bot on the channel
94
- typem = :on_bot
88
+ end
89
+ if !dest.nil? and !data.text.nil? and !data.text.to_s.match?(/\A\s*\z/)
90
+ get_bots_created()
91
+ if data.channel[0] == "D" and !data.text.to_s.match?(/^\s*<@#{config[:nick_id]}>\s+/) and
92
+ (data.text.to_s.match?(/^\s*(on)?\s*<#\w+\|[^>]*>/i) or data.text.to_s.match?(/^\s*(on)?\s*#\w+/i))
93
+ data.text = "<@#{config[:nick_id]}> " + data.text.to_s
95
94
  end
96
- elsif data.channel[0] == "D" #Direct message
97
- get_rules_imported()
98
- if @rules_imported.key?(data.user) && @rules_imported[data.user].key?(data.user) and
99
- @bots_created.key?(@rules_imported[data.user][data.user])
100
- if @channel_id == @rules_imported[data.user][data.user]
101
- #only to be treated by the channel we are 'using'
95
+ #todo: we need to add mixed channels: @smart-bot on private1 #bot1cm <#CXDDFRDDF|bot2cu>: echo A
96
+ if data.text.match(/\A\^\^+/) # to open a thread it will be only when starting by single ^
97
+ typem = :dont_treat
98
+ elsif data.text.match(/^\s*<@#{config[:nick_id]}>\s+(on\s+)?((<#\w+\|[^>]*>\s*)+)\s*:?\s*(.*)/im) or
99
+ data.text.match(/^\s*<@#{config[:nick_id]}>\s+(on\s+)?((#[a-zA-Z0-9\-\_]+\s*)+)\s*:?\s*(.*)/im) or
100
+ data.text.match(/^\s*<@#{config[:nick_id]}>\s+(on\s+)?(([a-zA-Z0-9\-\_]+\s*)+)\s*:\s*(.*)/im)
101
+ channels_rules = $2 #multiple channels @smart-bot on #channel1 #channel2 echo AAA
102
+ data_text = $4
103
+ channel_rules_name = ''
104
+ channel_rules = ''
105
+ channels_arr = channels_rules.scan(/<#(\w+)\|([^>]*)>/)
106
+ if channels_arr.size == 0
107
+ channels_arr = []
108
+ channels_rules.scan(/([^\s]+)/).each do |cn|
109
+ cna = cn.join.gsub('#','')
110
+ if @channels_name.key?(cna)
111
+ channels_arr << [cna, @channels_name[cna]]
112
+ else
113
+ channels_arr << [@channels_id[cna], cna]
114
+ end
115
+ end
116
+ else
117
+ channels_arr.each do |row|
118
+ row[0] = @channels_id[row[1]] if row[0] == ''
119
+ row[1] = @channels_name[row[0]] if row[1] == ''
120
+ end
121
+ end
122
+
123
+ # to be treated only on the bots of the requested channels
124
+ channels_arr.each do |tcid, tcname|
125
+ if @channel_id == tcid
126
+ data.text = data_text
127
+ typem = :on_call
128
+ channel_rules = tcid
129
+ channel_rules_name = tcname
130
+ break
131
+ elsif @bots_created.key?(@channel_id) and @bots_created[@channel_id][:extended].include?(tcname)
132
+ data.text = data_text
133
+ typem = :on_call
134
+ channel_rules = @channel_id
135
+ channel_rules_name = @channels_name[@channel_id]
136
+ break
137
+ end
138
+ end
139
+
140
+ elsif data.channel == @master_bot_id
141
+ if config.on_master_bot #only to be treated on master bot channel
142
+ typem = :on_master
143
+ end
144
+ elsif @bots_created.key?(data.channel)
145
+ if @channel_id == data.channel #only to be treated by the bot on the channel
146
+ typem = :on_bot
147
+ end
148
+ elsif data.channel[0] == "D" #Direct message
149
+ get_rules_imported()
150
+ if @rules_imported.key?(user_info.name) && @rules_imported[user_info.name].key?(user_info.name) and
151
+ @bots_created.key?(@rules_imported[user_info.name][user_info.name])
152
+ if @channel_id == @rules_imported[user_info.name][user_info.name]
153
+ #only to be treated by the channel we are 'using'
154
+ typem = :on_dm
155
+ end
156
+ elsif config.on_master_bot
157
+ #only to be treated by master bot
102
158
  typem = :on_dm
103
159
  end
104
- elsif config.on_master_bot
105
- #only to be treated by master bot
106
- typem = :on_dm
107
- end
108
- elsif data.channel[0] == "C" or data.channel[0] == "G"
109
- #only to be treated on the channel of the bot. excluding running ruby
110
- if !config.on_master_bot and @bots_created.key?(@channel_id) and @bots_created[@channel_id][:extended].include?(@channels_name[data.channel]) and
111
- !data.text.match?(/^!?\s*(ruby|code)\s+/) and !data.text.match?(/^!?!?\s*(ruby|code)\s+/) and !data.text.match?(/^\^?\s*(ruby|code)\s+/)
112
- typem = :on_extended
113
- elsif config.on_master_bot and (data.text.match?(/^!?\s*(ruby|code)\s+/) or data.text.match?(/^!?!?\s*(ruby|code)\s+/) or data.text.match?(/^\^?\s*(ruby|code)\s+/) )
114
- #or in case of running ruby, the master bot
160
+ elsif data.channel[0] == "C" or data.channel[0] == "G"
161
+ #only to be treated on the channel of the bot. excluding running ruby
162
+ if !config.on_master_bot and @bots_created.key?(@channel_id) and @bots_created[@channel_id][:extended].include?(@channels_name[data.channel]) and
163
+ !data.text.match?(/^!?\s*(ruby|code)\s+/) and !data.text.match?(/^!?!?\s*(ruby|code)\s+/) and !data.text.match?(/^\^?\s*(ruby|code)\s+/)
164
+ typem = :on_extended
165
+ elsif config.on_master_bot and (data.text.match?(/^!?\s*(ruby|code)\s+/) or data.text.match?(/^!?!?\s*(ruby|code)\s+/) or data.text.match?(/^\^?\s*(ruby|code)\s+/) )
166
+ #or in case of running ruby, the master bot
167
+ @bots_created.each do |k, v|
168
+ if v.key?(:extended) and v[:extended].include?(@channels_name[data.channel])
169
+ typem = :on_extended
170
+ break
171
+ end
172
+ end
173
+ end
174
+ extended = false
115
175
  @bots_created.each do |k, v|
116
176
  if v.key?(:extended) and v[:extended].include?(@channels_name[data.channel])
117
- typem = :on_extended
177
+ extended = true
118
178
  break
119
179
  end
120
180
  end
121
- end
122
- if data.channel[0] == "G" and config.on_master_bot and typem != :on_extended #private group
123
- typem = :on_pg
124
- end
125
- end
126
- end
127
- unless typem == :dont_treat
128
- if (Time.now - @last_activity_check) > 60 * 30 #every 30 minutes
129
- @last_activity_check = Time.now
130
- @listening.each do |k,v|
131
- v.each do |kk, vv|
132
- @listening[k].delete(kk) if (Time.now - vv) > 60 * 30
181
+ if data.channel[0] == "G" and config.on_master_bot and !extended #private group
182
+ typem = :on_pg
183
+ elsif data.channel[0] == 'C' and config.on_master_bot and !extended #public group
184
+ typem = :on_pub
133
185
  end
134
- @listening.delete(k) if @listening[k].empty?
135
186
  end
136
187
  end
137
- begin
138
- #todo: when changed @questions user_id then move user_info inside the ifs to avoid calling it when not necessary
139
- user_info = get_user_info(data.user)
188
+ load "#{config.path}/rules/general_commands.rb" if File.exist?("#{config.path}/rules/general_commands.rb") and @datetime_general_commands != File.mtime("#{config.path}/rules/general_commands.rb")
140
189
 
141
- #user_info.user.id = data.user #todo: remove this line when slack issue with Wxxxx Uxxxx fixed
142
- data.user = user_info.user.id #todo: remove this line when slack issue with Wxxxx Uxxxx fixed
143
- if data.thread_ts.nil?
144
- qdest = dest
145
- else
146
- qdest = data.thread_ts
190
+ unless typem == :dont_treat or user_info.nil?
191
+ if (Time.now - @last_activity_check) > 60 * 30 #every 30 minutes
192
+ @last_activity_check = Time.now
193
+ @listening.each do |k,v|
194
+ v.each do |kk, vv|
195
+ @listening[k].delete(kk) if (Time.now - vv) > 60 * 30
196
+ end
197
+ @listening.delete(k) if @listening[k].empty?
198
+ end
147
199
  end
148
- if !answer(user_info.user.name, qdest).empty?
149
- if data.text.match?(/^\s*(Bye|Bæ|Good\sBye|Adiós|Ciao|Bless|Bless\sBless|Adeu)\s(#{@salutations.join("|")})\s*$/i)
150
- answer_delete(user_info.user.name, qdest)
151
- command = data.text
200
+ begin
201
+ #user_info.id = data.user #todo: remove this line when slack issue with Wxxxx Uxxxx fixed
202
+ data.user = user_info.id #todo: remove this line when slack issue with Wxxxx Uxxxx fixed
203
+ if data.thread_ts.nil?
204
+ qdest = dest
152
205
  else
153
- command = answer(user_info.user.name, qdest)
154
- @answer[user_info.user.name][qdest] = data.text
155
- @questions[user_info.user.name] = data.text # to be backwards compatible #todo remove it when 2.0
206
+ qdest = data.thread_ts
156
207
  end
157
- elsif @repl_sessions.key?(user_info.user.name) and data.channel==@repl_sessions[user_info.user.name][:dest] and
158
- ((@repl_sessions[user_info.user.name][:on_thread] and data.thread_ts == @repl_sessions[user_info.user.name][:thread_ts]) or
159
- (!@repl_sessions[user_info.user.name][:on_thread] and data.thread_ts.to_s == '' ))
160
-
161
- if data.text.match(/^\s*```(.*)```\s*$/im)
162
- @repl_sessions[user_info.user.name][:command] = $1
163
- else
164
- @repl_sessions[user_info.user.name][:command] = data.text
208
+ if !answer(user_info.name, qdest).empty?
209
+ if data.text.match?(/\A\s*(Bye|Bæ|Good\sBye|Adiós|Ciao|Bless|Bless\sBless|Adeu)\s(#{@salutations.join("|")})\s*$/i)
210
+ answer_delete(user_info.name, qdest)
211
+ command = data.text
212
+ else
213
+ command = answer(user_info.name, qdest)
214
+ @answer[user_info.name][qdest] = data.text
215
+ @questions[user_info.name] = data.text # to be backwards compatible #todo remove it when 2.0
216
+ end
217
+ elsif @repl_sessions.key?(user_info.name) and data.channel==@repl_sessions[user_info.name][:dest] and
218
+ ((@repl_sessions[user_info.name][:on_thread] and data.thread_ts == @repl_sessions[user_info.name][:thread_ts]) or
219
+ (!@repl_sessions[user_info.name][:on_thread] and data.thread_ts.to_s == '' ))
220
+
221
+ if data.text.match(/^\s*```(.*)```\s*$/im)
222
+ @repl_sessions[user_info.name][:command] = $1
223
+ else
224
+ @repl_sessions[user_info.name][:command] = data.text
225
+ end
226
+ command = 'repl'
227
+ else
228
+ command = data.text
165
229
  end
166
- command = 'repl'
167
- else
168
- command = data.text
169
- end
170
-
171
- #when added special characters on the message
172
- if command.match(/\A\s*```(.*)```\s*\z/im)
173
- command = $1
174
- elsif command.size >= 2 and
175
- ((command[0] == "`" and command[-1] == "`") or (command[0] == "*" and command[-1] == "*") or (command[0] == "_" and command[-1] == "_"))
176
- command = command[1..-2]
177
- end
178
230
 
179
- #ruby file attached
180
- if !data.files.nil? and data.files.size == 1 and
181
- (command.match?(/^(ruby|code)\s*$/) or (command.match?(/^\s*$/) and data.files[0].filetype == "ruby") or
182
- (typem == :on_call and data.files[0].filetype == "ruby"))
183
- res = Faraday.new("https://files.slack.com", headers: { "Authorization" => "Bearer #{config[:token]}" }).get(data.files[0].url_private)
184
- command += " ruby" if command != "ruby"
185
- command = "#{command} #{res.body.to_s.force_encoding("UTF-8")}"
186
- end
231
+ #when added special characters on the message
232
+ if command.match(/\A\s*```(.*)```\s*\z/im)
233
+ command = $1
234
+ elsif command.size >= 2 and
235
+ ((command[0] == "`" and command[-1] == "`") or (command[0] == "*" and command[-1] == "*") or (command[0] == "_" and command[-1] == "_"))
236
+ command = command[1..-2]
237
+ end
187
238
 
188
- if typem == :on_call
189
- command = "!" + command unless command[0] == "!" or command.match?(/^\s*$/) or command[0] == "^"
239
+ #ruby file attached
240
+ if !data.files.nil? and data.files.size == 1 and
241
+ (command.match?(/^(ruby|code)\s*$/) or (command.match?(/^\s*$/) and data.files[0].filetype == "ruby") or
242
+ (typem == :on_call and data.files[0].filetype == "ruby"))
243
+ res = Faraday.new("https://files.slack.com", headers: { "Authorization" => "Bearer #{config[:token]}" }).get(data.files[0].url_private)
244
+ command += " ruby" if command != "ruby"
245
+ command = "#{command} #{res.body.to_s.force_encoding("UTF-8")}"
246
+ end
247
+ if typem == :on_call
248
+ command = "!" + command unless command[0] == "!" or command.match?(/^\s*$/) or command[0] == "^"
190
249
 
191
- #todo: add pagination for case more than 1000 channels on the workspace
192
- channels = get_channels()
193
- channel_found = channels.detect { |c| c.name == channel_rules_name }
194
- members = get_channel_members(@channels_id[channel_rules_name]) unless channel_found.nil?
195
- if channel_found.nil?
196
- @logger.fatal "Not possible to find the channel #{channel_rules_name}"
197
- elsif channel_found.name == config.master_channel
198
- respond "You cannot use the rules from Master Channel on any other channel.", data.channel
199
- elsif @status != :on
200
- respond "The bot in that channel is not :on", data.channel
201
- elsif data.user == channel_found.creator or members.include?(data.user)
202
- process_first(user_info.user, command, dest, channel_rules, typem, data.files, data.ts, data.thread_ts, data.routine)
203
- else
204
- respond "You need to join the channel <##{channel_found.id}> to be able to use the rules.", data.channel
250
+ #todo: add pagination for case more than 1000 channels on the workspace
251
+ channels = get_channels()
252
+ channel_found = channels.detect { |c| c.name == channel_rules_name }
253
+ members = get_channel_members(@channels_id[channel_rules_name]) unless channel_found.nil?
254
+ if channel_found.nil?
255
+ @logger.fatal "Not possible to find the channel #{channel_rules_name}"
256
+ elsif channel_found.name == config.master_channel
257
+ respond "You cannot use the rules from Master Channel on any other channel.", data.channel
258
+ elsif @status != :on
259
+ respond "The bot in that channel is not :on", data.channel
260
+ elsif data.user == channel_found.creator or members.include?(data.user)
261
+ process_first(user_info, command, dest, channel_rules, typem, data.files, data.ts, data.thread_ts, data.routine, data.routine_name, data.routine_type, command_orig)
262
+ else
263
+ respond "You need to join the channel <##{channel_found.id}> to be able to use the rules.", data.channel
264
+ end
265
+ elsif config.on_master_bot and typem == :on_extended and
266
+ command.size > 0 and command[0] != "-"
267
+ # to run ruby only from the master bot for the case more than one extended
268
+ process_first(user_info, command, dest, @channel_id, typem, data.files, data.ts, data.thread_ts, data.routine, data.routine_name, data.routine_type, command_orig)
269
+ elsif !config.on_master_bot and @bots_created[@channel_id].key?(:extended) and
270
+ @bots_created[@channel_id][:extended].include?(@channels_name[data.channel]) and
271
+ command.size > 0 and command[0] != "-"
272
+ process_first(user_info, command, dest, @channel_id, typem, data.files, data.ts, data.thread_ts, data.routine, data.routine_name, data.routine_type, command_orig)
273
+ elsif (dest[0] == "D" or @channel_id == data.channel or data.user == config[:nick_id]) and
274
+ command.size > 0 and command[0] != "-"
275
+ process_first(user_info, command, dest, data.channel, typem, data.files, data.ts, data.thread_ts, data.routine, data.routine_name, data.routine_type, command_orig)
276
+ # if @botname on #channel_rules: do something
277
+ elsif typem == :on_pub or typem == :on_pg
278
+ process_first(user_info, command, dest, channel_rules, typem, data.files, data.ts, data.thread_ts, data.routine, data.routine_name, data.routine_type, command_orig)
205
279
  end
206
- elsif config.on_master_bot and typem == :on_extended and
207
- command.size > 0 and command[0] != "-"
208
- # to run ruby only from the master bot for the case more than one extended
209
- process_first(user_info.user, command, dest, @channel_id, typem, data.files, data.ts, data.thread_ts, data.routine)
210
- elsif !config.on_master_bot and @bots_created[@channel_id].key?(:extended) and
211
- @bots_created[@channel_id][:extended].include?(@channels_name[data.channel]) and
212
- command.size > 0 and command[0] != "-"
213
- process_first(user_info.user, command, dest, @channel_id, typem, data.files, data.ts, data.thread_ts, data.routine)
214
- elsif (dest[0] == "D" or @channel_id == data.channel or data.user == config[:nick_id]) and
215
- command.size > 0 and command[0] != "-"
216
- process_first(user_info.user, command, dest, data.channel, typem, data.files, data.ts, data.thread_ts, data.routine)
217
- # if @botname on #channel_rules: do something
280
+ rescue Exception => stack
281
+ @logger.fatal stack
218
282
  end
219
- rescue Exception => stack
220
- @logger.fatal stack
221
- end
222
- else
223
- if !config.on_master_bot and !dest.nil? and (data.channel == @master_bot_id or dest[0] == "D") and
224
- data.text.match?(/^\s*bot\s+status\s*$/i) and @admin_users_id.include?(data.user)
225
- respond "ping from #{config.channel}", dest
226
- elsif !config.on_master_bot and !dest.nil? and data.user == config[:nick_id] and dest == @master_bot_id
227
- # to treat on other bots the status messages populated on master bot
228
- case data.text
229
- when /From now on I'll be on maintenance status/i
230
- sleep 2
231
- if File.exist?("#{config.path}/config_tmp.status")
232
- file_cts = IO.readlines("#{config.path}/config_tmp.status").join
233
- unless file_cts.to_s() == ""
234
- file_cts = eval(file_cts)
235
- if file_cts.is_a?(Hash) and file_cts.key?(:on_maintenance)
236
- config.on_maintenance = file_cts.on_maintenance
283
+
284
+ else
285
+ @logger.warn "Pay attention there is no user on users with id #{data.user}" if user_info.nil?
286
+ if !config.on_master_bot and !dest.nil? and (data.channel == @master_bot_id or dest[0] == "D") and
287
+ data.text.match?(/^\s*(!|!!|\^)?\s*bot\s+status\s*$/i) and @admin_users_id.include?(data.user)
288
+ respond "ping from #{config.channel}", dest
289
+ elsif !config.on_master_bot and !dest.nil? and data.user == config[:nick_id] and dest == @master_bot_id
290
+ # to treat on other bots the status messages populated on master bot
291
+ case data.text
292
+ when /General message has been set\./i, /General message won't be displayed anymore./i
293
+ sleep 2
294
+ if File.exist?("#{config.path}/config_tmp.status")
295
+ file_cts = IO.readlines("#{config.path}/config_tmp.status").join
296
+ unless file_cts.to_s() == ""
297
+ file_cts = eval(file_cts)
298
+ if file_cts.is_a?(Hash) and file_cts.key?(:general_message)
299
+ config.general_message = file_cts.general_message
300
+ end
237
301
  end
238
302
  end
239
- end
240
- when /From now on I won't be on maintenance/i
241
- sleep 2
242
- if File.exist?("#{config.path}/config_tmp.status")
243
- file_cts = IO.readlines("#{config.path}/config_tmp.status").join
244
- unless file_cts.to_s() == ""
245
- file_cts = eval(file_cts)
246
- if file_cts.is_a?(Hash) and file_cts.key?(:on_maintenance)
247
- config.on_maintenance = file_cts.on_maintenance
303
+ when /From now on I'll be on maintenance status/i
304
+ sleep 2
305
+ if File.exist?("#{config.path}/config_tmp.status")
306
+ file_cts = IO.readlines("#{config.path}/config_tmp.status").join
307
+ unless file_cts.to_s() == ""
308
+ file_cts = eval(file_cts)
309
+ if file_cts.is_a?(Hash) and file_cts.key?(:on_maintenance)
310
+ config.on_maintenance = file_cts.on_maintenance
311
+ config.on_maintenance_message = file_cts.on_maintenance_message
312
+ end
248
313
  end
249
314
  end
250
- end
251
-
252
- when /^Bot has been (closed|killed) by/i
253
- sleep 2
254
- get_bots_created()
255
- when /^Changed status on (.+) to :(.+)/i
256
- sleep 2
257
- get_bots_created()
258
- when /extended the rules from (.+) to be used on (.+)\.$/i
259
- sleep 2
260
- get_bots_created()
261
- when /removed the access to the rules of (.+) from (.+)\.$/i
262
- sleep 2
263
- get_bots_created()
264
- when /global shortcut added/
265
- sleep 2
266
- if File.exist?("#{config.path}/shortcuts/shortcuts_global.rb")
267
- file_sc = IO.readlines("#{config.path}/shortcuts/shortcuts_global.rb").join
268
- unless file_sc.to_s() == ""
269
- @shortcuts_global = eval(file_sc)
315
+ when /From now on I won't be on maintenance/i
316
+ sleep 2
317
+ if File.exist?("#{config.path}/config_tmp.status")
318
+ file_cts = IO.readlines("#{config.path}/config_tmp.status").join
319
+ unless file_cts.to_s() == ""
320
+ file_cts = eval(file_cts)
321
+ if file_cts.is_a?(Hash) and file_cts.key?(:on_maintenance)
322
+ config.on_maintenance = file_cts.on_maintenance
323
+ config.on_maintenance_message = file_cts.on_maintenance_message
324
+ end
325
+ end
270
326
  end
271
- end
272
- when /global shortcut deleted/
273
- sleep 2
274
- if File.exist?("#{config.path}/shortcuts/shortcuts_global.rb")
275
- file_sc = IO.readlines("#{config.path}/shortcuts/shortcuts_global.rb").join
276
- unless file_sc.to_s() == ""
277
- @shortcuts_global = eval(file_sc)
327
+
328
+ when /^Bot has been (closed|killed) by/i
329
+ sleep 2
330
+ get_bots_created()
331
+ when /^Changed status on (.+) to :(.+)/i
332
+ sleep 2
333
+ get_bots_created()
334
+ when /extended the rules from (.+) to be used on (.+)\.$/i
335
+ sleep 2
336
+ get_bots_created()
337
+ when /removed the access to the rules of (.+) from (.+)\.$/i
338
+ sleep 2
339
+ get_bots_created()
340
+ when /global shortcut added/
341
+ sleep 2
342
+ if File.exist?("#{config.path}/shortcuts/shortcuts_global.yaml")
343
+ @shortcuts_global = YAML.load(File.read("#{config.path}/shortcuts/shortcuts_global.yaml"))
344
+ end
345
+ when /global shortcut deleted/
346
+ sleep 2
347
+ if File.exist?("#{config.path}/shortcuts/shortcuts_global.yaml")
348
+ @shortcuts_global = YAML.load(File.read("#{config.path}/shortcuts/shortcuts_global.yaml"))
278
349
  end
279
350
  end
280
351
  end
281
352
  end
353
+ rescue Exception => stack
354
+ @logger.fatal stack
282
355
  end
283
356
  end
284
357
  end
@@ -50,8 +50,8 @@ class SlackSmartBot
50
50
  elsif !explanation_done and line.match?(/^\s+[^`].+\s*/i)
51
51
  resf += "\n#{line}"
52
52
  explanation_done = true
53
- elsif !example_done and line.match?(/^\s*_.+_\s*/i)
54
- resf += "\n Example: #{line}"
53
+ elsif !example_done and line.match?(/^\s*>?\s*_.+_\s*$/i)
54
+ resf += "\n Example: #{line.gsub(/^\s*>/,'')}"
55
55
  example_done = true
56
56
  end
57
57
  end