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,6 +1,7 @@
1
1
  class SlackSmartBot
2
2
  def process(user, command, dest, dchannel, rules_file, typem, files, ts)
3
3
  from = user.name
4
+ team_id_user = user.team_id + "_" + user.name
4
5
  if config.simulate
5
6
  display_name = user.profile.display_name
6
7
  else
@@ -9,7 +10,7 @@ class SlackSmartBot
9
10
  end
10
11
  display_name = user.profile.display_name
11
12
  end
12
-
13
+
13
14
  processed = true
14
15
 
15
16
  on_demand = false
@@ -28,7 +29,7 @@ class SlackSmartBot
28
29
  on_demand = true
29
30
  end
30
31
  if (on_demand or typem == :on_dm or
31
- (@listening.key?(from) and (@listening[from].key?(dest) or @listening[from].key?(Thread.current[:thread_ts])) )) and
32
+ (@listening.key?(team_id_user) and (@listening[team_id_user].key?(dest) or @listening[team_id_user].key?(Thread.current[:thread_ts])) )) and
32
33
  config.on_maintenance and !command.match?(/\A(set|turn)\s+maintenance\s+off\s*\z/)
33
34
  unless Thread.current.key?(:routine) and Thread.current[:routine]
34
35
  respond eval("\"" + config.on_maintenance_message + "\"")
@@ -37,82 +38,88 @@ class SlackSmartBot
37
38
  end
38
39
  if !config.on_maintenance or (config.on_maintenance and command.match?(/\A(set|turn)\s+maintenance\s+off\s*\z/))
39
40
  #todo: check :on_pg in this case
40
- if typem == :on_master or typem == :on_bot or typem == :on_pg or typem == :on_dm or
41
+ if typem == :on_master or typem == :on_bot or typem == :on_pg or typem == :on_dm or
41
42
  (command.match?(/\A\s*bot\s+stats\s*(.*)\s*$/i) and dest==@channels_id[config.stats_channel])
42
-
43
+
43
44
  case command
44
45
 
45
46
  when /\A\s*what's\s+new\s*$/i
46
47
  whats_new(user, dest, dchannel, from, display_name)
47
- when /\A\s*(#{@salutations.join("|")})\s+(rules|help)\s*(.+)?$/i, /\A(#{@salutations.join("|")}),? what can I do/i
48
- $2.to_s.match?(/rules/i) ? specific = true : specific = false
49
- help_command = $3
50
- bot_help(user, from, dest, dchannel, specific, help_command, rules_file)
48
+ when /\A(<)?\s*(#{@salutations.join("|")})\s+(rules|help)\s*(.+)?$/i,
49
+ /\A(<)?\s*(#{@salutations.join("|")})()(),? what can I do/i
50
+ $1.to_s=='' ? send_to_file = false : send_to_file = true
51
+ $3.to_s.match?(/rules/i) ? specific = true : specific = false
52
+ help_command = $4
53
+ react :runner
54
+ bot_help(user, from, dest, dchannel, specific, help_command, rules_file, send_to_file: send_to_file)
55
+ unreact :runner
51
56
  when /\A\s*(suggest|random)\s+(command|rule)\s*\z/i, /\A\s*(command|rule)\s+suggestion\s*\z/i
52
57
  $2.to_s.match?(/rule/i) || $1.to_s.match?(/rule/i) ? specific = true : specific = false
53
- suggest_command(from, dest, dchannel, specific, rules_file)
54
- when /\A\s*use\s+(rules\s+)?(from\s+)?<#C\w+\|(.+)>\s*$/i,
55
- /\A\s*use\s+(rules\s+)?(from\s+)?<#(\w+)\|>\s*$/i,
58
+ suggest_command(user, dest, dchannel, specific, rules_file)
59
+ when /\A\s*use\s+(rules\s+)?(from\s+)?<#C\w+\|(.+)>\s*$/i,
60
+ /\A\s*use\s+(rules\s+)?(from\s+)?<#(\w+)\|>\s*$/i,
56
61
  /\Ause\s+(rules\s+)?(from\s+)?([^\s]+\s*$)/i
57
62
  channel = $3
58
63
  use_rules(dest, channel, user, dchannel)
59
- when /\A\s*stop\s+using\s+rules\s+(on\s+)<#\w+\|(.+)>/i,
60
- /\A\s*stop\s+using\s+rules\s+(on\s+)<#(\w+)\|>/i,
64
+ when /\A\s*stop\s+using\s+rules\s+(on\s+)<#\w+\|(.+)>/i,
65
+ /\A\s*stop\s+using\s+rules\s+(on\s+)<#(\w+)\|>/i,
61
66
  /\A\s*stop\s+using\s+rules\s+(on\s+)(.+)\s*$/i
62
67
  channel = $2
63
68
  stop_using_rules_on(dest, user, from, channel, typem)
64
- when /\A\s*stop\s+using\s+rules\s*$()()/i,
65
- /\A\s*stop\s+using\s+(rules\s+from\s+)?<#\w+\|(.+)>/i,
66
- /\A\s*stop\s+using\s+(rules\s+from\s+)?<#(\w+)\|>/i,
69
+ when /\A\s*stop\s+using\s+rules\s*$()()/i,
70
+ /\A\s*stop\s+using\s+(rules\s+from\s+)?<#\w+\|(.+)>/i,
71
+ /\A\s*stop\s+using\s+(rules\s+from\s+)?<#(\w+)\|>/i,
67
72
  /\A\s*stop\s+using\s+(rules\s+from\s+)?(.+)\s*$/i
68
73
  channel = $2
69
74
  channel = @channel_id if channel.to_s == ''
70
75
  stop_using_rules(dest, channel, user, dchannel)
71
- when /\A\s*extend\s+rules\s+(to\s+)<#C\w+\|(.+)>/i, /\A\s*extend\s+rules\s+(to\s+)<#(\w+)\|>/i,
76
+ when /\A\s*extend\s+rules\s+(to\s+)<#C\w+\|(.+)>/i, /\A\s*extend\s+rules\s+(to\s+)<#(\w+)\|>/i,
72
77
  /\A\s*extend\s+rules\s+(to\s+)(.+)/i,
73
- /\A\s*use\s+rules\s+(on\s+)<#C\w+\|(.+)>/i, /\A\s*use\s+rules\s+(on\s+)<#(\w+)\|>/i,
78
+ /\A\s*use\s+rules\s+(on\s+)<#C\w+\|(.+)>/i, /\A\s*use\s+rules\s+(on\s+)<#(\w+)\|>/i,
74
79
  /\A\s*use\s+rules\s+(on\s+)(.+)/i
75
80
  channel = $2
76
81
  extend_rules(dest, user, from, channel, typem)
77
82
  when /\A\s*exit\s+bot(\s+silent)?\s*$/i, /\A\s*quit\s+bot(\s+silent)?\s*$/i, /\A\s*close\s+bot(\s+silent)?\s*$/i
78
83
  silent = $1.to_s != ''
79
- exit_bot(command, from, dest, display_name, silent: silent)
84
+ exit_bot(command, user, dest, display_name, silent: silent)
80
85
  when /\A\s*start\s+(this\s+)?bot$/i
81
86
  start_bot(dest, from)
82
87
  when /\A\s*pause\s+(this\s+)?bot$/i
83
88
  pause_bot(dest, from)
84
89
  when /\A\s*bot\s+status/i
85
90
  bot_status(dest, user)
86
- when /\Anotify\s+<#(C\w+)\|.+>\s+(.+)\s*\z/im,
87
- /\Anotify\s+<#(\w+)\|>\s+(.+)\s*\z/im,
91
+ when /\Anotify\s+<#(C\w+)\|.+>\s+(.+)\s*\z/im,
92
+ /\Anotify\s+<#(\w+)\|>\s+(.+)\s*\z/im,
88
93
  /\Anotify\s+(all)?\s*(.+)\s*\z/im
89
94
  where = $1
90
95
  message = $2
91
- notify_message(dest, from, where, message)
96
+ notify_message(dest, user, where, message)
92
97
  when /\Apublish\s+announcements\s*\z/i
93
98
  publish_announcements(user)
94
- when /\A\s*create\s+(cloud\s+|silent\s+)?bot\s+on\s+<#C\w+\|(.+)>\s*/i,
95
- /\A\s*create\s+(cloud\s+|silent\s+)?bot\s+on\s+<#(\w+)\|>\s*/i,
96
- /\Acreate\s+(cloud\s+|silent\s+)?bot\s+on\s+#(.+)\s*/i,
99
+ when /\A\s*create\s+(cloud\s+|silent\s+)?bot\s+on\s+<#C\w+\|(.+)>\s*/i,
100
+ /\A\s*create\s+(cloud\s+|silent\s+)?bot\s+on\s+<#(\w+)\|>\s*/i,
101
+ /\Acreate\s+(cloud\s+|silent\s+)?bot\s+on\s+#(.+)\s*/i,
97
102
  /\Acreate\s+(cloud\s+|silent\s+)?bot\s+on\s+(.+)\s*/i
98
103
  type = $1.to_s.downcase
99
104
  channel = $2
105
+ react :runner
100
106
  create_bot(dest, user, type, channel)
101
- when /\A\s*kill\s+bot\s+on\s+<#C\w+\|(.+)>\s*$/i,
102
- /\A\s*kill\s+bot\s+on\s+<#(\w+)\|>\s*$/i,
107
+ unreact :runner
108
+ when /\A\s*kill\s+bot\s+on\s+<#C\w+\|(.+)>\s*$/i,
109
+ /\A\s*kill\s+bot\s+on\s+<#(\w+)\|>\s*$/i,
103
110
  /\Akill\s+bot\s+on\s+#(.+)\s*$/i, /\Akill\s+bot\s+on\s+(.+)\s*$/i
104
111
  channel = $1
105
112
  kill_bot_on_channel(dest, from, channel)
106
113
  when /\A\s*(where\s+is|which\s+channels|where\s+is\s+a\s+member)\s+(#{@salutations.join("|")})\??\s*$/i
107
114
  where_smartbot(user)
108
115
  when /\A\s*(add|create)\s+(silent\s+)?(bgroutine|routine)\s+([\w\.]+)\s+(every)\s+(\d+)\s*(days|hours|minutes|seconds|mins|min|secs|sec|d|h|m|s)\s*(\s#(\w+)\s*)(\s.+)?\s*\z/im,
109
- /\A\s*(add|create)\s+(silent\s+)?(bgroutine|routine)\s+([\w\.]+)\s+(every)\s+(\d+)\s*(days|hours|minutes|seconds|mins|min|secs|sec|d|h|m|s)\s*(\s<#(C\w+)\|.*>\s*)?(\s.+)?\s*\z/im,
116
+ /\A\s*(add|create)\s+(silent\s+)?(bgroutine|routine)\s+([\w\.]+)\s+(every)\s+(\d+)\s*(days|hours|minutes|seconds|mins|min|secs|sec|d|h|m|s)\s*(\s<#([CG]\w+)\|[^>]*>\s*)?(\s.+)?\s*\z/im,
110
117
  /\A\s*(add|create)\s+(silent\s+)?(bgroutine|routine)\s+([\w\.]+)\s+on\s+(monday|tuesday|wednesday|thursday|friday|saturday|sunday|weekend|weekday)s?\s+at\s+(\d+:\d+:?\d+?)\s*()(\s#(\w+)\s*)(\s.+)?\s*\z/im,
111
- /\A\s*(add|create)\s+(silent\s+)?(bgroutine|routine)\s+([\w\.]+)\s+on\s+(monday|tuesday|wednesday|thursday|friday|saturday|sunday|weekend|weekday)s?\s+at\s+(\d+:\d+:?\d+?)\s*()(\s<#(C\w+)\|.*>\s*)?(\s.+)?\s*\z/im,
118
+ /\A\s*(add|create)\s+(silent\s+)?(bgroutine|routine)\s+([\w\.]+)\s+on\s+(monday|tuesday|wednesday|thursday|friday|saturday|sunday|weekend|weekday)s?\s+at\s+(\d+:\d+:?\d+?)\s*()(\s<#([CG]\w+)\|[^>]*>\s*)?(\s.+)?\s*\z/im,
112
119
  /\A\s*(add|create)\s+(silent\s+)?(bgroutine|routine)\s+([\w\.]+)\s+on\s+the\s+(\d+)[^\s]*\s+at\s+(\d+:\d+:?\d+?)\s*()(\s#(\w+)\s*)(\s.+)?\s*\z/im,
113
- /\A\s*(add|create)\s+(silent\s+)?(bgroutine|routine)\s+([\w\.]+)\s+on\s+the\s+(\d+)[^\s]*\s+at\s+(\d+:\d+:?\d+?)\s*()(\s<#(C\w+)\|.*>\s*)?(\s.+)?\s*\z/im,
120
+ /\A\s*(add|create)\s+(silent\s+)?(bgroutine|routine)\s+([\w\.]+)\s+on\s+the\s+(\d+)[^\s]*\s+at\s+(\d+:\d+:?\d+?)\s*()(\s<#([CG]\w+)\|[^>]*>\s*)?(\s.+)?\s*\z/im,
114
121
  /\A\s*(add|create)\s+(silent\s+)?(bgroutine|routine)\s+([\w\.]+)\s+(at)\s+(\d+:\d+:?\d+?)\s*()(\s#(\w+)\s*)(\s.+)?\s*\z/im,
115
- /\A\s*(add|create)\s+(silent\s+)?(bgroutine|routine)\s+([\w\.]+)\s+(at)\s+(\d+:\d+:?\d+?)\s*()(\s<#(C\w+)\|.*>\s*)?(\s.+)?\s*\z/im
122
+ /\A\s*(add|create)\s+(silent\s+)?(bgroutine|routine)\s+([\w\.]+)\s+(at)\s+(\d+:\d+:?\d+?)\s*()(\s<#([GC]\w+)\|[^>]*>\s*)?(\s.+)?\s*\z/im
116
123
  silent = $2.to_s!=''
117
124
  routine_type = $3.downcase
118
125
  name = $4.downcase
@@ -156,7 +163,7 @@ class SlackSmartBot
156
163
  regexp = $3.to_s
157
164
  see_routines(dest, from, user, all, header, regexp)
158
165
  when /\A\s*get\s+bot\s+logs?\s*$/i
159
- get_bot_logs(dest, from, typem)
166
+ get_bot_logs(dest, user, typem)
160
167
  when /\A\s*send\s+message\s+(on|to|in)\s+<(https?:[^:]+)>\s*:\s*(.+)\s*$/im,
161
168
  /\A\s*send\s+message\s+(on|to|in)\s+(https?:[^:]+)\s*:\s*(.+)\s*$/im,
162
169
  /\A\s*send\s+message\s+(on|to|in)\s*([^:]+)\s*:\s*(.+)\s*$/im
@@ -166,7 +173,7 @@ class SlackSmartBot
166
173
  to_channel = ''
167
174
  to = []
168
175
  stats_from = ''
169
- stats_to = ''
176
+ stats_to = ''
170
177
  stats_channel_filter = ''
171
178
  stats_command_filter = ''
172
179
 
@@ -198,16 +205,16 @@ class SlackSmartBot
198
205
  stats_command_filter = opt
199
206
  end
200
207
  end
201
-
208
+
202
209
  thread_ts.gsub!('.','')
203
- send_message(dest, from, typem, to, thread_ts, stats_from, stats_to, stats_channel_filter, stats_command_filter, message)
210
+ send_message(dest, user, typem, to, thread_ts, stats_from, stats_to, stats_channel_filter, stats_command_filter, message)
204
211
  when /\A\s*delete\s+message\s+(http.+)\s*$/i
205
212
  url = $1
206
- delete_message(from, typem, url)
213
+ delete_message(user, typem, url)
207
214
  when /\A\s*update\s+message\s+(http[^\s]+)\s+(.+)\s*\z/mi
208
215
  url = $1
209
216
  text = Thread.current[:command_orig].scan(/\A\s*update\s+message\s+<?http[^\s]+\s+(.+)\s*\z/mi).join
210
- update_message(from, typem, url, text)
217
+ update_message(user, typem, url, text)
211
218
  when /\A\s*react\s+(on|to|in)\s*([^\s]+)\s+([p\d\.]+)\s+(.+)\s*$/i,
212
219
  /\A\s*react\s+(on|to|in)\s*([^\s]+)\s+()(.+)\s*$/i
213
220
  to = $2
@@ -227,7 +234,7 @@ class SlackSmartBot
227
234
  respond "The channel specified doesn't exist or is in a incorrect format"
228
235
  else
229
236
  to = to_channel
230
- react_to(dest, from, typem, to, thread_ts, emojis)
237
+ react_to(dest, user, typem, to, thread_ts, emojis)
231
238
  end
232
239
 
233
240
  when /\A\s*(leader\s+board|leaderboard|ranking|podium)()()\s*$/i,
@@ -348,7 +355,7 @@ class SlackSmartBot
348
355
  end
349
356
  if this_month
350
357
  st_from = "#{Date.today.strftime("%Y-%m-01")}"
351
- st_to = "#{Date.today.strftime("%Y-%m-%d")}"
358
+ st_to = "#{Date.today.strftime("%Y-%m-%d")}"
352
359
  elsif last_month
353
360
  date = Date.today<<1
354
361
  st_from = "#{date.strftime("%Y-%m-01")}"
@@ -394,12 +401,12 @@ class SlackSmartBot
394
401
  when /\A(set|turn)\s+maintenance\s+(on|off)\s*()\z/im, /\A(set|turn)\s+maintenance\s+(on)\s*(.+)\s*\z/im
395
402
  status = $2.downcase
396
403
  message = $3.to_s
397
- set_maintenance(from, status, message)
404
+ set_maintenance(user, status, message)
398
405
  when /\A(set|turn)\s+(general|generic)\s+message\s+(off)\s*()\z/im, /\A(set|turn)\s+(general|generic)\s+message\s+(on\s+)?\s*(.+)\s*\z/im
399
406
  status = $3.to_s.downcase
400
407
  status = 'on' if status == ''
401
408
  message = $4.to_s
402
- set_general_message(from, status, message)
409
+ set_general_message(user, status, message)
403
410
  else
404
411
  processed = false
405
412
  end
@@ -410,25 +417,25 @@ class SlackSmartBot
410
417
  # only when :on and (listening or on demand or direct message)
411
418
  if @status == :on and
412
419
  (!answer.empty? or
413
- (@repl_sessions.key?(from) and dest==@repl_sessions[from][:dest] and
414
- ((@repl_sessions[from][:on_thread] and Thread.current[:thread_ts] == @repl_sessions[from][:thread_ts]) or
415
- (!@repl_sessions[from][:on_thread] and !Thread.current[:on_thread]))) or
416
- (@listening.key?(from) and typem != :on_extended and
417
- ((@listening[from].key?(dest) and !Thread.current[:on_thread]) or
418
- (@listening[from].key?(Thread.current[:thread_ts]) and Thread.current[:on_thread] ) )) or
420
+ (@repl_sessions.key?(team_id_user) and dest==@repl_sessions[team_id_user][:dest] and
421
+ ((@repl_sessions[team_id_user][:on_thread] and Thread.current[:thread_ts] == @repl_sessions[team_id_user][:thread_ts]) or
422
+ (!@repl_sessions[team_id_user][:on_thread] and !Thread.current[:on_thread]))) or
423
+ (@listening.key?(team_id_user) and typem != :on_extended and
424
+ ((@listening[team_id_user].key?(dest) and !Thread.current[:on_thread]) or
425
+ (@listening[team_id_user].key?(Thread.current[:thread_ts]) and Thread.current[:on_thread] ) )) or
419
426
  typem == :on_dm or typem == :on_pg or on_demand)
420
427
  processed2 = true
421
-
428
+
422
429
  case command
423
430
 
424
- when /\A\s*(add\s+)?(global\s+|generic\s+)?shortcut\s+(for\sall)?\s*([^:]+)\s*:\s*(.+)/i,
431
+ when /\A\s*(add\s+)?(global\s+|generic\s+)?shortcut\s+(for\sall)?\s*([^:]+)\s*:\s*(.+)/i,
425
432
  /\A(add\s+)(global\s+|generic\s+)?sc\s+(for\sall)?\s*([^:]+)\s*:\s*(.+)/i
426
433
  for_all = $3
427
434
  shortcut_name = $4.to_s.downcase
428
435
  command_to_run = $5
429
436
  global = $2.to_s != ''
430
437
  add_shortcut(dest, user, typem, for_all, shortcut_name, command, command_to_run, global)
431
- when /\A\s*(delete|remove)\s+(global\s+|generic\s+)?shortcut\s+(.+)/i,
438
+ when /\A\s*(delete|remove)\s+(global\s+|generic\s+)?shortcut\s+(.+)/i,
432
439
  /\A(delete|remove)\s+(global\s+|generic\s+)?sc\s+(.+)/i
433
440
  shortcut = $3.to_s.downcase
434
441
  global = $2.to_s != ''
@@ -456,7 +463,7 @@ class SlackSmartBot
456
463
  code.gsub!(/```\s*$/,'')
457
464
  @logger.info code
458
465
  ruby_code(dest, user, code, rules_file)
459
- when /\A\s*(private\s+|clean\s+|clean\s+private\s+|private\s+clean\s+)?(repl|irb|live)\s*()()()\z/i,
466
+ when /\A\s*(private\s+|clean\s+|clean\s+private\s+|private\s+clean\s+)?(repl|irb|live)\s*()()()\z/i,
460
467
  /\A\s*(private\s+|clean\s+|clean\s+private\s+|private\s+clean\s+)?(repl|irb|live)\s+([\w\-]+)()()\s*\z/i,
461
468
  /\A\s*(private\s+|clean\s+|clean\s+private\s+|private\s+clean\s+)?(repl|irb|live)\s+([\w\-]+)\s*:\s+"([^"]+)"()\s*\z/i,
462
469
  /\A\s*(private\s+|clean\s+|clean\s+private\s+|private\s+clean\s+)?(repl|irb|live)\s+([\w\-]+)\s*:\s+"([^"]+)"\s+(.+)\s*\z/i,
@@ -465,11 +472,11 @@ class SlackSmartBot
465
472
  opts_type = $1.to_s.downcase.split(' ')
466
473
  opts_type.include?('private') ? type = :private : type = :public
467
474
  type = "#{type}_clean".to_sym if opts_type.include?('clean')
468
-
475
+
469
476
  session_name = $3
470
477
  description = $4
471
478
  opts = " #{$5}"
472
- env_vars = opts.scan(/\s+[\w\-]+="[^"]+"/i) + opts.scan(/\s+[\w\-]+='[^']+'/i)
479
+ env_vars = opts.scan(/\s+[\w\-]+="[^"]+"/i) + opts.scan(/\s+[\w\-]+='[^']+'/i)
473
480
  opts.scan(/\s+[\w\-]+=[^'"\s]+/i).flatten.each do |ev|
474
481
  env_vars << ev.gsub('=',"='") + "'"
475
482
  end
@@ -481,7 +488,7 @@ class SlackSmartBot
481
488
  repl(dest, user, session_name, env_vars.flatten, rules_file, command, description, type)
482
489
  when /\A\s*get\s+(repl|irb|live)\s+([\w\-]+)\s*/i
483
490
  session_name = $2
484
- get_repl(dest, user, session_name)
491
+ get_repl(dest, user, session_name)
485
492
  when /\A\s*run\s+(repl|irb|live)\s+([\w\-]+)()\s*\z/im,
486
493
  /^\s*run\s+(repl|irb|live)\s+([\w\-]+)\s+(.+)\s*$/im
487
494
  session_name = $2
@@ -500,7 +507,7 @@ class SlackSmartBot
500
507
  env_vars[idx] = "ENV['#{ev}"
501
508
  end
502
509
  prerun = Thread.current[:command_orig].gsub('```', '`').scan(/\s+`(.+)`/m)
503
- run_repl(dest, user, session_name, env_vars.flatten, prerun.flatten, rules_file)
510
+ run_repl(dest, user, session_name, env_vars.flatten, prerun.flatten, rules_file)
504
511
  when /\A\s*(delete|remove)\s+(repl|irb|live)\s+([\w\-]+)\s*$/i
505
512
  repl_name = $3
506
513
  delete_repl(dest, user, repl_name)
@@ -1,12 +1,16 @@
1
1
  class SlackSmartBot
2
2
  def process_first(user, text, dest, dchannel, typem, files, ts, thread_ts, routine, routine_name, routine_type, command_orig)
3
3
  nick = user.name
4
+ team_id_user = user.team_id + "_" + nick
5
+ user.team_id_user = team_id_user
4
6
  rules_file = ""
7
+ Thread.current[:user] = user
8
+ Thread.current[:team_id_user] = team_id_user
5
9
  if text.match(/\A\s*(stop|quit|exit|kill)\s+(iterator|iteration|loop)\s+(\d+)\s*\z/i)
6
10
  save_stats :quit_loop, forced: true, data: {dest: dest, typem: typem, user: user, files: false, command: text, routine: routine}
7
11
  num_iteration = $3.to_i
8
- if config.admins.include?(user.name) or @loops.key?(user.name)
9
- if config.admins.include?(user.name)
12
+ if config.team_id_admins.include?(team_id_user) or @loops.key?(team_id_user)
13
+ if config.team_id_admins.include?(team_id_user)
10
14
  name_loop = ''
11
15
  @loops.each do |k,v|
12
16
  if v.include?(num_iteration)
@@ -15,7 +19,7 @@ class SlackSmartBot
15
19
  end
16
20
  end
17
21
  else
18
- name_loop = user.name
22
+ name_loop = team_id_user
19
23
  end
20
24
  if @loops.key?(name_loop) and @loops[name_loop].include?(num_iteration)
21
25
  @loops[name_loop].delete(num_iteration)
@@ -35,7 +39,7 @@ class SlackSmartBot
35
39
  text = "********" if !found
36
40
  text+= " (encrypted #{Thread.current[:command_id]})"
37
41
  end
38
- @logger.info "command: #{nick}> #{text}"
42
+ @logger.info "command: #{user.team_id}/#{nick}> #{text}"
39
43
  return :next #jal
40
44
  end
41
45
  if text.match(/\A\s*!*^?\s*(for\s*)?(\d+)\s+times\s+every\s+(\d+)\s*(m|minute|minutes|s|sc|second|seconds)\s+(.+)\s*\z/i)
@@ -52,11 +56,11 @@ class SlackSmartBot
52
56
  respond "You can't do that. Maximum times is 24, minimum every is 10 seconds, maximum every is 60 minutes.", dest, thread_ts: thread_ts
53
57
  return :next #jal
54
58
  end
55
- @loops[user.name] ||= []
59
+ @loops[team_id_user] ||= []
56
60
  @num_loops ||= 0
57
61
  @num_loops += 1
58
62
  loop_id = @num_loops
59
- @loops[user.name] << loop_id
63
+ @loops[team_id_user] << loop_id
60
64
  respond "Loop #{loop_id} started. To stop the loop use: `#{['stop','quit','exit', 'kill'].sample} #{['iteration','iterator','loop'].sample} #{loop_id}`", dest, thread_ts: thread_ts
61
65
  #todo: command_orig should be reasigned maybe to remove for N times every X seconds. Check.
62
66
  else
@@ -89,22 +93,22 @@ class SlackSmartBot
89
93
  elsif dest[0] == "C" or dest[0] == "G" # on a channel or private channel
90
94
  rules_file = config.rules_file
91
95
 
92
- if @rules_imported.key?(user.name) and @rules_imported[user.name].key?(dchannel)
93
- unless @bots_created.key?(@rules_imported[user.name][dchannel])
96
+ if @rules_imported.key?(team_id_user) and @rules_imported[team_id_user].key?(dchannel)
97
+ unless @bots_created.key?(@rules_imported[team_id_user][dchannel])
94
98
  get_bots_created()
95
99
  end
96
- if @bots_created.key?(@rules_imported[user.name][dchannel])
97
- rules_file = @bots_created[@rules_imported[user.name][dchannel]][:rules_file]
100
+ if @bots_created.key?(@rules_imported[team_id_user][dchannel])
101
+ rules_file = @bots_created[@rules_imported[team_id_user][dchannel]][:rules_file]
98
102
  end
99
103
  end
100
- elsif dest[0] == "D" and @rules_imported.key?(user.name) and @rules_imported[user.name].key?(user.name) #direct message
101
- unless @bots_created.key?(@rules_imported[user.name][user.name])
104
+ elsif dest[0] == "D" and @rules_imported.key?(team_id_user) and @rules_imported[team_id_user].key?(user.name) #direct message
105
+ unless @bots_created.key?(@rules_imported[team_id_user][user.name])
102
106
  get_bots_created()
103
107
  end
104
- if @bots_created.key?(@rules_imported[user.name][user.name])
105
- rules_file = @bots_created[@rules_imported[user.name][user.name]][:rules_file]
108
+ if @bots_created.key?(@rules_imported[team_id_user][user.name])
109
+ rules_file = @bots_created[@rules_imported[team_id_user][user.name]][:rules_file]
106
110
  end
107
- elsif dest[0] == "D" and (!@rules_imported.key?(user.name) or (@rules_imported.key?(user.name) and !@rules_imported[user.name].key?(user.name)))
111
+ elsif dest[0] == "D" and (!@rules_imported.key?(team_id_user) or (@rules_imported.key?(team_id_user) and !@rules_imported[team_id_user].key?(user.name)))
108
112
  if File.exist?("#{config.path}/rules/general_rules.rb")
109
113
  rules_file = "/rules/general_rules.rb"
110
114
  end
@@ -146,7 +150,8 @@ class SlackSmartBot
146
150
  when /removed the access to the rules of (.+) from (.+)\.$/i
147
151
  from_name = $1
148
152
  to_name = $2
149
- if config.on_master_bot and @bots_created[@channels_id[from_name]][:cloud]
153
+ if config.on_master_bot and @bots_created.key?(@channels_id[from_name]) and
154
+ @bots_created[@channels_id[from_name]][:cloud]
150
155
  @bots_created[@channels_id[from_name]][:extended].delete(to_name)
151
156
  update_bots_file()
152
157
  end
@@ -191,24 +196,24 @@ class SlackSmartBot
191
196
  if command.include?("$") #for adding shortcuts inside commands
192
197
  command.scan(/\$([^\$]+)/i).flatten.each do |sc|
193
198
  sc.strip!
194
- if @shortcuts.key?(nick) and @shortcuts[nick].keys.include?(sc)
195
- command.gsub!("$#{sc}", @shortcuts[nick][sc])
199
+ if @shortcuts.key?(team_id_user) and @shortcuts[team_id_user].keys.include?(sc)
200
+ command.gsub!("$#{sc}", @shortcuts[team_id_user][sc])
196
201
  elsif @shortcuts.key?(:all) and @shortcuts[:all].keys.include?(sc)
197
202
  command.gsub!("$#{sc}", @shortcuts[:all][sc])
198
- elsif @shortcuts_global.key?(nick) and @shortcuts_global[nick].keys.include?(sc)
199
- command.gsub!("$#{sc}", @shortcuts_global[nick][sc])
203
+ elsif @shortcuts_global.key?(team_id_user) and @shortcuts_global[team_id_user].keys.include?(sc)
204
+ command.gsub!("$#{sc}", @shortcuts_global[team_id_user][sc])
200
205
  elsif @shortcuts_global.key?(:all) and @shortcuts_global[:all].keys.include?(sc)
201
206
  command.gsub!("$#{sc}", @shortcuts_global[:all][sc])
202
207
  end
203
208
  end
204
209
  command.scan(/\$([^\s]+)/i).flatten.each do |sc|
205
210
  sc.strip!
206
- if @shortcuts.key?(nick) and @shortcuts[nick].keys.include?(sc)
207
- command.gsub!("$#{sc}", @shortcuts[nick][sc])
211
+ if @shortcuts.key?(team_id_user) and @shortcuts[team_id_user].keys.include?(sc)
212
+ command.gsub!("$#{sc}", @shortcuts[team_id_user][sc])
208
213
  elsif @shortcuts.key?(:all) and @shortcuts[:all].keys.include?(sc)
209
214
  command.gsub!("$#{sc}", @shortcuts[:all][sc])
210
- elsif @shortcuts_global.key?(nick) and @shortcuts_global[nick].keys.include?(sc)
211
- command.gsub!("$#{sc}", @shortcuts_global[nick][sc])
215
+ elsif @shortcuts_global.key?(team_id_user) and @shortcuts_global[team_id_user].keys.include?(sc)
216
+ command.gsub!("$#{sc}", @shortcuts_global[team_id_user][sc])
212
217
  elsif @shortcuts_global.key?(:all) and @shortcuts_global[:all].keys.include?(sc)
213
218
  command.gsub!("$#{sc}", @shortcuts_global[:all][sc])
214
219
  end
@@ -219,16 +224,16 @@ class SlackSmartBot
219
224
  end
220
225
  if command.scan(/^(shortcut|sc)\s+([^:]+)\s*$/i).any? or
221
226
  (@shortcuts.keys.include?(:all) and @shortcuts[:all].keys.include?(command)) or
222
- (@shortcuts.keys.include?(nick) and @shortcuts[nick].keys.include?(command)) or
227
+ (@shortcuts.keys.include?(team_id_user) and @shortcuts[team_id_user].keys.include?(command)) or
223
228
  (@shortcuts_global.keys.include?(:all) and @shortcuts_global[:all].keys.include?(command)) or
224
- (@shortcuts_global.keys.include?(nick) and @shortcuts_global[nick].keys.include?(command))
229
+ (@shortcuts_global.keys.include?(team_id_user) and @shortcuts_global[team_id_user].keys.include?(command))
225
230
  command = $2.downcase unless $2.nil?
226
- if @shortcuts.keys.include?(nick) and @shortcuts[nick].keys.include?(command)
227
- text = @shortcuts[nick][command].dup
231
+ if @shortcuts.keys.include?(team_id_user) and @shortcuts[team_id_user].keys.include?(command)
232
+ text = @shortcuts[team_id_user][command].dup
228
233
  elsif @shortcuts.keys.include?(:all) and @shortcuts[:all].keys.include?(command)
229
234
  text = @shortcuts[:all][command].dup
230
- elsif @shortcuts_global.keys.include?(nick) and @shortcuts_global[nick].keys.include?(command)
231
- text = @shortcuts_global[nick][command].dup
235
+ elsif @shortcuts_global.keys.include?(team_id_user) and @shortcuts_global[team_id_user].keys.include?(command)
236
+ text = @shortcuts_global[team_id_user][command].dup
232
237
  elsif @shortcuts_global.keys.include?(:all) and @shortcuts_global[:all].keys.include?(command)
233
238
  text = @shortcuts_global[:all][command].dup
234
239
  else
@@ -247,13 +252,24 @@ class SlackSmartBot
247
252
  t = Thread.new do
248
253
  begin
249
254
  sleep every_seconds * i if every_seconds > 0
250
- Thread.exit if command_every!='' and @loops.key?(user.name) and !@loops[user.name].include?(loop_id)
255
+ Thread.exit if command_every!='' and @loops.key?(team_id_user) and !@loops[team_id_user].include?(loop_id)
251
256
  @logger.info "i: #{i}, num_times: #{num_times}, every_seconds: #{every_seconds}, command: #{command_thread}" if command_every!=''
252
257
  processed = false
253
258
  processed_rules = false
254
259
 
260
+ if command_thread.match?(/\A.+\s+\?\?\s+.+\z/im) and !command_thread.match?(/\A\s*(add|create)\s+(silent\s+)?(bgroutine|routine)\s+([\w\.]+)/im)
261
+ pos = command_thread.index("??")
262
+ Thread.current[:prompt] = command_thread[pos+2..-1].strip
263
+ command_thread = command_thread[0..pos-1].strip
264
+ Thread.current[:stdout] = ""
265
+ else
266
+ Thread.current[:prompt] = ""
267
+ Thread.current[:stdout] = ""
268
+ end
255
269
  Thread.current[:dest] = dest
256
270
  Thread.current[:user] = user
271
+ Thread.current[:team_id_user] = user.team_id + "_" + user.name
272
+ Thread.current[:team_id] = user.team_id
257
273
  Thread.current[:command] = command_thread.dup
258
274
  Thread.current[:rules_file] = rules_file
259
275
  Thread.current[:typem] = typem
@@ -271,12 +287,12 @@ class SlackSmartBot
271
287
  else
272
288
  Thread.current[:on_thread] = true
273
289
  end
274
- if (dest[0] == "C") || (dest[0] == "G") and @rules_imported.key?(user.name) &&
275
- @rules_imported[user.name].key?(dchannel) && @bots_created.key?(@rules_imported[user.name][dchannel])
276
- Thread.current[:using_channel] = @rules_imported[user.name][dchannel]
277
- elsif dest[0] == "D" && @rules_imported.key?(user.name) && @rules_imported[user.name].key?(user.name) and
278
- @bots_created.key?(@rules_imported[user.name][user.name])
279
- Thread.current[:using_channel] = @rules_imported[user.name][user.name]
290
+ if (dest[0] == "C") || (dest[0] == "G") and @rules_imported.key?(team_id_user) &&
291
+ @rules_imported[team_id_user].key?(dchannel) && @bots_created.key?(@rules_imported[team_id_user][dchannel])
292
+ Thread.current[:using_channel] = @rules_imported[team_id_user][dchannel]
293
+ elsif dest[0] == "D" && @rules_imported.key?(team_id_user) && @rules_imported[team_id_user].key?(user.name) and
294
+ @bots_created.key?(@rules_imported[team_id_user][user.name])
295
+ Thread.current[:using_channel] = @rules_imported[team_id_user][user.name]
280
296
  else
281
297
  Thread.current[:using_channel] = ""
282
298
  end
@@ -300,24 +316,36 @@ class SlackSmartBot
300
316
  command_thread = command2
301
317
  on_demand = true
302
318
  end
319
+
320
+ if !config.on_maintenance and @listening.key?(team_id_user) and @listening[team_id_user].key?(Thread.current[:thread_ts]) and !Thread.current[:thread_ts].empty? and
321
+ ((@active_chat_gpt_sessions.key?(team_id_user) and @active_chat_gpt_sessions[team_id_user].key?(Thread.current[:thread_ts])) or
322
+ (@chat_gpt_collaborating.key?(team_id_user) and @chat_gpt_collaborating[team_id_user].key?(Thread.current[:thread_ts])))
323
+ @listening[team_id_user][Thread.current[:thread_ts]] = Time.now
324
+ command_thread = "? #{command_thread}" #chatgpt
325
+ end
326
+
327
+
303
328
  unless config.on_maintenance or @status != :on
304
329
  if typem == :on_pub or typem == :on_pg or typem == :on_extended
305
- if command_thread.match(/\A\s*(#{@salutations.join("|")})\s+(rules|help)\s*(.+)?$/i) or command_thread.match(/\A(#{@salutations.join("|")}),? what can I do/i)
306
- $2.to_s.match?(/rules/i) ? specific = true : specific = false
307
- help_command = $3
330
+ if command_thread.match(/\A(<)?\s*(#{@salutations.join("|")})\s+(rules|help)\s*(.+)?$/i) or command_thread.match(/\A(<)?\s*(#{@salutations.join("|")}),? what can I do/i)
331
+ $1.to_s=='' ? send_to_file = false : send_to_file = true
332
+ $3.to_s.match?(/rules/i) ? specific = true : specific = false
333
+ help_command = $4
334
+ react :runner
308
335
  if typem == :on_extended and specific
309
- bot_rules(dest, help_command, typem, rules_file, user)
336
+ bot_rules(dest, help_command, typem, rules_file, user, send_to_file: send_to_file)
310
337
  else
311
- bot_help(user, user.name, dest, dchannel, specific, help_command, rules_file)
338
+ bot_help(user, user.name, dest, dchannel, specific, help_command, rules_file, send_to_file: send_to_file)
312
339
  end
313
340
  processed = true
341
+ unreact :runner
314
342
  end
315
343
  end
316
344
  processed = (processed || general_bot_commands(user, command_thread, dest, files))
317
345
  processed = (processed || general_commands(user, command_thread, dest, files)) if defined?(general_commands)
318
346
  if processed
319
347
  text_to_log = command_thread.dup
320
-
348
+
321
349
  if Thread.current.key?(:encrypted) and Thread.current[:encrypted].size > 0
322
350
  found = false
323
351
  Thread.current[:encrypted].each do |encdata|
@@ -327,19 +355,19 @@ class SlackSmartBot
327
355
  text_to_log = "********" if !found
328
356
  text_to_log+= " (encrypted #{Thread.current[:command_id]})"
329
357
  end
330
- @logger.info "command: #{nick}> #{text_to_log}"
358
+ @logger.info "command: #{user.team_id}/#{nick}> #{text_to_log}" unless user.id == config.nick_id_granular
331
359
  end
332
360
  end
333
361
 
334
362
  if !config.on_maintenance and !processed and typem != :on_pub and typem != :on_pg
335
363
  if @status == :on and
336
364
  (!answer.empty? or
337
- (@repl_sessions.key?(nick) and dest == @repl_sessions[nick][:dest] and
338
- ((@repl_sessions[nick][:on_thread] and thread_ts == @repl_sessions[nick][:thread_ts]) or
339
- (!@repl_sessions[nick][:on_thread] and !Thread.current[:on_thread]))) or
340
- (@listening.key?(nick) and typem != :on_extended and
341
- ((@listening[nick].key?(dest) and !Thread.current[:on_thread]) or
342
- (@listening[nick].key?(thread_ts) and Thread.current[:on_thread]))) or
365
+ (@repl_sessions.key?(team_id_user) and dest == @repl_sessions[team_id_user][:dest] and
366
+ ((@repl_sessions[team_id_user][:on_thread] and thread_ts == @repl_sessions[team_id_user][:thread_ts]) or
367
+ (!@repl_sessions[team_id_user][:on_thread] and !Thread.current[:on_thread]))) or
368
+ (@listening.key?(team_id_user) and typem != :on_extended and
369
+ ((@listening[team_id_user].key?(dest) and !Thread.current[:on_thread]) or
370
+ (@listening[team_id_user].key?(thread_ts) and Thread.current[:on_thread]))) or
343
371
  dest[0] == "D" or on_demand)
344
372
  unless processed
345
373
  text_to_log = command_thread.dup
@@ -352,14 +380,14 @@ class SlackSmartBot
352
380
  text_to_log = "********" if !found
353
381
  text_to_log+= " (encrypted #{Thread.current[:command_id]})"
354
382
  end
355
- @logger.info "command: #{nick}> #{text_to_log}"
383
+ @logger.info "command: #{user.team_id}/#{nick}> #{text_to_log}" unless user.id == config.nick_id_granular
356
384
  end
357
385
  #todo: verify this
358
386
 
359
387
  if dest[0] == "C" or dest[0] == "G" or (dest[0] == "D" and typem == :on_call)
360
- if typem != :on_call and @rules_imported.key?(user.name) and @rules_imported[user.name].key?(dchannel)
361
- if @bots_created.key?(@rules_imported[user.name][dchannel])
362
- if @bots_created[@rules_imported[user.name][dchannel]][:status] != :on
388
+ if typem != :on_call and @rules_imported.key?(team_id_user) and @rules_imported[team_id_user].key?(dchannel)
389
+ if @bots_created.key?(@rules_imported[team_id_user][dchannel])
390
+ if @bots_created[@rules_imported[team_id_user][dchannel]][:status] != :on
363
391
  respond "The bot on that channel is not :on", dest
364
392
  rules_file = ""
365
393
  end
@@ -386,9 +414,9 @@ class SlackSmartBot
386
414
  @logger.warn "It seems like rules method is not defined"
387
415
  end
388
416
  end
389
- elsif @rules_imported.key?(user.name) and @rules_imported[user.name].key?(user.name)
390
- if @bots_created.key?(@rules_imported[user.name][user.name])
391
- if @bots_created[@rules_imported[user.name][user.name]][:status] == :on
417
+ elsif @rules_imported.key?(team_id_user) and @rules_imported[team_id_user].key?(user.name)
418
+ if @bots_created.key?(@rules_imported[team_id_user][user.name])
419
+ if @bots_created[@rules_imported[team_id_user][user.name]][:status] == :on
392
420
  begin
393
421
  eval(File.new(config.path + rules_file).read) if File.exist?(config.path + rules_file) and ![".", ".."].include?(config.path + rules_file)
394
422
  rescue Exception => stack
@@ -396,7 +424,7 @@ class SlackSmartBot
396
424
  @logger.fatal stack
397
425
  end
398
426
  else
399
- respond "The bot on <##{@rules_imported[user.name][user.name]}|#{@bots_created[@rules_imported[user.name][user.name]][:channel_name]}> is not :on", dest
427
+ respond "The bot on <##{@rules_imported[team_id_user][user.name]}|#{@bots_created[@rules_imported[team_id_user][user.name]][:channel_name]}> is not :on", dest
400
428
  rules_file = ""
401
429
  end
402
430
  end
@@ -417,7 +445,7 @@ class SlackSmartBot
417
445
  end
418
446
  end
419
447
  elsif dest[0] == "D" and
420
- (!@rules_imported.key?(user.name) or (@rules_imported.key?(user.name) and !@rules_imported[user.name].key?(user.name))) and
448
+ (!@rules_imported.key?(team_id_user) or (@rules_imported.key?(team_id_user) and !@rules_imported[team_id_user].key?(user.name))) and
421
449
  rules_file.include?("general_rules.rb")
422
450
  begin
423
451
  eval(File.new(config.path + rules_file).read) if File.exist?(config.path + rules_file) and ![".", ".."].include?(config.path + rules_file)
@@ -455,21 +483,34 @@ class SlackSmartBot
455
483
 
456
484
  processed = (processed_rules || processed)
457
485
 
458
- if processed and @listening.key?(nick)
459
- if Thread.current[:on_thread] and @listening[nick].key?(Thread.current[:thread_ts])
460
- @listening[nick][Thread.current[:thread_ts]] = Time.now
461
- elsif !Thread.current[:on_thread] and @listening[nick].key?(dest)
462
- @listening[nick][dest] = Time.now
486
+ if processed and @listening.key?(team_id_user)
487
+ if Thread.current[:on_thread] and @listening[team_id_user].key?(Thread.current[:thread_ts])
488
+ @listening[team_id_user][Thread.current[:thread_ts]] = Time.now
489
+ elsif !Thread.current[:on_thread] and @listening[team_id_user].key?(dest)
490
+ @listening[team_id_user][dest] = Time.now
463
491
  end
464
492
  end
465
493
  end
466
494
  end
467
495
 
496
+ if Thread.current[:prompt].to_s != ''
497
+ prompt = "#{Thread.current[:command]}\n\n#{Thread.current[:prompt]}\n\n#{Thread.current[:stdout]}\n\n"
498
+ Thread.current[:prompt] = ''
499
+ Thread.current[:stdout] = ''
500
+ if processed
501
+ if @active_chat_gpt_sessions.key?(team_id_user) and @active_chat_gpt_sessions[team_id_user].key?(Thread.current[:thread_ts])
502
+ open_ai_chat(prompt, false, :temporary)
503
+ else
504
+ open_ai_chat(prompt, true, :temporary, model: config[:ai].open_ai.chat_gpt.smartbot_model)
505
+ end
506
+ end
507
+ end
468
508
  if processed and config.general_message != "" and !routine
469
509
  respond eval("\"" + config.general_message + "\"")
470
510
  end
471
511
  respond "_*Loop #{loop_id}* (#{i+1}/#{num_times}) <@#{user.name}>: #{command_every}_" if command_every!='' and processed
472
- @loops[user.name].delete(loop_id) if command_every!='' and !processed and @loops.key?(user.name) and @loops[user.name].include?(loop_id)
512
+ @loops[team_id_user].delete(loop_id) if command_every!='' and !processed and @loops.key?(team_id_user) and @loops[team_id_user].include?(loop_id)
513
+
473
514
  rescue Exception => stack
474
515
  @logger.fatal stack
475
516
  end