slack-smart-bot 1.14.2 → 1.15.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (176) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +222 -37
  3. data/img/chat_gpt.png +0 -0
  4. data/img/chat_gpt_session.png +0 -0
  5. data/img/chat_gpt_share.png +0 -0
  6. data/img/command_add_sc.png +0 -0
  7. data/img/command_bot_help_echo.png +0 -0
  8. data/img/command_loop.png +0 -0
  9. data/img/command_my_timeoff.png +0 -0
  10. data/img/command_recap.png +0 -0
  11. data/img/command_repl1.png +0 -0
  12. data/img/command_repl2.png +0 -0
  13. data/img/command_ruby.png +0 -0
  14. data/img/command_run_repl.png +0 -0
  15. data/img/command_see_announcements.png +0 -0
  16. data/img/command_see_statuses.png +0 -0
  17. data/img/command_see_team.png +0 -0
  18. data/img/command_summarize.png +0 -0
  19. data/img/commands_inline.png +0 -0
  20. data/img/commands_on_demand.png +0 -0
  21. data/img/commands_on_external_call.png +0 -0
  22. data/img/image_editing.png +0 -0
  23. data/img/image_generation.png +0 -0
  24. data/img/image_variations.png +0 -0
  25. data/img/openai-300.png +0 -0
  26. data/img/openai.png +0 -0
  27. data/img/slack-300.png +0 -0
  28. data/img/slack.png +0 -0
  29. data/img/smart-bot-150.png +0 -0
  30. data/img/smart-bot-profile-pic-2.png +0 -0
  31. data/img/smart-bot-profile-pic.png +0 -0
  32. data/img/smart-bot.png +0 -0
  33. data/img/whisper.png +0 -0
  34. data/lib/slack/smart-bot/ai/open_ai/connect.rb +165 -43
  35. data/lib/slack/smart-bot/ai/open_ai/models.rb +61 -9
  36. data/lib/slack/smart-bot/ai/open_ai/send_gpt_chat.rb +67 -11
  37. data/lib/slack/smart-bot/ai/open_ai/send_image_edit.rb +4 -3
  38. data/lib/slack/smart-bot/ai/open_ai/send_image_generation.rb +4 -4
  39. data/lib/slack/smart-bot/ai/open_ai/send_image_variation.rb +4 -3
  40. data/lib/slack/smart-bot/ai/open_ai/whisper_transcribe.rb +4 -3
  41. data/lib/slack/smart-bot/comm/ask.rb +20 -8
  42. data/lib/slack/smart-bot/comm/dont_understand.rb +2 -2
  43. data/lib/slack/smart-bot/comm/event_hello.rb +30 -1
  44. data/lib/slack/smart-bot/comm/get_channel_members.rb +2 -1
  45. data/lib/slack/smart-bot/comm/get_presence.rb +1 -0
  46. data/lib/slack/smart-bot/comm/get_smartbot_team_info.rb +10 -0
  47. data/lib/slack/smart-bot/comm/get_user_info.rb +45 -6
  48. data/lib/slack/smart-bot/comm/get_users.rb +8 -1
  49. data/lib/slack/smart-bot/comm/respond.rb +225 -196
  50. data/lib/slack/smart-bot/comm/send_msg_channel.rb +2 -2
  51. data/lib/slack/smart-bot/comm/send_msg_user.rb +10 -9
  52. data/lib/slack/smart-bot/comm/unreact.rb +2 -2
  53. data/lib/slack/smart-bot/comm.rb +1 -0
  54. data/lib/slack/smart-bot/commands/general/add_admin.rb +16 -6
  55. data/lib/slack/smart-bot/commands/general/add_announcement.rb +3 -3
  56. data/lib/slack/smart-bot/commands/general/add_vacation.rb +28 -12
  57. data/lib/slack/smart-bot/commands/general/ai/open_ai/open_ai_chat.rb +272 -23
  58. data/lib/slack/smart-bot/commands/general/ai/open_ai/open_ai_chat_add_collaborator.rb +42 -0
  59. data/lib/slack/smart-bot/commands/general/ai/open_ai/open_ai_chat_copy_session.rb +89 -0
  60. data/lib/slack/smart-bot/commands/general/ai/open_ai/open_ai_chat_delete_session.rb +45 -0
  61. data/lib/slack/smart-bot/commands/general/ai/open_ai/open_ai_chat_get_prompts.rb +41 -0
  62. data/lib/slack/smart-bot/commands/general/ai/open_ai/open_ai_chat_list_sessions.rb +81 -0
  63. data/lib/slack/smart-bot/commands/general/ai/open_ai/open_ai_chat_share_session.rb +52 -0
  64. data/lib/slack/smart-bot/commands/general/ai/open_ai/open_ai_chat_use_model.rb +52 -0
  65. data/lib/slack/smart-bot/commands/general/ai/open_ai/open_ai_edit_image.rb +14 -11
  66. data/lib/slack/smart-bot/commands/general/ai/open_ai/open_ai_generate_image.rb +15 -11
  67. data/lib/slack/smart-bot/commands/general/ai/open_ai/open_ai_models.rb +29 -17
  68. data/lib/slack/smart-bot/commands/general/ai/open_ai/open_ai_variations_image.rb +16 -13
  69. data/lib/slack/smart-bot/commands/general/ai/open_ai/open_ai_whisper.rb +13 -7
  70. data/lib/slack/smart-bot/commands/general/allow_access.rb +8 -4
  71. data/lib/slack/smart-bot/commands/general/bot_help.rb +24 -10
  72. data/lib/slack/smart-bot/commands/general/bye_bot.rb +9 -5
  73. data/lib/slack/smart-bot/commands/general/delete_announcement.rb +2 -1
  74. data/lib/slack/smart-bot/commands/general/delete_share.rb +2 -1
  75. data/lib/slack/smart-bot/commands/general/deny_access.rb +1 -1
  76. data/lib/slack/smart-bot/commands/general/get_smartbot_readme.rb +15 -0
  77. data/lib/slack/smart-bot/commands/general/hi_bot.rb +10 -4
  78. data/lib/slack/smart-bot/commands/general/personal_settings.rb +26 -8
  79. data/lib/slack/smart-bot/commands/general/poster.rb +26 -2
  80. data/lib/slack/smart-bot/commands/general/public_holidays.rb +14 -24
  81. data/lib/slack/smart-bot/commands/general/recap.rb +399 -0
  82. data/lib/slack/smart-bot/commands/general/remove_admin.rb +19 -9
  83. data/lib/slack/smart-bot/commands/general/remove_vacation.rb +23 -6
  84. data/lib/slack/smart-bot/commands/general/see_access.rb +2 -1
  85. data/lib/slack/smart-bot/commands/general/see_admins.rb +8 -4
  86. data/lib/slack/smart-bot/commands/general/see_announcements.rb +5 -5
  87. data/lib/slack/smart-bot/commands/general/see_favorite_commands.rb +4 -4
  88. data/lib/slack/smart-bot/commands/general/see_shares.rb +1 -1
  89. data/lib/slack/smart-bot/commands/general/see_vacations.rb +34 -17
  90. data/lib/slack/smart-bot/commands/general/set_public_holidays.rb +4 -2
  91. data/lib/slack/smart-bot/commands/general/share_messages.rb +3 -3
  92. data/lib/slack/smart-bot/commands/general/summarize.rb +191 -0
  93. data/lib/slack/smart-bot/commands/general/teams/add_team.rb +4 -8
  94. data/lib/slack/smart-bot/commands/general/teams/delete_team.rb +3 -3
  95. data/lib/slack/smart-bot/commands/general/teams/memos/add_memo_team.rb +34 -29
  96. data/lib/slack/smart-bot/commands/general/teams/memos/add_memo_team_comment.rb +1 -1
  97. data/lib/slack/smart-bot/commands/general/teams/memos/delete_memo_team.rb +6 -4
  98. data/lib/slack/smart-bot/commands/general/teams/memos/see_memo_team.rb +26 -15
  99. data/lib/slack/smart-bot/commands/general/teams/memos/see_memos_team.rb +33 -24
  100. data/lib/slack/smart-bot/commands/general/teams/memos/set_memo_status.rb +4 -4
  101. data/lib/slack/smart-bot/commands/general/teams/ping_team.rb +10 -8
  102. data/lib/slack/smart-bot/commands/general/teams/see_teams.rb +73 -61
  103. data/lib/slack/smart-bot/commands/general/teams/see_vacations_team.rb +28 -13
  104. data/lib/slack/smart-bot/commands/general/teams/update_team.rb +9 -9
  105. data/lib/slack/smart-bot/commands/general_bot_commands.rb +1152 -839
  106. data/lib/slack/smart-bot/commands/on_bot/add_shortcut.rb +18 -17
  107. data/lib/slack/smart-bot/commands/on_bot/admin/add_routine.rb +11 -9
  108. data/lib/slack/smart-bot/commands/on_bot/admin/remove_routine.rb +2 -0
  109. data/lib/slack/smart-bot/commands/on_bot/admin/run_routine.rb +1 -0
  110. data/lib/slack/smart-bot/commands/on_bot/admin/see_routines.rb +5 -3
  111. data/lib/slack/smart-bot/commands/on_bot/admin_master/delete_message.rb +2 -3
  112. data/lib/slack/smart-bot/commands/on_bot/admin_master/get_bot_logs.rb +2 -3
  113. data/lib/slack/smart-bot/commands/on_bot/admin_master/react_to.rb +2 -3
  114. data/lib/slack/smart-bot/commands/on_bot/admin_master/send_message.rb +7 -6
  115. data/lib/slack/smart-bot/commands/on_bot/admin_master/update_message.rb +2 -3
  116. data/lib/slack/smart-bot/commands/on_bot/delete_repl.rb +1 -1
  117. data/lib/slack/smart-bot/commands/on_bot/delete_shortcut.rb +21 -20
  118. data/lib/slack/smart-bot/commands/on_bot/general/bot_stats.rb +40 -7
  119. data/lib/slack/smart-bot/commands/on_bot/general/bot_status.rb +6 -2
  120. data/lib/slack/smart-bot/commands/on_bot/general/stop_using_rules.rb +7 -6
  121. data/lib/slack/smart-bot/commands/on_bot/general/suggest_command.rb +5 -4
  122. data/lib/slack/smart-bot/commands/on_bot/general/use_rules.rb +4 -3
  123. data/lib/slack/smart-bot/commands/on_bot/get_repl.rb +4 -4
  124. data/lib/slack/smart-bot/commands/on_bot/kill_repl.rb +1 -1
  125. data/lib/slack/smart-bot/commands/on_bot/repl.rb +109 -53
  126. data/lib/slack/smart-bot/commands/on_bot/repl_client.rb +35 -29
  127. data/lib/slack/smart-bot/commands/on_bot/run_repl.rb +5 -5
  128. data/lib/slack/smart-bot/commands/on_bot/see_repls.rb +1 -2
  129. data/lib/slack/smart-bot/commands/on_bot/see_shortcuts.rb +5 -4
  130. data/lib/slack/smart-bot/commands/on_extended/bot_rules.rb +22 -12
  131. data/lib/slack/smart-bot/commands/on_master/admin_master/exit_bot.rb +12 -7
  132. data/lib/slack/smart-bot/commands/on_master/admin_master/notify_message.rb +2 -2
  133. data/lib/slack/smart-bot/commands/on_master/admin_master/publish_announcements.rb +1 -1
  134. data/lib/slack/smart-bot/commands/on_master/admin_master/set_general_message.rb +5 -5
  135. data/lib/slack/smart-bot/commands/on_master/admin_master/set_maintenance.rb +5 -5
  136. data/lib/slack/smart-bot/commands/on_master/create_bot.rb +3 -3
  137. data/lib/slack/smart-bot/commands.rb +10 -0
  138. data/lib/slack/smart-bot/config.rb +126 -0
  139. data/lib/slack/smart-bot/listen.rb +12 -11
  140. data/lib/slack/smart-bot/process.rb +62 -55
  141. data/lib/slack/smart-bot/process_first.rb +106 -65
  142. data/lib/slack/smart-bot/treat_message.rb +79 -47
  143. data/lib/slack/smart-bot/utils/answer.rb +11 -3
  144. data/lib/slack/smart-bot/utils/answer_delete.rb +11 -3
  145. data/lib/slack/smart-bot/utils/check_vacations.rb +21 -3
  146. data/lib/slack/smart-bot/utils/create_routine_thread.rb +13 -13
  147. data/lib/slack/smart-bot/utils/display_calendar.rb +42 -8
  148. data/lib/slack/smart-bot/utils/encryption/decrypt.rb +16 -9
  149. data/lib/slack/smart-bot/utils/encryption/encrypt.rb +14 -11
  150. data/lib/slack/smart-bot/utils/find_user.rb +71 -0
  151. data/lib/slack/smart-bot/utils/get_access_channels.rb +22 -3
  152. data/lib/slack/smart-bot/utils/get_channels_name_and_id.rb +3 -4
  153. data/lib/slack/smart-bot/utils/get_command_ids.rb +5 -5
  154. data/lib/slack/smart-bot/utils/get_countries_candelarific.rb +18 -0
  155. data/lib/slack/smart-bot/utils/get_help.rb +21 -19
  156. data/lib/slack/smart-bot/utils/get_openai_sessions.rb +47 -0
  157. data/lib/slack/smart-bot/utils/get_personal_settings.rb +29 -3
  158. data/lib/slack/smart-bot/utils/get_rules_imported.rb +27 -6
  159. data/lib/slack/smart-bot/utils/get_shares.rb +1 -1
  160. data/lib/slack/smart-bot/utils/get_team_members.rb +4 -4
  161. data/lib/slack/smart-bot/utils/get_vacations.rb +15 -7
  162. data/lib/slack/smart-bot/utils/has_access.rb +10 -4
  163. data/lib/slack/smart-bot/utils/is_admin.rb +25 -17
  164. data/lib/slack/smart-bot/utils/local_time.rb +29 -0
  165. data/lib/slack/smart-bot/utils/save_stats.rb +5 -3
  166. data/lib/slack/smart-bot/utils/update_access_channels.rb +19 -3
  167. data/lib/slack/smart-bot/utils/update_openai_sessions.rb +42 -0
  168. data/lib/slack/smart-bot/utils/update_personal_settings.rb +11 -3
  169. data/lib/slack/smart-bot/utils/update_rules_imported.rb +18 -3
  170. data/lib/slack/smart-bot/utils/update_vacations.rb +5 -2
  171. data/lib/slack/smart-bot/utils/upgrade_to_use_team_ids.rb +276 -0
  172. data/lib/slack/smart-bot/utils.rb +6 -1
  173. data/lib/slack-smart-bot.rb +182 -76
  174. data/lib/slack-smart-bot_general_commands.rb +10 -9
  175. data/whats_new.txt +30 -13
  176. metadata +148 -20
@@ -1,16 +1,55 @@
1
1
  class SlackSmartBot
2
2
 
3
- def get_user_info(user)
3
+ def get_user_info(user, is_bot: false)
4
4
  begin
5
5
  if user.to_s.length>0
6
- if config.simulate and config.key?(:client)
7
- if user[0]=='@' #name
8
- client.web_client.users_info.select{|k, v| v[:user][:name] == user[1..-1]}.values[-1]
9
- else #id
6
+ if user[0]=='@' #name
7
+ user = user[1..-1]
8
+ is_name = true
9
+ else
10
+ is_name = false
11
+ end
12
+ if user.match?(/^[A-Z0-9]{7,11}_/) #team_id_user_name
13
+ team_id = user.split('_')[0]
14
+ user = user.split('_')[1..-1].join('_')
15
+ else
16
+ team_id = config.team_id
17
+ end
18
+ if config.simulate and config.key?(:client) #todo: add support for bots
19
+ if client.web_client.users_info.key?(user.to_sym) #id
10
20
  client.web_client.users_info[user.to_sym]
21
+ else #name
22
+ client.web_client.users_info.select{|k, v| v[:user][:name] == user and v[:user][:team_id] == team_id}.values[-1]
11
23
  end
12
24
  else
13
- client.web_client.users_info(user: user)
25
+ if is_bot
26
+ @logger.info "Getting bot info for <#{user}>"
27
+ begin
28
+ result = client.web_client.bots_info(bot: user)
29
+ rescue Exception => stack
30
+ @logger.warn stack
31
+ return nil
32
+ end
33
+ if !result.nil? and result.key?(:bot) and result[:bot].key?(:user_id)
34
+ user = result[:bot][:user_id]
35
+ is_name = false
36
+ else
37
+ return nil
38
+ end
39
+ end
40
+ #todo: see how to get user info using also the team_id
41
+ if is_name
42
+ result = client.web_client.users_info(user: "@#{user}")
43
+ else
44
+ result = client.web_client.users_info(user: user)
45
+ end
46
+ # in case of Enterprise Grid we use the enterprise_id as team_id and the enterprise_user id as user_id
47
+ if !result.nil? and result.key?(:user) and result[:user].key?(:enterprise_user) and result[:user][:enterprise_user].key?(:enterprise_id)
48
+ result[:user][:team_id] = result[:user][:enterprise_user][:enterprise_id]
49
+ result[:user][:id] = result[:user][:enterprise_user][:id]
50
+ end
51
+
52
+ return result
14
53
  end
15
54
  end
16
55
  rescue Exception => stack
@@ -4,7 +4,7 @@ class SlackSmartBot
4
4
  begin
5
5
  users = []
6
6
  cursor = nil
7
- if config.simulate
7
+ if config.simulate
8
8
  users = client.web_client.users_list
9
9
  else
10
10
  begin
@@ -16,6 +16,13 @@ class SlackSmartBot
16
16
  end until cursor.empty?
17
17
  users.flatten!
18
18
  end
19
+ users.each do |user|
20
+ # in case of Enterprise Grid we use the enterprise_id as team_id and the enterprise_user id as user_id
21
+ if user.key?(:enterprise_user) and user[:enterprise_user].key?(:enterprise_id)
22
+ user[:team_id] = user[:enterprise_user][:enterprise_id]
23
+ user[:id] = user[:enterprise_user][:id]
24
+ end
25
+ end
19
26
  return users
20
27
  rescue Exception => stack
21
28
  @logger.warn stack
@@ -2,241 +2,270 @@ class SlackSmartBot
2
2
  def respond(msg = "", dest = nil, unfurl_links: true, unfurl_media: true, thread_ts: "", web_client: true, blocks: [], dont_share: false, return_message: false, max_chars_per_message: 4000)
3
3
  result = true
4
4
  resp = nil
5
- if (msg.to_s != "" or !msg.to_s.match?(/^A\s*\z/) or !blocks.empty?) and Thread.current[:routine_type].to_s != "bgroutine"
6
- if !web_client.is_a?(TrueClass) and !web_client.is_a?(FalseClass)
7
- (!unfurl_links or !unfurl_media) ? web_client = true : web_client = false
8
- end
9
- begin
10
- msg = msg.to_s
11
- web_client = true if !blocks.empty?
12
5
 
13
- on_thread = Thread.current[:on_thread]
14
- if dest.nil? and Thread.current.key?(:dest)
15
- dest = Thread.current[:dest]
16
- elsif dest.is_a?(Symbol) and dest == :on_thread
17
- on_thread = true
18
- dest = Thread.current[:dest]
19
- elsif dest.is_a?(Symbol) and dest == :direct
20
- dest = Thread.current[:user].id
21
- end
22
- if thread_ts.to_s.match?(/^\d+\.\d+$/)
23
- on_thread = true
24
- #thread id
25
- elsif thread_ts.to_s.match?(/^p\d\d\d\d\d+$/)
26
- on_thread = true
27
- #a thread id taken from url fex: p1622549264010700
28
- thread_ts = thread_ts.scan(/(\d+)/).join
29
- thread_ts = "#{thread_ts[0..9]}.#{thread_ts[10..-1]}"
30
- else
31
- thread_ts = Thread.current[:thread_ts] if thread_ts == ""
32
- end
33
-
34
- dest = @channels_id[dest] if @channels_id.key?(dest) #it is a name of channel
6
+ if Thread.current.key?(:prompt) and !Thread.current[:prompt].empty? #don't send response to slack since chatgpt will get the response from stdout
7
+ Thread.current[:stdout] += "#{msg}\n"
8
+ return true
9
+ else
10
+ if (msg.to_s != "" or !msg.to_s.match?(/^A\s*\z/) or !blocks.empty?) and Thread.current[:routine_type].to_s != "bgroutine"
11
+ if !web_client.is_a?(TrueClass) and !web_client.is_a?(FalseClass)
12
+ (!unfurl_links or !unfurl_media) ? web_client = true : web_client = false
13
+ end
14
+ begin
15
+ msg = msg.to_s
16
+ web_client = true if !blocks.empty?
35
17
 
36
- on_thread ? txt_on_thread=':on_thread:' : txt_on_thread=''
37
-
38
- if blocks.empty?
39
- if !config.simulate #https://api.slack.com/docs/rate-limits
40
- msg.size > 500 ? wait = 0.5 : wait = 0.1
41
- sleep wait if Time.now <= (@last_respond + wait)
42
- else
43
- wait = 0
18
+ on_thread = Thread.current[:on_thread]
19
+ if dest.nil? and Thread.current.key?(:dest)
20
+ dest = Thread.current[:dest]
21
+ elsif dest.is_a?(Symbol) and dest == :on_thread
22
+ on_thread = true
23
+ dest = Thread.current[:dest]
24
+ elsif dest.is_a?(Symbol) and dest == :direct
25
+ dest = Thread.current[:user].id
44
26
  end
45
- msgs = [] # max of max_chars_per_message characters per message
46
- if max_chars_per_message.nil?
47
- txt = msg
27
+ if thread_ts.to_s.match?(/^\d+\.\d+$/)
28
+ on_thread = true
29
+ #thread id
30
+ elsif thread_ts.to_s.match?(/^p\d\d\d\d\d+$/)
31
+ on_thread = true
32
+ #a thread id taken from url fex: p1622549264010700
33
+ thread_ts = thread_ts.scan(/(\d+)/).join
34
+ thread_ts = "#{thread_ts[0..9]}.#{thread_ts[10..-1]}"
48
35
  else
49
- txt = ""
50
- msg.split("\n").each do |m|
51
- if (m + txt).size > max_chars_per_message
52
- unless txt == ""
53
- txt[0] = '.' if txt.match?(/\A\s\s\s/) #first line of message in slack don't show spaces at the begining so we force it by changing first char
54
- t = txt.chars.each_slice(max_chars_per_message).map(&:join)
55
- msgs << t
56
- txt = ""
57
- end
58
- end
59
- txt += (m + "\n")
60
- txt[0] = '.' if txt.match?(/\A\s\s\s/) #first line of message in slack don't show spaces at the begining so we force it by changing first char
61
- txt[0] = ". " if txt.match?(/\A\t/)
62
- end
36
+ thread_ts = Thread.current[:thread_ts] if thread_ts == ""
63
37
  end
64
- msgs << txt
65
- msgs.flatten!
66
- msgs.delete_if{|e| e.match?(/\A\s*\z/)}
67
- if dest.nil?
68
- if config[:simulate]
69
- open("#{config.path}/buffer_complete.log", "a") { |f|
70
- f.puts "|#{@channel_id}|#{config[:nick_id]}|#{config[:nick]}|#{txt_on_thread}#{msg}~~~"
71
- }
38
+
39
+ dest = @channels_id[dest] if @channels_id.key?(dest) #it is a name of channel
40
+
41
+ on_thread ? txt_on_thread=":on_thread:" : txt_on_thread=''
42
+
43
+ if blocks.empty?
44
+ if !config.simulate #https://api.slack.com/docs/rate-limits
45
+ msg.size > 500 ? wait = 0.5 : wait = 0.1
46
+ sleep wait if Time.now <= (@last_respond + wait)
72
47
  else
73
- if on_thread
74
- msgs.each do |msg|
75
- if web_client
76
- resp = client.web_client.chat_postMessage(channel: @channel_id, text: msg, as_user: true, unfurl_links: unfurl_links, unfurl_media: unfurl_media, thread_ts: thread_ts)
77
- else
78
- resp = client.message(channel: @channel_id, text: msg, as_user: true, thread_ts: thread_ts, unfurl_links: unfurl_links, unfurl_media: unfurl_media)
48
+ wait = 0
49
+ end
50
+ msgs = [] # max of max_chars_per_message characters per message
51
+ if max_chars_per_message.nil?
52
+ txt = msg
53
+ else
54
+ txt = ""
55
+ in_a_code_block = false
56
+ print_previous = false
57
+ all_lines = msg.split("\n")
58
+
59
+ all_lines.each_with_index do |m, i|
60
+ if m.match?(/^\s*```/)
61
+ in_a_code_block = !in_a_code_block
62
+ num_chars_code = 0
63
+ print_previous = false
64
+ if in_a_code_block
65
+ all_lines[i+1..-1].each do |l|
66
+ num_chars_code += l.size
67
+ break if l.match?(/^\s*```/)
68
+ end
69
+ if num_chars_code + (m + txt).size > max_chars_per_message
70
+ print_previous = true
71
+ end
79
72
  end
80
- sleep wait
81
- end
82
- else
83
- msgs.each do |msg|
84
- if web_client
85
- resp = client.web_client.chat_postMessage(channel: @channel_id, text: msg, as_user: true, unfurl_links: unfurl_links, unfurl_media: unfurl_media)
86
- else
87
- resp = client.message(channel: @channel_id, text: msg, as_user: true, unfurl_links: unfurl_links, unfurl_media: unfurl_media)
73
+ end
74
+ if ((m + txt).size > max_chars_per_message and !in_a_code_block) or print_previous
75
+ unless txt == ""
76
+ txt[0] = '.' if txt.match?(/\A\s\s\s/) #first line of message in slack don't show spaces at the begining so we force it by changing first char
77
+ if m.match?(/^\s*```\s*$/) and !in_a_code_block
78
+ txt += (m + "\n")
79
+ m = ""
80
+ end
81
+ t = txt.chars.each_slice(max_chars_per_message).map(&:join)
82
+ msgs << t
83
+ txt = ""
84
+ print_previous = false if print_previous
88
85
  end
89
- sleep wait
90
86
  end
87
+ txt += (m + "\n")
88
+ txt[0] = '.' if txt.match?(/\A\s\s\s/) #first line of message in slack don't show spaces at the begining so we force it by changing first char
89
+ txt[0] = ". " if txt.match?(/\A\t/)
91
90
  end
92
91
  end
93
- if config[:testing] and config.on_master_bot and !@buffered
94
- @buffered = true
95
- open("#{config.path}/buffer.log", "a") { |f|
96
- f.puts "|#{@channel_id}|#{config[:nick_id]}|#{config[:nick]}|#{msg}"
97
- }
98
- end
99
- elsif dest[0] == "C" or dest[0] == "G" # channel
100
- if config[:simulate]
101
- open("#{config.path}/buffer_complete.log", "a") { |f|
102
- f.puts "|#{dest}|#{config[:nick_id]}|#{config[:nick]}|#{txt_on_thread}#{msg}~~~"
103
- }
104
- else
105
- if on_thread
106
- msgs.each do |msg|
107
- if web_client
108
- resp = client.web_client.chat_postMessage(channel: dest, text: msg, as_user: true, unfurl_links: unfurl_links, unfurl_media: unfurl_media, thread_ts: thread_ts)
109
- else
110
- resp = client.message(channel: dest, text: msg, as_user: true, thread_ts: thread_ts, unfurl_links: unfurl_links, unfurl_media: unfurl_media)
92
+ msgs << txt
93
+ msgs.flatten!
94
+ msgs.delete_if{|e| e.match?(/\A\s*\z/)}
95
+ if dest.nil?
96
+ if config[:simulate]
97
+ open("#{config.path}/buffer_complete.log", "a") { |f|
98
+ f.puts "|#{@channel_id}|#{thread_ts}|#{config[:nick_id]}|#{config[:nick]}|#{txt_on_thread}#{msg}~~~"
99
+ }
100
+ else
101
+ if on_thread
102
+ msgs.each do |msg|
103
+ if web_client
104
+ resp = client.web_client.chat_postMessage(channel: @channel_id, text: msg, as_user: true, unfurl_links: unfurl_links, unfurl_media: unfurl_media, thread_ts: thread_ts)
105
+ else
106
+ resp = client.message(channel: @channel_id, text: msg, as_user: true, thread_ts: thread_ts, unfurl_links: unfurl_links, unfurl_media: unfurl_media)
107
+ end
108
+ sleep wait
109
+ end
110
+ else
111
+ msgs.each do |msg|
112
+ if web_client
113
+ resp = client.web_client.chat_postMessage(channel: @channel_id, text: msg, as_user: true, unfurl_links: unfurl_links, unfurl_media: unfurl_media)
114
+ else
115
+ resp = client.message(channel: @channel_id, text: msg, as_user: true, unfurl_links: unfurl_links, unfurl_media: unfurl_media)
116
+ end
117
+ sleep wait
111
118
  end
112
- sleep wait
113
119
  end
120
+ end
121
+ if config[:testing] and config.on_master_bot and !@buffered
122
+ @buffered = true
123
+ open("#{config.path}/buffer.log", "a") { |f|
124
+ f.puts "|#{@channel_id}|#{thread_ts}|#{config[:nick_id]}|#{config[:nick]}|#{msg}"
125
+ }
126
+ end
127
+ elsif dest[0] == "C" or dest[0] == "G" # channel
128
+ if config[:simulate]
129
+ open("#{config.path}/buffer_complete.log", "a") { |f|
130
+ f.puts "|#{dest}|#{thread_ts}|#{config[:nick_id]}|#{config[:nick]}|#{txt_on_thread}#{msg}~~~"
131
+ }
114
132
  else
115
- msgs.each do |msg|
116
- if web_client
117
- resp = client.web_client.chat_postMessage(channel: dest, text: msg, as_user: true, unfurl_links: unfurl_links, unfurl_media: unfurl_media)
118
- else
119
- resp = client.message(channel: dest, text: msg, as_user: true, unfurl_links: unfurl_links, unfurl_media: unfurl_media)
133
+ if on_thread
134
+ msgs.each do |msg|
135
+ if web_client
136
+ resp = client.web_client.chat_postMessage(channel: dest, text: msg, as_user: true, unfurl_links: unfurl_links, unfurl_media: unfurl_media, thread_ts: thread_ts)
137
+ else
138
+ resp = client.message(channel: dest, text: msg, as_user: true, thread_ts: thread_ts, unfurl_links: unfurl_links, unfurl_media: unfurl_media)
139
+ end
140
+ sleep wait
141
+ end
142
+ else
143
+ msgs.each do |msg|
144
+ if web_client
145
+ resp = client.web_client.chat_postMessage(channel: dest, text: msg, as_user: true, unfurl_links: unfurl_links, unfurl_media: unfurl_media)
146
+ else
147
+ resp = client.message(channel: dest, text: msg, as_user: true, unfurl_links: unfurl_links, unfurl_media: unfurl_media)
148
+ end
149
+ sleep wait
120
150
  end
121
- sleep wait
122
151
  end
123
152
  end
124
- end
125
- if config[:testing] and config.on_master_bot and !@buffered
126
- @buffered = true
127
- open("#{config.path}/buffer.log", "a") { |f|
128
- f.puts "|#{dest}|#{config[:nick_id]}|#{config[:nick]}|#{msg}"
129
- }
130
- end
131
- elsif dest[0] == "D" or dest[0] == "U" or dest[0] == "W" # Direct message
132
- msgs.each do |msg|
133
- resp = send_msg_user(dest, msg, on_thread, unfurl_links: unfurl_links, unfurl_media: unfurl_media)
134
- sleep wait
135
- end
136
- elsif dest[0] == "@"
137
- begin
138
- user_info = @users.select { |u| u.id == dest[1..-1] or u.name == dest[1..-1] or (u.key?(:enterprise_user) and u.enterprise_user.id == dest[1..-1]) }[-1]
153
+ if config[:testing] and config.on_master_bot and !@buffered
154
+ @buffered = true
155
+ open("#{config.path}/buffer.log", "a") { |f|
156
+ f.puts "|#{dest}|#{thread_ts}|#{config[:nick_id]}|#{config[:nick]}|#{msg}"
157
+ }
158
+ end
159
+ elsif dest[0] == "D" or dest[0] == "U" or dest[0] == "W" # Direct message
139
160
  msgs.each do |msg|
140
- resp = send_msg_user(user_info.id, msg, on_thread, unfurl_links: unfurl_links, unfurl_media: unfurl_media)
161
+ resp = send_msg_user(dest, msg, on_thread, unfurl_links: unfurl_links, unfurl_media: unfurl_media, thread_ts: thread_ts)
141
162
  sleep wait
142
163
  end
143
- rescue Exception => stack
144
- @logger.warn("user #{dest} not found.")
145
- @logger.warn stack
146
- if Thread.current.key?(:dest)
147
- respond("User #{dest} not found.")
164
+ elsif dest[0] == "@"
165
+ begin
166
+ user_info = @users.select { |u| u.id == dest[1..-1] or u.name == dest[1..-1] or (u.key?(:enterprise_user) and u.enterprise_user.id == dest[1..-1]) }[-1]
167
+ msgs.each do |msg|
168
+ resp = send_msg_user(user_info.id, msg, on_thread, unfurl_links: unfurl_links, unfurl_media: unfurl_media, thread_ts: thread_ts)
169
+ sleep wait
170
+ end
171
+ rescue Exception => stack
172
+ @logger.warn("user #{dest} not found.")
173
+ @logger.warn stack
174
+ if Thread.current.key?(:dest)
175
+ respond("User #{dest} not found.")
176
+ end
177
+ result = false
148
178
  end
179
+ else
180
+ @logger.warn("method respond not treated correctly: msg:#{msg} dest:#{dest}")
149
181
  result = false
150
182
  end
151
183
  else
152
- @logger.warn("method respond not treated correctly: msg:#{msg} dest:#{dest}")
153
- result = false
154
- end
155
- else
156
- wait = 0.1
157
- if dest.nil?
158
- if config[:simulate]
159
- open("#{config.path}/buffer_complete.log", "a") { |f|
160
- f.puts "|#{@channel_id}|#{config[:nick_id]}|#{config[:nick]}|#{txt_on_thread}#{blocks.join}~~~"
161
- }
162
- else
163
- if on_thread
164
- blocks.each_slice(40).to_a.each do |blockstmp|
165
- resp = client.web_client.chat_postMessage(channel: @channel_id, blocks: blockstmp, as_user: true, thread_ts: thread_ts)
166
- sleep wait
167
- end
184
+ wait = 0.1
185
+ if dest.nil?
186
+ if config[:simulate]
187
+ open("#{config.path}/buffer_complete.log", "a") { |f|
188
+ f.puts "|#{@channel_id}|#{thread_ts}|#{config[:nick_id]}|#{config[:nick]}|#{txt_on_thread}#{blocks.join}~~~"
189
+ }
168
190
  else
169
- blocks.each_slice(40).to_a.each do |blockstmp|
170
- resp = client.web_client.chat_postMessage(channel: @channel_id, blocks: blockstmp, as_user: true)
171
- sleep wait
191
+ if on_thread
192
+ blocks.each_slice(40).to_a.each do |blockstmp|
193
+ resp = client.web_client.chat_postMessage(channel: @channel_id, blocks: blockstmp, as_user: true, thread_ts: thread_ts)
194
+ sleep wait
195
+ end
196
+ else
197
+ blocks.each_slice(40).to_a.each do |blockstmp|
198
+ resp = client.web_client.chat_postMessage(channel: @channel_id, blocks: blockstmp, as_user: true)
199
+ sleep wait
200
+ end
172
201
  end
173
202
  end
174
- end
175
- if config[:testing] and config.on_master_bot and !@buffered
176
- @buffered = true
177
- open("#{config.path}/buffer.log", "a") { |f|
178
- f.puts "|#{@channel_id}|#{config[:nick_id]}|#{config[:nick]}|#{blocks.join}"
179
- }
180
- end
181
- elsif dest[0] == "C" or dest[0] == "G" # channel
182
- if config[:simulate]
183
- open("#{config.path}/buffer_complete.log", "a") { |f|
184
- f.puts "|#{dest}|#{config[:nick_id]}|#{config[:nick]}|#{txt_on_thread}#{blocks.join}~~~"
185
- }
186
- else
187
- if on_thread
188
- blocks.each_slice(40).to_a.each do |blockstmp|
189
- resp = client.web_client.chat_postMessage(channel: dest, blocks: blockstmp, as_user: true, thread_ts: thread_ts)
190
- sleep wait
191
- end
203
+ if config[:testing] and config.on_master_bot and !@buffered
204
+ @buffered = true
205
+ open("#{config.path}/buffer.log", "a") { |f|
206
+ f.puts "|#{@channel_id}|#{thread_ts}|#{config[:nick_id]}|#{config[:nick]}|#{blocks.join}"
207
+ }
208
+ end
209
+ elsif dest[0] == "C" or dest[0] == "G" # channel
210
+ if config[:simulate]
211
+ open("#{config.path}/buffer_complete.log", "a") { |f|
212
+ f.puts "|#{dest}|#{thread_ts}|#{config[:nick_id]}|#{config[:nick]}|#{txt_on_thread}#{blocks.join}~~~"
213
+ }
192
214
  else
193
- blocks.each_slice(40).to_a.each do |blockstmp|
194
- resp = client.web_client.chat_postMessage(channel: dest, blocks: blockstmp, as_user: true)
195
- sleep wait
215
+ if on_thread
216
+ blocks.each_slice(40).to_a.each do |blockstmp|
217
+ resp = client.web_client.chat_postMessage(channel: dest, blocks: blockstmp, as_user: true, thread_ts: thread_ts)
218
+ sleep wait
219
+ end
220
+ else
221
+ blocks.each_slice(40).to_a.each do |blockstmp|
222
+ resp = client.web_client.chat_postMessage(channel: dest, blocks: blockstmp, as_user: true)
223
+ sleep wait
224
+ end
196
225
  end
197
226
  end
198
- end
199
- if config[:testing] and config.on_master_bot and !@buffered
200
- @buffered = true
201
- open("#{config.path}/buffer.log", "a") { |f|
202
- f.puts "|#{dest}|#{config[:nick_id]}|#{config[:nick]}|#{blocks.join}"
203
- }
204
- end
205
- elsif dest[0] == "D" or dest[0] == "U" or dest[0] == "W" # Direct message
206
- blocks.each_slice(40).to_a.each do |blockstmp|
207
- resp = send_msg_user(dest, msg, on_thread, unfurl_links: unfurl_links, unfurl_media: unfurl_media, blocks: blockstmp)
208
- sleep wait
209
- end
210
- elsif dest[0] == "@"
211
- begin
212
- user_info = @users.select { |u| u.id == dest[1..-1] or (u.key?(:enterprise_user) and u.enterprise_user.id == dest[1..-1]) }[-1]
227
+ if config[:testing] and config.on_master_bot and !@buffered
228
+ @buffered = true
229
+ open("#{config.path}/buffer.log", "a") { |f|
230
+ f.puts "|#{dest}|#{thread_ts}|#{config[:nick_id]}|#{config[:nick]}|#{blocks.join}"
231
+ }
232
+ end
233
+ elsif dest[0] == "D" or dest[0] == "U" or dest[0] == "W" # Direct message
213
234
  blocks.each_slice(40).to_a.each do |blockstmp|
214
- resp = send_msg_user(user_info.id, msg, on_thread, unfurl_links: unfurl_links, unfurl_media: unfurl_media, blocks: blockstmp)
235
+ resp = send_msg_user(dest, msg, on_thread, unfurl_links: unfurl_links, unfurl_media: unfurl_media, blocks: blockstmp, thread_ts: thread_ts)
215
236
  sleep wait
216
237
  end
217
- rescue Exception => stack
218
- @logger.warn("user #{dest} not found.")
219
- @logger.warn stack
220
- if Thread.current.key?(:dest)
221
- respond("User #{dest} not found.")
238
+ elsif dest[0] == "@"
239
+ begin
240
+ user_info = @users.select { |u| u.id == dest[1..-1] or (u.key?(:enterprise_user) and u.enterprise_user.id == dest[1..-1]) }[-1]
241
+ blocks.each_slice(40).to_a.each do |blockstmp|
242
+ resp = send_msg_user(user_info.id, msg, on_thread, unfurl_links: unfurl_links, unfurl_media: unfurl_media, blocks: blockstmp, thread_ts: thread_ts)
243
+ sleep wait
244
+ end
245
+ rescue Exception => stack
246
+ @logger.warn("user #{dest} not found.")
247
+ @logger.warn stack
248
+ if Thread.current.key?(:dest)
249
+ respond("User #{dest} not found.")
250
+ end
251
+ result = false
222
252
  end
253
+ else
254
+ @logger.warn("method respond not treated correctly: msg:#{msg} dest:#{dest}")
223
255
  result = false
224
256
  end
225
- else
226
- @logger.warn("method respond not treated correctly: msg:#{msg} dest:#{dest}")
227
- result = false
228
257
  end
258
+ @last_respond = Time.now
259
+ rescue Exception => stack
260
+ @logger.warn stack
261
+ result = false
229
262
  end
230
- @last_respond = Time.now
231
- rescue Exception => stack
232
- @logger.warn stack
233
- result = false
234
263
  end
264
+ if Thread.current.key?(:routine) and Thread.current[:routine]
265
+ File.write("#{config.path}/routines/#{@channel_id}/#{Thread.current[:routine_name]}_output.txt", msg, mode: "a+")
266
+ end
267
+ result = resp if return_message
268
+ return result
235
269
  end
236
- if Thread.current.key?(:routine) and Thread.current[:routine]
237
- File.write("#{config.path}/routines/#{@channel_id}/#{Thread.current[:routine_name]}_output.txt", msg, mode: "a+")
238
- end
239
- result = resp if return_message
240
- return result
241
270
  end
242
271
  end
@@ -15,7 +15,7 @@ class SlackSmartBot
15
15
  end
16
16
  if config[:simulate]
17
17
  open("#{config.path}/buffer_complete.log", "a") { |f|
18
- f.puts "|#{channel_id}|#{config[:nick_id]}|#{config[:nick]}|#{msg}~~~"
18
+ f.puts "|#{channel_id}|#{Thread.current[:thread_ts]}|#{config[:nick_id]}|#{config[:nick]}|#{msg}~~~"
19
19
  }
20
20
  else
21
21
  if Thread.current[:on_thread]
@@ -27,7 +27,7 @@ class SlackSmartBot
27
27
  if config[:testing] and config.on_master_bot and !@buffered
28
28
  @buffered = true
29
29
  open("#{config.path}/buffer.log", "a") { |f|
30
- f.puts "|#{channel_id}|#{config[:nick_id]}|#{config[:nick]}|#{msg}"
30
+ f.puts "|#{channel_id}|#{Thread.current[:thread_ts]}|#{config[:nick_id]}|#{config[:nick]}|#{msg}"
31
31
  }
32
32
  end
33
33
  rescue Exception => stack
@@ -1,27 +1,28 @@
1
1
  class SlackSmartBot
2
2
 
3
3
  #to send messages without listening for a response to users
4
- def send_msg_user(id_user, msg='', on_thread=nil, unfurl_links: true, unfurl_media: true, blocks: [], web_client: true)
4
+ def send_msg_user(id_user, msg='', on_thread=nil, unfurl_links: true, unfurl_media: true, blocks: [], web_client: true, thread_ts: nil)
5
5
  resp = nil
6
6
  unless msg == "" and blocks.empty?
7
7
  begin
8
8
  on_thread = Thread.current[:on_thread] if on_thread.nil?
9
+ thread_ts = Thread.current[:thread_ts] if thread_ts.to_s == ""
9
10
  web_client = true if !blocks.empty? or !unfurl_links or !unfurl_media
10
11
  if id_user[0] == "D"
11
12
  if config[:simulate]
12
13
  open("#{config.path}/buffer_complete.log", "a") { |f|
13
- f.puts "|#{id_user}|#{config[:nick_id]}|#{config[:nick]}|#{msg}~~~"
14
+ f.puts "|#{id_user}|#{thread_ts}|#{config[:nick_id]}|#{config[:nick]}|#{msg}~~~"
14
15
  }
15
16
  else
16
17
  if web_client
17
18
  if on_thread
18
- resp = client.web_client.chat_postMessage(channel: id_user, text: msg, blocks: blocks, as_user: true, unfurl_links: unfurl_links, unfurl_media: unfurl_media, thread_ts: Thread.current[:thread_ts])
19
+ resp = client.web_client.chat_postMessage(channel: id_user, text: msg, blocks: blocks, as_user: true, unfurl_links: unfurl_links, unfurl_media: unfurl_media, thread_ts: thread_ts)
19
20
  else
20
21
  resp = client.web_client.chat_postMessage(channel: id_user, text: msg, blocks: blocks, as_user: true, unfurl_links: unfurl_links, unfurl_media: unfurl_media)
21
22
  end
22
23
  else
23
24
  if on_thread
24
- resp = client.message(channel: id_user, as_user: true, text: msg, thread_ts: Thread.current[:thread_ts], unfurl_links: unfurl_links, unfurl_media: unfurl_media)
25
+ resp = client.message(channel: id_user, as_user: true, text: msg, thread_ts: thread_ts, unfurl_links: unfurl_links, unfurl_media: unfurl_media)
25
26
  else
26
27
  resp = client.message(channel: id_user, as_user: true, text: msg, unfurl_links: unfurl_links, unfurl_media: unfurl_media)
27
28
  end
@@ -30,25 +31,25 @@ class SlackSmartBot
30
31
  if config[:testing] and config.on_master_bot and !@buffered
31
32
  @buffered = true
32
33
  open("#{config.path}/buffer.log", "a") { |f|
33
- f.puts "|#{id_user}|#{config[:nick_id]}|#{config[:nick]}|#{msg}#{blocks.join}"
34
+ f.puts "|#{id_user}|#{thread_ts}|#{config[:nick_id]}|#{config[:nick]}|#{msg}#{blocks.join}"
34
35
  }
35
36
  end
36
37
  else
37
38
  if config[:simulate]
38
39
  open("#{config.path}/buffer_complete.log", "a") { |f|
39
- f.puts "|#{DIRECT[id_user.to_sym].ubot}|#{config[:nick_id]}|#{config[:nick]}|#{msg}#{blocks.join}~~~"
40
+ f.puts "|#{DIRECT[id_user.to_sym].ubot}|#{thread_ts}|#{config[:nick_id]}|#{config[:nick]}|#{msg}#{blocks.join}~~~"
40
41
  }
41
42
  else
42
43
  im = client.web_client.conversations_open(users: id_user)
43
44
  if web_client
44
45
  if on_thread
45
- resp = client.web_client.chat_postMessage(channel: im["channel"]["id"], text: msg, blocks: blocks, as_user: true, unfurl_links: unfurl_links, unfurl_media: unfurl_media, thread_ts: Thread.current[:thread_ts])
46
+ resp = client.web_client.chat_postMessage(channel: im["channel"]["id"], text: msg, blocks: blocks, as_user: true, unfurl_links: unfurl_links, unfurl_media: unfurl_media, thread_ts: thread_ts)
46
47
  else
47
48
  resp = client.web_client.chat_postMessage(channel: im["channel"]["id"], text: msg, blocks: blocks, as_user: true, unfurl_links: unfurl_links, unfurl_media: unfurl_media)
48
49
  end
49
50
  else
50
51
  if on_thread
51
- resp = client.message(channel: im["channel"]["id"], as_user: true, text: msg, thread_ts: Thread.current[:thread_ts], unfurl_links: unfurl_links, unfurl_media: unfurl_media)
52
+ resp = client.message(channel: im["channel"]["id"], as_user: true, text: msg, thread_ts: thread_ts, unfurl_links: unfurl_links, unfurl_media: unfurl_media)
52
53
  else
53
54
  resp = client.message(channel: im["channel"]["id"], as_user: true, text: msg, unfurl_links: unfurl_links, unfurl_media: unfurl_media)
54
55
  end
@@ -57,7 +58,7 @@ class SlackSmartBot
57
58
  if config[:testing] and config.on_master_bot and !@buffered
58
59
  @buffered = true
59
60
  open("#{config.path}/buffer.log", "a") { |f|
60
- f.puts "|#{im["channel"]["id"]}|#{config[:nick_id]}|#{config[:nick]}|#{msg}#{blocks.join}"
61
+ f.puts "|#{im["channel"]["id"]}|#{thread_ts}|#{config[:nick_id]}|#{config[:nick]}|#{msg}#{blocks.join}"
61
62
  }
62
63
  end
63
64
  end